summaryrefslogtreecommitdiffstats
path: root/release
diff options
context:
space:
mode:
Diffstat (limited to 'release')
-rw-r--r--release/Makefile306
-rw-r--r--release/Makefile.azure53
-rw-r--r--release/Makefile.ec259
-rw-r--r--release/Makefile.gce69
-rw-r--r--release/Makefile.mirrors254
-rw-r--r--release/Makefile.vagrant122
-rw-r--r--release/Makefile.vm167
-rwxr-xr-xrelease/amd64/make-memstick.sh41
-rw-r--r--release/amd64/mkisoimages.sh60
-rw-r--r--release/arm/BANANAPI.conf41
-rw-r--r--release/arm/BEAGLEBONE.conf39
-rw-r--r--release/arm/CUBIEBOARD.conf40
-rw-r--r--release/arm/CUBIEBOARD2.conf41
-rw-r--r--release/arm/CUBOX-HUMMINGBOARD.conf41
-rw-r--r--release/arm/GUMSTIX.conf39
-rw-r--r--release/arm/PANDABOARD.conf39
-rw-r--r--release/arm/RPI-B.conf45
-rw-r--r--release/arm/RPI2.conf45
-rw-r--r--release/arm/WANDBOARD.conf41
-rwxr-xr-xrelease/arm64/make-memstick.sh41
-rw-r--r--release/doc/Makefile38
-rw-r--r--release/doc/README127
-rw-r--r--release/doc/en_US.ISO8859-1/Makefile16
-rw-r--r--release/doc/en_US.ISO8859-1/errata/Makefile19
-rw-r--r--release/doc/en_US.ISO8859-1/errata/article.xml100
-rw-r--r--release/doc/en_US.ISO8859-1/hardware/Makefile30
-rw-r--r--release/doc/en_US.ISO8859-1/hardware/article.xml1659
-rw-r--r--release/doc/en_US.ISO8859-1/readme/Makefile24
-rw-r--r--release/doc/en_US.ISO8859-1/readme/article.xml412
-rw-r--r--release/doc/en_US.ISO8859-1/relnotes/Makefile24
-rw-r--r--release/doc/en_US.ISO8859-1/relnotes/article.xml1805
-rw-r--r--release/doc/en_US.ISO8859-1/share/xml/catalog.xml12
-rw-r--r--release/doc/en_US.ISO8859-1/share/xml/release.xsl28
-rw-r--r--release/doc/share/examples/Makefile.relnotesng61
-rw-r--r--release/doc/share/misc/dev.archlist.txt178
-rw-r--r--release/doc/share/misc/man2hwnotes.pl533
-rw-r--r--release/doc/share/mk/doc.relnotes.mk54
-rw-r--r--release/doc/share/xml/Makefile11
-rw-r--r--release/doc/share/xml/catalog.xml13
-rw-r--r--release/doc/share/xml/errata.xml28
-rw-r--r--release/doc/share/xml/release.ent82
-rw-r--r--release/doc/share/xml/release.xsl106
-rw-r--r--release/doc/share/xml/security.xml28
-rw-r--r--release/doc/share/xml/sponsor.ent55
-rw-r--r--release/doc/share/xml/vendor.ent9
-rwxr-xr-xrelease/i386/make-memstick.sh41
-rw-r--r--release/i386/mkisoimages.sh45
-rw-r--r--release/pc98/mkisoimages.sh45
-rw-r--r--release/picobsd/Version1
-rw-r--r--release/picobsd/bridge/PICOBSD118
-rw-r--r--release/picobsd/bridge/PICOBSD.hints39
-rw-r--r--release/picobsd/bridge/config6
-rw-r--r--release/picobsd/bridge/crunch.conf183
-rw-r--r--release/picobsd/bridge/floppy.tree.exclude2
-rw-r--r--release/picobsd/build/Makefile.conf61
-rw-r--r--release/picobsd/build/config17
-rw-r--r--release/picobsd/build/mfs.mtree72
-rwxr-xr-xrelease/picobsd/build/picobsd1095
-rw-r--r--release/picobsd/floppy.tree/etc/fstab6
-rw-r--r--release/picobsd/floppy.tree/etc/hosts17
-rw-r--r--release/picobsd/floppy.tree/etc/inetd.conf21
-rw-r--r--release/picobsd/floppy.tree/etc/master.passwd11
-rw-r--r--release/picobsd/floppy.tree/etc/networks5
-rw-r--r--release/picobsd/floppy.tree/etc/ppp/ppp.conf9
-rw-r--r--release/picobsd/floppy.tree/etc/ppp/ppp.deny15
-rw-r--r--release/picobsd/floppy.tree/etc/ppp/ppp.linkup10
-rw-r--r--release/picobsd/floppy.tree/etc/ppp/ppp.secret.sample23
-rw-r--r--release/picobsd/floppy.tree/etc/profile5
-rw-r--r--release/picobsd/floppy.tree/etc/rc.conf10
-rw-r--r--release/picobsd/floppy.tree/etc/rc.conf.defaults184
-rw-r--r--release/picobsd/floppy.tree/etc/rc.firewall142
-rw-r--r--release/picobsd/floppy.tree/etc/rc163
-rw-r--r--release/picobsd/floppy.tree/etc/snmpd.conf58
-rw-r--r--release/picobsd/floppy.tree/etc/ssh/sshd_config28
-rw-r--r--release/picobsd/floppy.tree/etc/ttys36
-rwxr-xr-xrelease/picobsd/floppy.tree/sbin/dhclient-script384
-rw-r--r--release/picobsd/mfs_tree/etc/disktab85
-rw-r--r--release/picobsd/mfs_tree/etc/gettytab42
-rw-r--r--release/picobsd/mfs_tree/etc/group19
-rw-r--r--release/picobsd/mfs_tree/etc/login.conf118
-rw-r--r--release/picobsd/mfs_tree/etc/motd9
-rw-r--r--release/picobsd/mfs_tree/etc/protocols14
-rw-r--r--release/picobsd/mfs_tree/etc/rc27
-rw-r--r--release/picobsd/mfs_tree/etc/rc.network83
-rw-r--r--release/picobsd/mfs_tree/etc/rc.serial127
-rw-r--r--release/picobsd/mfs_tree/etc/remote50
-rw-r--r--release/picobsd/mfs_tree/etc/services94
-rw-r--r--release/picobsd/mfs_tree/etc/shells7
-rw-r--r--release/picobsd/mfs_tree/etc/termcap187
-rwxr-xr-xrelease/picobsd/mfs_tree/stand/update50
-rw-r--r--release/picobsd/qemu/PICOBSD124
-rw-r--r--release/picobsd/qemu/PICOBSD.hints39
-rw-r--r--release/picobsd/qemu/config26
-rw-r--r--release/picobsd/qemu/crunch.conf200
-rw-r--r--release/picobsd/qemu/floppy.tree.exclude2
-rw-r--r--release/picobsd/tinyware/aps/Makefile9
-rw-r--r--release/picobsd/tinyware/aps/README19
-rw-r--r--release/picobsd/tinyware/aps/main.c101
-rw-r--r--release/picobsd/tinyware/help/Makefile9
-rw-r--r--release/picobsd/tinyware/help/README8
-rw-r--r--release/picobsd/tinyware/help/help.c157
-rw-r--r--release/picobsd/tinyware/login/Makefile25
-rw-r--r--release/picobsd/tinyware/login/README6
-rw-r--r--release/picobsd/tinyware/login/pathnames.h43
-rw-r--r--release/picobsd/tinyware/login/pico-login.c1093
-rw-r--r--release/picobsd/tinyware/msg/Makefile9
-rw-r--r--release/picobsd/tinyware/msg/README15
-rw-r--r--release/picobsd/tinyware/msg/msg.c75
-rw-r--r--release/picobsd/tinyware/msh/Makefile8
-rw-r--r--release/picobsd/tinyware/msh/README13
-rw-r--r--release/picobsd/tinyware/msh/msh.1260
-rw-r--r--release/picobsd/tinyware/msh/sh.h388
-rw-r--r--release/picobsd/tinyware/msh/sh1.c953
-rw-r--r--release/picobsd/tinyware/msh/sh2.c801
-rw-r--r--release/picobsd/tinyware/msh/sh3.c1143
-rw-r--r--release/picobsd/tinyware/msh/sh4.c767
-rw-r--r--release/picobsd/tinyware/msh/sh5.c675
-rw-r--r--release/picobsd/tinyware/msh/sh6.c9
-rw-r--r--release/picobsd/tinyware/ns/Makefile9
-rw-r--r--release/picobsd/tinyware/ns/README43
-rw-r--r--release/picobsd/tinyware/ns/ns.c831
-rw-r--r--release/picobsd/tinyware/oinit/Makefile22
-rw-r--r--release/picobsd/tinyware/oinit/README123
-rw-r--r--release/picobsd/tinyware/oinit/oinit.c947
-rw-r--r--release/picobsd/tinyware/passwd/Makefile68
-rw-r--r--release/picobsd/tinyware/passwd/extern.h38
-rw-r--r--release/picobsd/tinyware/passwd/local_passwd.c237
-rw-r--r--release/picobsd/tinyware/passwd/passwd.c193
-rw-r--r--release/picobsd/tinyware/passwd/pw_copy.c304
-rw-r--r--release/picobsd/tinyware/passwd/pw_util.c258
-rw-r--r--release/picobsd/tinyware/passwd/pw_util.h44
-rw-r--r--release/picobsd/tinyware/simple_httpd/Makefile8
-rw-r--r--release/picobsd/tinyware/simple_httpd/README167
-rw-r--r--release/picobsd/tinyware/simple_httpd/simple_httpd.c501
-rw-r--r--release/picobsd/tinyware/sps/Makefile9
-rw-r--r--release/picobsd/tinyware/sps/README11
-rw-r--r--release/picobsd/tinyware/sps/sps.c122
-rw-r--r--release/picobsd/tinyware/view/Makefile9
-rw-r--r--release/picobsd/tinyware/view/README86
-rw-r--r--release/picobsd/tinyware/view/fbsd.pngbin0 -> 7386 bytes
-rw-r--r--release/picobsd/tinyware/view/picobsd.vu9
-rw-r--r--release/picobsd/tinyware/view/view.c619
-rw-r--r--release/picobsd/tinyware/vm/Makefile10
-rw-r--r--release/picobsd/tinyware/vm/README10
-rw-r--r--release/picobsd/tinyware/vm/vm.c112
-rw-r--r--release/pkg_repos/release-dvd.conf8
-rw-r--r--release/powerpc/boot.tbxi15
-rwxr-xr-xrelease/powerpc/generate-hfs.sh64
-rw-r--r--release/powerpc/hfs-boot.bz2.uu23
-rwxr-xr-xrelease/powerpc/make-memstick.sh47
-rw-r--r--release/powerpc/mkisoimages.sh69
-rwxr-xr-xrelease/rc.local93
-rw-r--r--release/release.conf.sample112
-rwxr-xr-xrelease/release.sh406
-rw-r--r--release/scripts/FreeBSD_install_cdrom.conf16
-rwxr-xr-xrelease/scripts/atlas-upload.sh159
-rw-r--r--release/scripts/box.ovf226
-rwxr-xr-xrelease/scripts/list-new-changesets.py118
-rwxr-xr-xrelease/scripts/make-manifest.sh26
-rwxr-xr-xrelease/scripts/mk-vmimage.sh122
-rwxr-xr-xrelease/scripts/mm-mtree.sh160
-rwxr-xr-xrelease/scripts/pkg-stage.sh90
-rwxr-xr-xrelease/scripts/relnotes-search.sh133
-rw-r--r--release/sparc64/mkisoimages.sh84
-rw-r--r--release/tools/arm.subr137
-rw-r--r--release/tools/azure.conf29
-rw-r--r--release/tools/ec2.conf88
-rw-r--r--release/tools/gce.conf93
-rw-r--r--release/tools/openstack.conf25
-rw-r--r--release/tools/vagrant-virtualbox.conf18
-rw-r--r--release/tools/vagrant-vmware.conf22
-rw-r--r--release/tools/vagrant.conf75
-rw-r--r--release/tools/vmimage.subr234
173 files changed, 25158 insertions, 0 deletions
diff --git a/release/Makefile b/release/Makefile
new file mode 100644
index 0000000..e3a233d
--- /dev/null
+++ b/release/Makefile
@@ -0,0 +1,306 @@
+# $FreeBSD$
+#
+# Makefile for building releases and release media.
+#
+# User-driven targets:
+# cdrom: Builds release CD-ROM media (disc1.iso)
+# dvdrom: Builds release DVD-ROM media (dvd1.iso)
+# memstick: Builds memory stick image (memstick.img)
+# mini-memstick: Builds minimal memory stick image (mini-memstick.img)
+# ftp: Sets up FTP distribution area (ftp)
+# release: Invokes real-release, vm-release, and cloudware-release targets
+# real-release: Build all media and FTP distribution area
+# vm-release: Build all virtual machine image targets
+# cloudware-release: Build all cloud hosting provider targets
+# install: Invokes the release-install and vm-install targets
+# release-install: Copies all release installation media into ${DESTDIR}
+# vm-install: Copies all virtual machine images into ${DESTDIR}
+#
+# Variables affecting the build process:
+# WORLDDIR: location of src tree -- must have built world and default kernel
+# (by default, the directory above this one)
+# PORTSDIR: location of ports tree to distribute (default: /usr/ports)
+# DOCDIR: location of doc tree (default: /usr/doc)
+# XTRADIR: xtra-bits-dir argument for <arch>/mkisoimages.sh
+# NOPKG: if set, do not distribute third-party packages
+# NOPORTS: if set, do not distribute ports tree
+# NOSRC: if set, do not distribute source tree
+# NODOC: if set, do not generate release documentation
+# WITH_DVD: if set, generate dvd1.iso
+# WITH_COMPRESSED_IMAGES: if set, compress installation images with xz(1)
+# (uncompressed images are not removed)
+# WITH_VMIMAGES: if set, build virtual machine images with the release
+# WITH_COMPRESSED_VMIMAGES: if set, compress virtual machine disk images
+# with xz(1) (extremely time consuming)
+# WITH_CLOUDWARE: if set, build cloud hosting disk images with the release
+# TARGET/TARGET_ARCH: architecture of built release
+#
+
+WORLDDIR?= ${.CURDIR}/..
+PORTSDIR?= /usr/ports
+DOCDIR?= /usr/doc
+RELNOTES_LANG?= en_US.ISO8859-1
+
+.if !defined(TARGET) || empty(TARGET)
+TARGET= ${MACHINE}
+.endif
+.if !defined(TARGET_ARCH) || empty(TARGET_ARCH)
+.if ${TARGET} == ${MACHINE}
+TARGET_ARCH= ${MACHINE_ARCH}
+.else
+TARGET_ARCH= ${TARGET}
+.endif
+.endif
+IMAKE= ${MAKE} TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET}
+DISTDIR= dist
+
+# Define OSRELEASE by using newvars.sh
+.if !defined(OSRELEASE) || empty(OSRELEASE)
+.for _V in TYPE BRANCH REVISION
+${_V}!= eval $$(awk '/^${_V}=/{print}' ${.CURDIR}/../sys/conf/newvers.sh); echo $$${_V}
+.endfor
+.for _V in ${TARGET_ARCH}
+.if !empty(TARGET:M${_V})
+OSRELEASE= ${TYPE}-${REVISION}-${BRANCH}-${TARGET}
+VOLUME_LABEL= ${REVISION:C/[.-]/_/g}_${BRANCH:C/[.-]/_/g}_${TARGET}
+.else
+OSRELEASE= ${TYPE}-${REVISION}-${BRANCH}-${TARGET}-${TARGET_ARCH}
+VOLUME_LABEL= ${REVISION:C/[.-]/_/g}_${BRANCH:C/[.-]/_/g}_${TARGET_ARCH}
+.endif
+.endfor
+.endif
+
+.if !defined(VOLUME_LABEL) || empty(VOLUME_LABEL)
+VOLUME_LABEL= FreeBSD_Install
+.endif
+
+.if !exists(${DOCDIR})
+NODOC= true
+.endif
+.if !exists(${PORTSDIR})
+NOPORTS= true
+.endif
+
+EXTRA_PACKAGES=
+.if !defined(NOPORTS)
+EXTRA_PACKAGES+= ports.txz
+.endif
+.if !defined(NOSRC)
+EXTRA_PACKAGES+= src.txz
+.endif
+.if !defined(NODOC)
+EXTRA_PACKAGES+= reldoc
+.endif
+
+RELEASE_TARGETS= ftp
+IMAGES=
+.if exists(${.CURDIR}/${TARGET}/mkisoimages.sh)
+RELEASE_TARGETS+= cdrom
+IMAGES+= disc1.iso bootonly.iso
+. if defined(WITH_DVD) && !empty(WITH_DVD)
+RELEASE_TARGETS+= dvdrom
+IMAGES+= dvd1.iso
+. endif
+.endif
+.if exists(${.CURDIR}/${TARGET}/make-memstick.sh)
+RELEASE_TARGETS+= memstick.img
+RELEASE_TARGETS+= mini-memstick.img
+IMAGES+= memstick.img
+IMAGES+= mini-memstick.img
+.endif
+
+CLEANFILES= packagesystem *.txz MANIFEST release ${IMAGES}
+.if defined(WITH_COMPRESSED_IMAGES) && !empty(WITH_COMPRESSED_IMAGES)
+. for I in ${IMAGES}
+CLEANFILES+= ${I}.xz
+. endfor
+.endif
+.if defined(WITH_DVD) && !empty(WITH_DVD)
+CLEANFILES+= pkg-stage
+.endif
+CLEANDIRS= dist ftp disc1 bootonly dvd
+beforeclean:
+ chflags -R noschg .
+.include <bsd.obj.mk>
+clean: beforeclean
+
+base.txz:
+ mkdir -p ${DISTDIR}
+ cd ${WORLDDIR} && ${IMAKE} distributeworld DISTDIR=${.OBJDIR}/${DISTDIR}
+# Set up mergemaster root database
+ sh ${.CURDIR}/scripts/mm-mtree.sh -m ${WORLDDIR} -F \
+ "TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET}" -D "${.OBJDIR}/${DISTDIR}/base"
+ etcupdate extract -B -M "TARGET_ARCH=${TARGET_ARCH} TARGET=${TARGET}" \
+ -s ${WORLDDIR} -d "${.OBJDIR}/${DISTDIR}/base/var/db/etcupdate"
+# Package all components
+ cd ${WORLDDIR} && ${IMAKE} packageworld DISTDIR=${.OBJDIR}/${DISTDIR}
+ mv ${DISTDIR}/*.txz .
+
+kernel.txz:
+ mkdir -p ${DISTDIR}
+ cd ${WORLDDIR} && ${IMAKE} distributekernel packagekernel DISTDIR=${.OBJDIR}/${DISTDIR}
+ mv ${DISTDIR}/kernel*.txz .
+
+src.txz:
+ mkdir -p ${DISTDIR}/usr
+ ln -fs ${WORLDDIR} ${DISTDIR}/usr/src
+ cd ${DISTDIR} && tar cLvf - --exclude .svn --exclude .zfs \
+ --exclude .git --exclude @ --exclude usr/src/release/dist usr/src | \
+ ${XZ_CMD} > ${.OBJDIR}/src.txz
+
+ports.txz:
+ mkdir -p ${DISTDIR}/usr
+ ln -fs ${PORTSDIR} ${DISTDIR}/usr/ports
+ cd ${DISTDIR} && tar cLvf - \
+ --exclude .git --exclude .svn \
+ --exclude usr/ports/distfiles --exclude usr/ports/packages \
+ --exclude 'usr/ports/INDEX*' --exclude work usr/ports | \
+ ${XZ_CMD} > ${.OBJDIR}/ports.txz
+
+reldoc:
+ cd ${.CURDIR}/doc && ${MAKE} all install clean 'FORMATS=html txt' \
+ INSTALL_COMPRESSED='' URLS_ABSOLUTE=YES DOCDIR=${.OBJDIR}/rdoc
+ mkdir -p reldoc
+.for i in hardware readme relnotes errata
+ ln -f rdoc/${RELNOTES_LANG}/${i}/article.txt reldoc/${i:tu}.TXT
+ ln -f rdoc/${RELNOTES_LANG}/${i}/article.html reldoc/${i:tu}.HTM
+.endfor
+ cp rdoc/${RELNOTES_LANG}/readme/docbook.css reldoc
+
+disc1: packagesystem
+# Install system
+ mkdir -p ${.TARGET}
+ cd ${WORLDDIR} && ${IMAKE} installkernel installworld distribution \
+ DESTDIR=${.OBJDIR}/${.TARGET} MK_RESCUE=no MK_KERNEL_SYMBOLS=no \
+ MK_PROFILE=no MK_SENDMAIL=no MK_TESTS=no MK_LIB32=no \
+ MK_DEBUG_FILES=no
+# Copy distfiles
+ mkdir -p ${.TARGET}/usr/freebsd-dist
+ for dist in MANIFEST $$(ls *.txz | grep -v -- '-dbg'); \
+ do cp $${dist} ${.TARGET}/usr/freebsd-dist; \
+ done
+# Copy documentation, if generated
+.if !defined(NODOC)
+ cp reldoc/* ${.TARGET}
+.endif
+# Set up installation environment
+ ln -fs /tmp/bsdinstall_etc/resolv.conf ${.TARGET}/etc/resolv.conf
+ echo sendmail_enable=\"NONE\" > ${.TARGET}/etc/rc.conf
+ echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf
+ echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf
+ echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf
+ cp ${.CURDIR}/rc.local ${.TARGET}/etc
+ touch ${.TARGET}
+
+bootonly: packagesystem
+# Install system
+ mkdir -p ${.TARGET}
+ cd ${WORLDDIR} && ${IMAKE} installkernel installworld distribution \
+ DESTDIR=${.OBJDIR}/${.TARGET} MK_AMD=no MK_AT=no \
+ MK_GAMES=no MK_GROFF=no \
+ MK_INSTALLLIB=no MK_LIB32=no MK_MAIL=no \
+ MK_NCP=no MK_TOOLCHAIN=no MK_PROFILE=no \
+ MK_INSTALLIB=no MK_RESCUE=no MK_DICT=no \
+ MK_KERNEL_SYMBOLS=no MK_TESTS=no MK_DEBUG_FILES=no
+# Copy manifest only (no distfiles) to get checksums
+ mkdir -p ${.TARGET}/usr/freebsd-dist
+ cp MANIFEST ${.TARGET}/usr/freebsd-dist
+# Copy documentation, if generated
+.if !defined(NODOC)
+ cp reldoc/* ${.TARGET}
+.endif
+# Set up installation environment
+ ln -fs /tmp/bsdinstall_etc/resolv.conf ${.TARGET}/etc/resolv.conf
+ echo sendmail_enable=\"NONE\" > ${.TARGET}/etc/rc.conf
+ echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf
+ echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf
+ echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf
+ cp ${.CURDIR}/rc.local ${.TARGET}/etc
+
+dvd: packagesystem
+# Install system
+ mkdir -p ${.TARGET}
+ cd ${WORLDDIR} && ${IMAKE} installkernel installworld distribution \
+ DESTDIR=${.OBJDIR}/${.TARGET} MK_RESCUE=no MK_KERNEL_SYMBOLS=no \
+ MK_TESTS=no MK_DEBUG_FILES=no
+# Copy distfiles
+ mkdir -p ${.TARGET}/usr/freebsd-dist
+ for dist in MANIFEST $$(ls *.txz | grep -v -- '-dbg'); \
+ do cp $${dist} ${.TARGET}/usr/freebsd-dist; \
+ done
+# Copy documentation, if generated
+.if !defined(NODOC)
+ cp reldoc/* ${.TARGET}
+.endif
+# Set up installation environment
+ ln -fs /tmp/bsdinstall_etc/resolv.conf ${.TARGET}/etc/resolv.conf
+ echo sendmail_enable=\"NONE\" > ${.TARGET}/etc/rc.conf
+ echo hostid_enable=\"NO\" >> ${.TARGET}/etc/rc.conf
+ echo debug.witness.trace=0 >> ${.TARGET}/etc/sysctl.conf
+ echo vfs.mountroot.timeout=\"10\" >> ${.TARGET}/boot/loader.conf
+ cp ${.CURDIR}/rc.local ${.TARGET}/etc
+ touch ${.TARGET}
+
+release.iso: disc1.iso
+disc1.iso: disc1
+ sh ${.CURDIR}/${TARGET}/mkisoimages.sh -b ${VOLUME_LABEL}_CD ${.TARGET} disc1 ${XTRADIR}
+
+dvd1.iso: dvd pkg-stage
+ sh ${.CURDIR}/${TARGET}/mkisoimages.sh -b ${VOLUME_LABEL}_DVD ${.TARGET} dvd ${XTRADIR}
+
+bootonly.iso: bootonly
+ sh ${.CURDIR}/${TARGET}/mkisoimages.sh -b ${VOLUME_LABEL}_BO ${.TARGET} bootonly ${XTRADIR}
+
+memstick: memstick.img
+memstick.img: disc1
+ sh ${.CURDIR}/${TARGET}/make-memstick.sh disc1 ${.TARGET}
+
+mini-memstick: mini-memstick.img
+mini-memstick.img: bootonly
+ sh ${.CURDIR}/${TARGET}/make-memstick.sh bootonly ${.TARGET}
+
+packagesystem: base.txz kernel.txz ${EXTRA_PACKAGES}
+ sh ${.CURDIR}/scripts/make-manifest.sh *.txz > MANIFEST
+ touch ${.TARGET}
+
+pkg-stage:
+.if !defined(NOPKG)
+ env REPOS_DIR=${.CURDIR}/pkg_repos/ \
+ sh ${.CURDIR}/scripts/pkg-stage.sh
+ mkdir -p ${.OBJDIR}/dvd/packages/repos/
+ cp ${.CURDIR}/scripts/FreeBSD_install_cdrom.conf \
+ ${.OBJDIR}/dvd/packages/repos/
+.endif
+ touch ${.TARGET}
+
+cdrom: disc1.iso bootonly.iso
+dvdrom: dvd1.iso
+ftp: packagesystem
+ rm -rf ftp
+ mkdir -p ftp
+ cp *.txz MANIFEST ftp
+
+release: real-release vm-release cloudware-release
+ touch ${.OBJDIR}/${.TARGET}
+
+real-release:
+ ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} obj
+ ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${RELEASE_TARGETS}
+
+install: release-install vm-install cloudware-install
+
+release-install:
+.if defined(DESTDIR) && !empty(DESTDIR)
+ mkdir -p ${DESTDIR}
+.endif
+ cp -a ftp ${DESTDIR}/
+.for I in ${IMAGES}
+ cp -p ${I} ${DESTDIR}/${OSRELEASE}-${I}
+. if defined(WITH_COMPRESSED_IMAGES) && !empty(WITH_COMPRESSED_IMAGES)
+ ${XZ_CMD} -k ${DESTDIR}/${OSRELEASE}-${I}
+. endif
+.endfor
+ cd ${DESTDIR} && sha512 ${OSRELEASE}* > ${DESTDIR}/CHECKSUM.SHA512
+ cd ${DESTDIR} && sha256 ${OSRELEASE}* > ${DESTDIR}/CHECKSUM.SHA256
+
+.include "${.CURDIR}/Makefile.vm"
diff --git a/release/Makefile.azure b/release/Makefile.azure
new file mode 100644
index 0000000..12fd348
--- /dev/null
+++ b/release/Makefile.azure
@@ -0,0 +1,53 @@
+#
+# $FreeBSD$
+#
+#
+# Makefile for uploading Microsoft Azure disk images.
+#
+
+AZURE_IMG?= ${.OBJDIR}/azure.vhdf
+AZURE_UPLOAD_TGTS= azure-check-depends \
+ azure-do-upload
+CLEANFILES+= ${AZURE_UPLOAD_TGTS}
+
+.if defined(AZURE_UPLOAD_CONF) && !empty(AZURE_UPLOAD_CONF)
+. for VAR in _STORAGE _ACCOUNT _KEY
+AZURE${VAR}!= grep -E ^AZURE${VAR} ${AZURE_UPLOAD_CONF} | awk -F' ' '{print $$2}'
+. endfor
+.endif
+
+.if ${BRANCH} == "STABLE" || ${BRANCH} == "CURRENT" || ${BRANCH} == "PRERELEASE"
+SNAPSHOT_DATE!= date +-%Y-%m-%d
+.endif
+
+AZURE_TARGET:= ${OSRELEASE}${SNAPSHOT_DATE}.vhd
+
+azure-upload: ${AZURE_UPLOAD_TGTS}
+
+azure-check-depends:
+.for VAR in _STORAGE _ACCOUNT _KEY
+. if !defined(AZURE${VAR}) || empty(AZURE${VAR})
+ @echo "Variable AZURE${VAR} cannot be empty."
+ @false
+. endif
+.endfor
+.if !exists(/usr/local/bin/azure)
+. if !exists(/usr/local/bin/npm)
+. if !exists(${PORTSDIR}/www/npm/Makefile)
+. if !exists(/usr/local/sbin/pkg-static)
+ env ASSUME_ALWAYS_YES=yes pkg bootstrap -yf
+. endif
+ env ASSUME_ALWAYS_YES=yes pkg install -y www/npm
+. else
+ make -C ${PORTSDIR}/www/npm BATCH=1 all install clean
+. endif
+. endif
+ npm install -g azure-cli
+.endif
+
+azure-do-upload:
+ /usr/local/bin/azure storage blob upload \
+ ${AZURE_IMG} ${AZURE_STORAGE} ${AZURE_TARGET} \
+ -t page -a ${AZURE_ACCOUNT} -k "${AZURE_KEY}"
+ touch ${.OBJDIR}/${.TARGET}
+
diff --git a/release/Makefile.ec2 b/release/Makefile.ec2
new file mode 100644
index 0000000..2695183
--- /dev/null
+++ b/release/Makefile.ec2
@@ -0,0 +1,59 @@
+#
+# $FreeBSD$
+#
+#
+# Makefile for creating an EC2 AMI from a disk image.
+#
+
+.if ${BRANCH} == "CURRENT" || ${BRANCH} == "STABLE" || ${BRANCH} == "PRERELEASE"
+AMINAMESUFFIX!= date +-%Y-%m-%d
+.endif
+.if defined(EC2PUBLIC)
+PUBLISH= --public
+.endif
+
+CLEANFILES+= ec2ami
+
+.if !exists(/usr/local/bin/bsdec2-image-upload)
+CW_EC2_PORTINSTALL= cw-ec2-portinstall
+CLEANFILES+= ${CW_EC2_PORTINSTALL}
+.else
+CW_EC2_PORTINSTALL=
+.endif
+
+cw-ec2-portinstall:
+.if exists(${PORTSDIR}/net/bsdec2-image-upload/Makefile)
+ make -C ${PORTSDIR}/net/bsdec2-image-upload BATCH=1 all install clean
+.else
+. if !exists(/usr/local/sbin/pkg-static)
+ env ASSUME_ALWAYS_YES=yes pkg bootstrap -y
+. endif
+ env ASSUME_ALWAYS_YES=yes pkg install -y net/bsdec2-image-upload
+.endif
+ @touch ${.TARGET}
+
+ec2ami: cw-ec2 ${CW_EC2_PORTINSTALL}
+.if !defined(AWSKEYFILE) || !exists(${AWSKEYFILE})
+ @echo "--------------------------------------------------------------"
+ @echo ">>> AWSKEYFILE must point at AWS keys for EC2 AMI creation"
+ @echo "--------------------------------------------------------------"
+ @false
+.endif
+.if !defined(AWSREGION)
+ @echo "--------------------------------------------------------------"
+ @echo ">>> AWSREGION must be specified EC2 AMI creation"
+ @echo "--------------------------------------------------------------"
+ @false
+.endif
+.if !defined(AWSBUCKET)
+ @echo "--------------------------------------------------------------"
+ @echo ">>> AWSBUCKET must be specified for EC2 AMI creation"
+ @echo "--------------------------------------------------------------"
+ @false
+.endif
+ /usr/local/bin/bsdec2-image-upload ${PUBLISH} \
+ ${.OBJDIR}/ec2.raw \
+ "${TYPE} ${REVISION}-${BRANCH}-${TARGET}${AMINAMESUFFIX}" \
+ "${TYPE} ${REVISION}-${BRANCH}-${TARGET}" \
+ ${AWSREGION} ${AWSBUCKET} ${AWSKEYFILE}
+ @touch ${.TARGET}
diff --git a/release/Makefile.gce b/release/Makefile.gce
new file mode 100644
index 0000000..b6b6577
--- /dev/null
+++ b/release/Makefile.gce
@@ -0,0 +1,69 @@
+#
+# $FreeBSD$
+#
+#
+# Makefile for uploading Google Compute Engine disk images.
+#
+
+GCE_IMG?= ${.OBJDIR}/gce.raw
+GCE_UPLOAD_TGTS= gce-check-depends \
+ gce-do-package \
+ gce-do-upload
+# I do not yet have a better way to deal with the "must be run interactively"
+# thing, so this is a fail-safe "do not do anything."
+.if !defined(GCE_LOGIN_SKIP) || empty(GCE_LOGIN_SKIP)
+GCE_UPLOAD_TGTS= gce-do-login
+.endif
+CLEANFILES+= ${GCE_UPLOAD_TGTS}
+
+GCE_BUCKET?=
+
+.if ${BRANCH} == "STABLE" || ${BRANCH} == "CURRENT" || ${BRANCH} == "PRERELEASE"
+SNAPSHOT_DATE!= date +-%Y-%m-%d
+.endif
+
+# Really? Uppercase characters are not allowed? Sigh...
+# And don't even get me started on the '.'.
+GCE_TARGET:= ${OSRELEASE:S,.raw,,:tl:S,.,-,g}${SNAPSHOT_DATE}
+
+gce-upload: ${GCE_UPLOAD_TGTS}
+
+gce-check-depends:
+.for VAR in _BUCKET
+. if !defined(GCE${VAR}) || empty(GCE${VAR})
+ @echo "Variable GCE${VAR} cannot be empty."
+ @false
+. endif
+.endfor
+.if !exists(/usr/local/bin/gcutil)
+. if !exists(${PORTSDIR}/net/google-cloud-sdk/Makefile)
+. if !exists(/usr/local/sbin/pkg-static)
+ env ASSUME_ALWAYS_YES=yes pkg bootstrap -yf
+. endif
+ env ASSUME_ALWAYS_YES=yes pkg install -y net/google-cloud-sdk
+. else
+ make -C ${PORTSDIR}/net/google-cloud-sdk BATCH=1 all install clean
+. endif
+.endif
+
+gce-do-package:
+ @# Yes, really... Sigh.
+ cd ${.OBJDIR} && mv gce.raw disk.raw
+ cd ${.OBJDIR} && tar --format=gnutar -zcf \
+ ${GCE_TARGET:S,${.OBJDIR}/,,}.tar.gz disk.raw
+ cd ${.OBJDIR} && mv disk.raw gce.raw
+ touch ${.OBJDIR}/${.TARGET}
+
+gce-do-login:
+ @echo "This requires human interaction, which is not yet supported."
+ @true
+
+gce-do-upload:
+ @# Fallthrough in case the bucket already exists.
+ /usr/local/bin/gsutil mb gs://${GCE_BUCKET} || true
+ /usr/local/bin/gsutil cp ${.OBJDIR}/${GCE_TARGET}.tar.gz \
+ gs://${GCE_BUCKET}/
+ /usr/local/bin/gcutil addimage ${GCE_TARGET} \
+ gs://${GCE_BUCKET}/${GCE_TARGET}.tar.gz
+ touch ${.OBJDIR}/${.TARGET}
+
diff --git a/release/Makefile.mirrors b/release/Makefile.mirrors
new file mode 100644
index 0000000..92e5eda
--- /dev/null
+++ b/release/Makefile.mirrors
@@ -0,0 +1,254 @@
+#
+# This Makefile helps create the directory structure on ftp-master,
+# making staging builds a bit more sane.
+#
+# You probably do not want to use this. Really.
+# You have been warned.
+#
+# Seriously.
+#
+# Don't use this unless you know why you're using it.
+#
+# $FreeBSD$
+#
+
+.include "${.CURDIR}/Makefile"
+
+RELEASEDIR?= /R
+FTPDIR?= ${RELEASEDIR}/ftp-stage
+.if exists(${RELEASEDIR})
+STAGE_TARGETS?= iso-images-stage
+.endif
+
+.if (defined(EMBEDDED_TARGET) && !empty(EMBEDDED_TARGET)) || (defined(EMBEDDEDBUILD) && !empty(EMBEDDEDBUILD))
+. if ${TARGET} == "arm" || ${EMBEDDED_TARGET} == "arm"
+EMBEDDED= 1
+. endif
+.endif
+
+# snapshot
+.if ${BRANCH} == "STABLE" || ${BRANCH} == "CURRENT" || ${BRANCH} == "PRERELEASE"
+SNAPSHOT= 1
+TLD?= ${FTPDIR}/snapshots
+. if !defined(SVNREVISION) || empty(SVNREVISION)
+. for _D in /usr/bin /usr/local/bin
+. for _S in svnversion svnliteversion
+. if exists(${_D}/${_S})
+SVNVERSION?= ${_D}/${_S}
+. endif
+. endfor
+. endfor
+. if exists(${SVNVERSION}) && !empty(SVNVERSION)
+SVNREVISION!= ${SVNVERSION} ${WORLDDIR}/Makefile
+. endif
+. endif # !defined(SVNREVISION)
+. if !defined(BUILDDATE) || empty(BUILDDATE)
+. if exists(${.CURDIR}/${.OBJDIR}/dist/base/bin/sh)
+BUILDDATE!= cd ${.CURDIR} && date -j -f '%s' $$(stat -f "%c" ${.OBJDIR}/dist/base/bin/sh) +%Y%m%d
+. else
+BUILDDATE!= date +%Y%m%d
+. endif
+. endif
+_SNAP_SUFFIX:= ${BUILDDATE}-r${SVNREVISION}
+.else
+# release
+SNAPSHOT=
+TLD?= ${FTPDIR}/releases
+.endif
+
+.if defined(EMBEDDED) && !empty(EMBEDDED)
+. if ${TARGET} == "arm" && ${TARGET_ARCH} == "armv6"
+. if !defined(BOARDNAME) && empty(BOARDNAME)
+BOARDNAME:= ${KERNCONF}
+. else
+OLDNAME:= ${KERNCONF}
+. endif
+. if ${BRANCH} == "STABLE" || ${BRANCH} == "CURRENT" || ${BRANCH} == "PRERELEASE"
+SNAPSHOT= 1
+. endif
+IMAGES:= img
+. endif # arm/armv6
+.endif # embedded
+
+.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
+STAGE_TARGETS+= vm-images-stage
+VM_DIR= ${TLD}/VM-IMAGES/${REVISION}-${BRANCH}/${TARGET_ARCH}
+.endif
+
+CLEANFILES+= ${STAGE_TARGETS}
+CHECKSUM_FILES?= SHA512 SHA256
+SNAP_SUFFIX!= echo ${_SNAP_SUFFIX:S,^-,,1} | tr -d ' '
+ISO_DIR= ${TLD}/${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}
+FTP_DIR= ${TLD}/${TARGET}/${TARGET_ARCH}/${REVISION}-${BRANCH}
+
+remove-old-bits:
+ rm -rf ${FTPDIR}
+
+iso-images-stage:
+ mkdir -p ${ISO_DIR}
+ mkdir -p ${TLD}/ISO-IMAGES/${REVISION}
+.if defined(SNAPSHOT) && !empty(SNAPSHOT)
+ cd ${RELEASEDIR} && rm -f CHECKSUM.*
+. for IMAGE in ${IMAGES}
+. if defined(EMBEDDED) && !empty(EMBEDDED)
+. if defined(OLDNAME) && !empty(OLDNAME)
+ @# arm/armv6 IMX6 -> WANDBOARD, for example.
+ cd ${RELEASEDIR} && \
+ mv ${OSRELEASE}-${OLDNAME}.${IMAGE}.xz \
+ ${OSRELEASE}-${BOARDNAME}.${IMAGE}.xz
+. endif
+ cd ${RELEASEDIR} && \
+ mv ${OSRELEASE}-${BOARDNAME}.${IMAGE}.xz \
+ ${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}.${IMAGE}.xz
+ cp -p ${RELEASEDIR}/${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}.${IMAGE}.xz \
+ ${ISO_DIR}/${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}.${IMAGE}.xz
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}.${IMAGE}.xz
+. endif # not embedded
+. if exists(${RELEASEDIR}/${OSRELEASE}-${IMAGE})
+ cd ${RELEASEDIR} && \
+ mv ${OSRELEASE}-${IMAGE} \
+ ${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}
+ cp -p ${RELEASEDIR}/${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE} \
+ ${ISO_DIR}/${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}
+. endif
+. if exists(${RELEASEDIR}/${OSRELEASE}-${IMAGE}.xz)
+ cd ${RELEASEDIR} && \
+ mv ${OSRELEASE}-${IMAGE}.xz \
+ ${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}.xz
+ cp -p ${RELEASEDIR}/${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}.xz \
+ ${ISO_DIR}/${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}.xz
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/${OSRELEASE}-${SNAP_SUFFIX}-${IMAGE}.xz
+. endif
+. endfor # images loop
+ cd ${RELEASEDIR} && rm -f CHECKSUM.*
+. for CHECKSUM in ${CHECKSUM_FILES}
+. if defined(EMBEDDED) && !empty(EMBEDDED)
+ cd ${RELEASEDIR} && ${CHECKSUM:tl} ${OSRELEASE}* > \
+ CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}
+ cp -p ${RELEASEDIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX} \
+ ${ISO_DIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}-${SNAP_SUFFIX}
+. else # not embedded
+ cd ${RELEASEDIR} && ${CHECKSUM:tl} ${OSRELEASE}* > \
+ CHECKSUM.${CHECKSUM}-${OSRELEASE}-${SNAP_SUFFIX}
+ cp -p ${RELEASEDIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${SNAP_SUFFIX} \
+ ${ISO_DIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${SNAP_SUFFIX}
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${SNAP_SUFFIX}
+. endif #
+. endfor # checksum files
+.else # not snapshot
+. for IMAGE in ${IMAGES}
+. if defined(EMBEDDED) && !empty(EMBEDDED)
+. if defined(OLDNAME) && !empty(OLDNAME)
+ @# arm/armv6 IMX6 -> WANDBOARD, for example.
+ cd ${RELEASEDIR} && \
+ mv ${OSRELEASE}-${OLDNAME}.${IMAGE}.xz \
+ ${OSRELEASE}-${BOARDNAME}.${IMAGE}.xz
+. endif
+ cp -p ${RELEASEDIR}/${OSRELEASE}-${BOARDNAME}.${IMAGE}.xz \
+ ${ISO_DIR}/${OSRELEASE}-${BOARDNAME}.${IMAGE}.xz
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/${OSRELEASE}-${BOARDNAME}.${IMAGE}.xz
+. endif # not embedded
+. if exists(${RELEASEDIR}/${OSRELEASE}-${IMAGE})
+ cd ${RELEASEDIR} && \
+ cp -p ${RELEASEDIR}/${OSRELEASE}-${IMAGE} \
+ ${ISO_DIR}/${OSRELEASE}-${IMAGE}
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/${OSRELEASE}-${IMAGE}
+. endif
+. if exists(${RELEASEDIR}/${OSRELEASE}-${IMAGE}.xz)
+ cp -p ${RELEASEDIR}/${OSRELEASE}-${IMAGE}.xz \
+ ${ISO_DIR}/${OSRELEASE}-${IMAGE}.xz
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/${OSRELEASE}-${IMAGE}.xz
+. endif
+. endfor # images loop
+ cd ${RELEASEDIR} && rm -f CHECKSUM.*
+. for CHECKSUM in ${CHECKSUM_FILES}
+. if defined(EMBEDDED) && !empty(EMBEDDED)
+ cd ${RELEASEDIR} && ${CHECKSUM:tl} ${OSRELEASE}* > \
+ CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}
+ cp -p ${RELEASEDIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME} \
+ ${ISO_DIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/CHECKSUM.${CHECKSUM}-${OSRELEASE}-${BOARDNAME}
+. else # not embedded
+ cd ${RELEASEDIR} && ${CHECKSUM:tl} ${OSRELEASE}* > \
+ CHECKSUM.${CHECKSUM}-${OSRELEASE}
+ cp -p ${RELEASEDIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE} \
+ ${ISO_DIR}/CHECKSUM.${CHECKSUM}-${OSRELEASE}
+ cd ${TLD}/ISO-IMAGES/${REVISION} && \
+ ln -s \
+ ../../${TARGET}/${TARGET_ARCH}/ISO-IMAGES/${REVISION}/CHECKSUM.${CHECKSUM}-${OSRELEASE}
+. endif
+. endfor # checksum files
+.endif # release
+.if exists(${RELEASEDIR}/ftp)
+ mkdir -p ${FTP_DIR}
+ cp -p ${RELEASEDIR}/ftp/*.txz ${RELEASEDIR}/ftp/MANIFEST ${FTP_DIR}
+ cd ${TLD}/${TARGET} && \
+ ln -s ${TARGET_ARCH}/${REVISION}-${BRANCH} \
+ ${REVISION}-${BRANCH}
+.endif
+
+vm-images-stage:
+ mkdir -p ${VM_DIR}
+.if defined(SNAPSHOT) && !empty(SNAPSHOT)
+. if exists(${VM_DIR}/Latest)
+ rm -rf ${VM_DIR}/Latest
+. endif
+ mkdir -p ${VM_DIR}/Latest
+ mkdir -p ${VM_DIR}/${BUILDDATE}
+. for VMFORMAT in ${VMFORMATS}
+ cd ${RELEASEDIR}/vmimages && \
+ mv ${OSRELEASE}.${VMFORMAT}.xz \
+ ${OSRELEASE}-${SNAP_SUFFIX}.${VMFORMAT}.xz
+ cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}-${SNAP_SUFFIX}.${VMFORMAT}.xz \
+ ${VM_DIR}/${BUILDDATE}/${OSRELEASE}-${SNAP_SUFFIX}.${VMFORMAT}.xz
+ cd ${VM_DIR}/Latest && \
+ ln -s ../${BUILDDATE}/${OSRELEASE}-${SNAP_SUFFIX}.${VMFORMAT}.xz \
+ ${OSRELEASE}.${VMFORMAT}.xz
+. endfor
+ cd ${RELEASEDIR}/vmimages && rm -f CHECKSUM.*
+. for CHECKSUM in ${CHECKSUM_FILES}
+ cd ${RELEASEDIR}/vmimages && \
+ ${CHECKSUM:tl} ${OSRELEASE}* > CHECKSUM.${CHECKSUM}-${SNAP_SUFFIX}
+ cp -p ${RELEASEDIR}/vmimages/CHECKSUM.${CHECKSUM}-${SNAP_SUFFIX} \
+ ${VM_DIR}/${BUILDDATE}/CHECKSUM.${CHECKSUM}-${SNAP_SUFFIX}
+ cd ${VM_DIR}/Latest && \
+ ln -s ../${BUILDDATE}/CHECKSUM.${CHECKSUM}-${SNAP_SUFFIX} \
+ CHECKSUM.${CHECKSUM}
+. endfor
+.else # not snapshot
+. if exists(${VM_DIR}/Latest)
+ rm -rf ${VM_DIR}/Latest
+. endif
+ mkdir -p ${VM_DIR}/Latest
+. for VMFORMAT in ${VMFORMATS}
+ cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}.${VMFORMAT}.xz \
+ ${VM_DIR}/Latest/${OSRELEASE}.${VMFORMAT}.xz
+. endfor
+. for CHECKSUM in ${CHECKSUM_FILES}
+ cp -p ${RELEASEDIR}/vmimages/CHECKSUM.${CHECKSUM} \
+ ${VM_DIR}/Latest/CHECKSUM.${CHECKSUM}
+. endfor
+.endif
+
+ftp-stage: remove-old-bits ${STAGE_TARGETS}
+
diff --git a/release/Makefile.vagrant b/release/Makefile.vagrant
new file mode 100644
index 0000000..3b53ba9
--- /dev/null
+++ b/release/Makefile.vagrant
@@ -0,0 +1,122 @@
+#
+# $FreeBSD$
+#
+#
+# Makefile for uploading Vagrant boxes to Hashicorp Atlas
+#
+
+VAGRANT_IMG?= ${.OBJDIR}/vagrant.vmdk
+VAGRANT_UPLOAD_TGTS= vagrant-check-depends
+CLEANFILES+= ${VAGRANT_UPLOAD_TGTS}
+
+.if defined(VAGRANT_UPLOAD_CONF) && !empty(VAGRANT_UPLOAD_CONF)
+. for VAR in _KEY _USERNAME
+VAGRANT${VAR}!= grep -E ^VAGRANT${VAR} ${VAGRANT_UPLOAD_CONF} | awk -F' ' '{print $$2}'
+ATLAS${VAR}:= ${VAGRANT${VAR}}
+. endfor
+.endif
+
+.if ${BRANCH} == "STABLE" || ${BRANCH} == "CURRENT" || ${BRANCH} == "PRERELEASE"
+SNAPSHOT_DATE!= date +-%Y%m%d
+.endif
+
+VAGRANT_VERSION!= date +%Y.%m.%d
+VAGRANT_TARGET:= ${OSRELEASE}${SNAPSHOT_DATE}
+.if !empty(CLOUDWARE)
+. for _PROVIDER in ${CLOUDWARE}
+. if ${_PROVIDER:MVAGRANT*}
+VAGRANT_PROVIDERS+= ${_PROVIDER:S/VAGRANT-//:tl}
+. endif
+. endfor
+.endif
+VAGRANT_PROVIDERS?= vmware virtualbox
+
+
+vagrant-check-depends:
+.for VAR in _KEY _USERNAME _VERSION
+. if !defined(VAGRANT${VAR}) || empty(VAGRANT${VAR})
+ @echo "Variable VAGRANT${VAR} cannot be empty."
+ @false
+. endif
+.endfor
+.if !exists(/usr/local/bin/curl)
+. if !exists(${PORTSDIR}/ftp/curl/Makefile)
+. if !exists(/usr/local/sbin/pkg-static)
+ env ASSUME_ALWAYS_YES=yes pkg bootstrap -yf
+. endif
+ env ASSUME_ALWAYS_YES=yes pkg install -y curl
+. else
+ make -C ${PORTSDIR}/ftp/curl BATCH=1 all install clean
+. endif
+.endif
+
+.for PROVIDER in ${VAGRANT_PROVIDERS}
+CLEANFILES+= vagrant-do-package-${PROVIDER} ${VAGRANT_TARGET}.${PROVIDER}.box
+CLEANDIRS+= ${PROVIDER}
+VAGRANT_UPLOAD_TGTS+= vagrant-do-upload-${PROVIDER}
+
+${PROVIDER}:
+ @mkdir -p ${PROVIDER}
+
+${VAGRANT_TARGET}.${PROVIDER}.box: ${PROVIDER} cw-vagrant-${PROVIDER} vagrant-create-${PROVIDER}-metadata
+ @echo "==> PACKAGING: ${VAGRANT_TARGET}.${PROVIDER}.box in `pwd`"
+ @cp vagrant-${PROVIDER}.vmdk ${PROVIDER}/vagrant.vmdk
+. if ${PROVIDER} == "virtualbox"
+ @(cd ${.OBJDIR}/${PROVIDER} && echo '{"provider":"${PROVIDER}"}' > metadata.json)
+ @(cd ${.OBJDIR}/${PROVIDER} && tar -czf ../${VAGRANT_TARGET}.${PROVIDER}.box metadata.json box.ovf vagrant.vmdk)
+. elif ${PROVIDER} == "vmware"
+ @(cd ${.OBJDIR}/${PROVIDER} && echo '{"provider":"${PROVIDER}_desktop"}' > metadata.json)
+ @(cd ${.OBJDIR}/${PROVIDER} && tar -czf ../${VAGRANT_TARGET}.${PROVIDER}.box metadata.json vagrant.vmx vagrant.vmdk)
+. endif
+
+CLEANFILES+= vagrant-do-upload-${PROVIDER}
+vagrant-do-upload-${PROVIDER}: ${VAGRANT_TARGET}.${PROVIDER}.box
+. if ${PROVIDER} == "virtualbox"
+ ${.CURDIR}/scripts/atlas-upload.sh -b ${TYPE}-${REVISION}-${BRANCH} -f ${VAGRANT_TARGET}.${PROVIDER}.box -p ${PROVIDER} -k ${VAGRANT_KEY} -u ${VAGRANT_USERNAME} -v ${VAGRANT_VERSION}
+. elif ${PROVIDER} == "vmware"
+ ${.CURDIR}/scripts/atlas-upload.sh -b ${TYPE}-${REVISION}-${BRANCH} -f ${VAGRANT_TARGET}.${PROVIDER}.box -p ${PROVIDER}_desktop -k ${VAGRANT_KEY} -u ${VAGRANT_USERNAME} -v ${VAGRANT_VERSION}
+. endif
+ touch ${.OBJDIR}/${.TARGET}
+.endfor
+
+vagrant-upload: ${VAGRANT_UPLOAD_TGTS}
+
+vagrant-create-virtualbox-metadata: virtualbox/box.ovf
+
+virtualbox/box.ovf: ${.CURDIR}/scripts/box.ovf
+ cp ${.ALLSRC} virtualbox/
+
+vmware/vagrant.vmx:
+ @(cd vmware && echo '.encoding = "UTF-8"' > vagrant.vmx)
+ @(cd vmware && echo 'bios.bootorder = "hdd,CDROM"' >> vagrant.vmx)
+ @(cd vmware && echo 'checkpoint.vmstate = ""' >> vagrant.vmx)
+ @(cd vmware && echo 'cleanshutdown = "TRUE"' >> vagrant.vmx)
+ @(cd vmware && echo 'config.version = "8"' >> vagrant.vmx)
+ @(cd vmware && echo 'displayname = "${VAGRANT_TARGET}"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.addresstype = "generated"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.bsdname = "en0"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.connectiontype = "nat"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.displayname = "Ethernet"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.linkstatepropagation.enable = "FALSE"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.pcislotnumber = "33"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.present = "TRUE"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.virtualdev = "e1000"' >> vagrant.vmx)
+ @(cd vmware && echo 'ethernet0.wakeonpcktrcv = "FALSE"' >> vagrant.vmx)
+ @(cd vmware && echo 'floppy0.present = "FALSE"' >> vagrant.vmx)
+ @(cd vmware && echo 'guestos = "freebsd-64"' >> vagrant.vmx)
+ @(cd vmware && echo 'gui.fullscreenatpoweron = "FALSE"' >> vagrant.vmx)
+ @(cd vmware && echo 'gui.viewmodeatpoweron = "windowed"' >> vagrant.vmx)
+ @(cd vmware && echo 'memsize = "512"' >> vagrant.vmx)
+ @(cd vmware && echo 'sound.startconnected = "FALSE"' >> vagrant.vmx)
+ @(cd vmware && echo 'softpoweroff = "TRUE"' >> vagrant.vmx)
+ @(cd vmware && echo 'scsi0.pcislotnumber = "16"' >> vagrant.vmx)
+ @(cd vmware && echo 'scsi0.present = "TRUE"' >> vagrant.vmx)
+ @(cd vmware && echo 'scsi0.virtualdev = "lsilogic"' >> vagrant.vmx)
+ @(cd vmware && echo 'scsi0:0.filename = "vagrant.vmdk"' >> vagrant.vmx)
+ @(cd vmware && echo 'scsi0:0.present = "TRUE"' >> vagrant.vmx)
+ @(cd vmware && echo 'tools.synctime = "TRUE"' >> vagrant.vmx)
+ @(cd vmware && echo 'usb.present = "FALSE"' >> vagrant.vmx)
+ @(cd vmware && echo 'virtualhw.productcompatibility = "hosted"' >> vagrant.vmx)
+ @(cd vmware && echo 'virtualhw.version = "9"' >> vagrant.vmx)
+
+vagrant-create-vmware-metadata: vmware/vagrant.vmx
diff --git a/release/Makefile.vm b/release/Makefile.vm
new file mode 100644
index 0000000..902442f
--- /dev/null
+++ b/release/Makefile.vm
@@ -0,0 +1,167 @@
+#
+# $FreeBSD$
+#
+#
+# Makefile for building virtual machine and cloud provider disk images.
+#
+
+VMTARGETS= vm-image
+VMFORMATS?= vhd vmdk qcow2 raw
+VMSIZE?= 20G
+VMBASE?= vm
+
+VHD_DESC= Azure, VirtualPC, Hyper-V, Xen disk image
+VMDK_DESC= VMWare, VirtualBox disk image
+QCOW2_DESC= Qemu, KVM disk image
+RAW_DESC= Unformatted raw disk image
+
+CLOUDWARE?= AZURE \
+ EC2 \
+ GCE \
+ OPENSTACK \
+ VAGRANT-VIRTUALBOX \
+ VAGRANT-VMWARE
+AZURE_FORMAT= vhdf
+AZURE_DESC= Microsoft Azure platform image
+AZURE_DISK= ${OSRELEASE}.${AZURE_FORMAT}
+EC2_FORMAT= raw
+EC2_DESC= Amazon EC2 image
+EC2_DISK= ${OSRELEASE}.${EC2_FORMAT}
+GCE_FORMAT= raw
+GCE_DESC= Google Compute Engine image
+GCE_DISK= disk.${GCE_FORMAT}
+OPENSTACK_FORMAT=qcow2
+OPENSTACK_DESC= OpenStack platform image
+OPENSTACK_DISK= ${OSRELEASE}.${OPENSTACK_FORMAT}
+VAGRANT-VIRTUALBOX_FORMAT= vmdk
+VAGRANT-VIRTUALBOX_DESC= Vagrant Image for VirtualBox
+VAGRANT-VIRTUALBOX_DISK= ${OSRELEASE}.vbox.${VAGRANT_FORMAT}
+VAGRANT-VMWARE_FORMAT= vmdk
+VAGRANT-VMWARE_DESC= Vagrant Image for VMWare
+VAGRANT-VMWARE_DISK= ${OSRELEASE}.vmware.${VAGRANT_FORMAT}
+
+.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
+. for _CW in ${CLOUDWARE}
+CLOUDTARGETS+= cw-${_CW:tl}
+CLEANDIRS+= cw-${_CW:tl}
+CLEANFILES+= ${_CW:tl}.img \
+ ${_CW:tl}.${${_CW:tu}_FORMAT} \
+ ${_CW:tl}.${${_CW:tu}_FORMAT}.raw \
+ cw${_CW:tl}-package
+CLOUDINSTALL+= cw${_CW:tl}-install
+CLOUDPACKAGE+= cw${_CW:tl}-package
+${_CW:tu}IMAGE= ${_CW:tl}.${${_CW:tu}_FORMAT}
+. if exists(${.CURDIR}/tools/${_CW:tl}.conf) && !defined(${_CW:tu}CONF)
+${_CW:tu}CONF?= ${.CURDIR}/tools/${_CW:tl}.conf
+. endif
+
+cw-${_CW:tl}:
+ mkdir -p ${.OBJDIR}/${.TARGET}
+ env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
+ ${.CURDIR}/scripts/mk-vmimage.sh \
+ -C ${.CURDIR}/tools/vmimage.subr -d ${.OBJDIR}/${.TARGET} \
+ -i ${.OBJDIR}/${_CW:tl}.img -s ${VMSIZE} -f ${${_CW}_FORMAT} \
+ -S ${WORLDDIR} -o ${.OBJDIR}/${${_CW}IMAGE} -c ${${_CW}CONF}
+ touch ${.TARGET}
+
+cw${_CW:tl}-install:
+ mkdir -p ${DESTDIR}/${_CW:tl}
+ cp -p ${${_CW}IMAGE} \
+ ${DESTDIR}/${_CW:tl}/${${_CW}_DISK}
+ cd ${DESTDIR}/${_CW:tl} && sha512 ${${_CW}_DISK}* > \
+ ${DESTDIR}/${_CW:tl}/CHECKSUM.SHA512
+ cd ${DESTDIR}/${_CW:tl} && sha256 ${${_CW}_DISK}* > \
+ ${DESTDIR}/${_CW:tl}/CHECKSUM.SHA256
+
+cw${_CW:tl}-package:
+ @# Special target to handle packaging cloud images in the formats
+ @# specific to each hosting provider.
+.if exists(${.CURDIR}/tools/${_CW:tl}-package.sh)
+ env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
+ ${.CURDIR}/tools/${_CW:tl}-package.sh \
+ -D ${DESTDIR} -I ${${_CW}_DISK} -S ${WORLDDIR}
+.endif
+ touch ${.TARGET}
+
+. endfor
+.endif
+
+.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
+CLEANDIRS+= ${VMTARGETS}
+. for FORMAT in ${VMFORMATS}
+CLEANFILES+= ${FORMAT}.img
+CLEANFILES+= ${VMBASE}.${FORMAT}
+. endfor
+.endif
+
+vm-base: vm-image
+
+vm-image:
+.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
+. for FORMAT in ${VMFORMATS}
+ mkdir -p ${.OBJDIR}/${.TARGET}
+ env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
+ ${.CURDIR}/scripts/mk-vmimage.sh \
+ -C ${.CURDIR}/tools/vmimage.subr -d ${.OBJDIR}/${.TARGET} \
+ -i ${.OBJDIR}/${FORMAT}.img -s ${VMSIZE} -f ${FORMAT} \
+ -S ${WORLDDIR} -o ${.OBJDIR}/${VMBASE}.${FORMAT}
+. endfor
+.endif
+ touch ${.TARGET}
+
+vm-cloudware: ${CLOUDTARGETS}
+
+list-vmtargets: list-cloudware
+ @${ECHO}
+ @${ECHO} "Supported virtual machine disk image formats:"
+.for FORMAT in ${VMFORMATS:tu}
+ @${ECHO} " ${FORMAT:tl}: ${${FORMAT}_DESC}"
+.endfor
+
+list-cloudware:
+.if !empty(CLOUDWARE)
+ @${ECHO}
+ @${ECHO} "Supported cloud hosting provider images:"
+. for _CW in ${CLOUDWARE}
+ @${ECHO} " ${_CW:tu}: ${${_CW:tu}_DESC}"
+. endfor
+.endif
+
+vm-install:
+.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
+ mkdir -p ${DESTDIR}/vmimages
+. for FORMAT in ${VMFORMATS}
+ cp -p ${VMBASE}.${FORMAT} \
+ ${DESTDIR}/vmimages/${OSRELEASE}.${FORMAT}
+. endfor
+. if defined(WITH_COMPRESSED_VMIMAGES) && !empty(WITH_COMPRESSED_VMIMAGES)
+. for FORMAT in ${VMFORMATS}
+ # Don't keep the originals. There is a copy in ${.OBJDIR} if needed.
+ ${XZ_CMD} ${DESTDIR}/vmimages/${OSRELEASE}.${FORMAT}
+. endfor
+. endif
+ cd ${DESTDIR}/vmimages && sha512 ${OSRELEASE}* > \
+ ${DESTDIR}/vmimages/CHECKSUM.SHA512
+ cd ${DESTDIR}/vmimages && sha256 ${OSRELEASE}* > \
+ ${DESTDIR}/vmimages/CHECKSUM.SHA256
+.endif
+
+vm-release:
+.if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES)
+ ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${VMTARGETS}
+.endif
+
+cloudware-release:
+.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
+ ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${CLOUDTARGETS}
+.endif
+
+cloudware-install:
+.if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE)
+ ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${CLOUDINSTALL}
+.endif
+
+.include "${.CURDIR}/Makefile.ec2"
+.include "${.CURDIR}/Makefile.azure"
+.include "${.CURDIR}/Makefile.gce"
+.include "${.CURDIR}/Makefile.vagrant"
diff --git a/release/amd64/make-memstick.sh b/release/amd64/make-memstick.sh
new file mode 100755
index 0000000..6c289e0
--- /dev/null
+++ b/release/amd64/make-memstick.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# This script generates a "memstick image" (image that can be copied to a
+# USB memory stick) from a directory tree. Note that the script does not
+# clean up after itself very well for error conditions on purpose so the
+# problem can be diagnosed (full filesystem most likely but ...).
+#
+# Usage: make-memstick.sh <directory tree> <image filename>
+#
+# $FreeBSD$
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+if [ $# -ne 2 ]; then
+ echo "make-memstick.sh /path/to/directory /path/to/image/file"
+ exit 1
+fi
+
+if [ ! -d ${1} ]; then
+ echo "${1} must be a directory"
+ exit 1
+fi
+
+if [ -e ${2} ]; then
+ echo "won't overwrite ${2}"
+ exit 1
+fi
+
+echo '/dev/ufs/FreeBSD_Install / ufs ro,noatime 1 1' > ${1}/etc/fstab
+makefs -B little -o label=FreeBSD_Install ${2}.part ${1}
+if [ $? -ne 0 ]; then
+ echo "makefs failed"
+ exit 1
+fi
+rm ${1}/etc/fstab
+
+mkimg -s gpt -b ${1}/boot/pmbr -p efi:=${1}/boot/boot1.efifat -p freebsd-boot:=${1}/boot/gptboot -p freebsd-ufs:=${2}.part -p freebsd-swap::1M -o ${2}
+rm ${2}.part
+
diff --git a/release/amd64/mkisoimages.sh b/release/amd64/mkisoimages.sh
new file mode 100644
index 0000000..755fb52
--- /dev/null
+++ b/release/amd64/mkisoimages.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# Module: mkisoimages.sh
+# Author: Jordan K Hubbard
+# Date: 22 June 2001
+#
+# $FreeBSD$
+#
+# This script is used by release/Makefile to build the (optional) ISO images
+# for a FreeBSD release. It is considered architecture dependent since each
+# platform has a slightly unique way of making bootable CDs. This script
+# is also allowed to generate any number of images since that is more of
+# publishing decision than anything else.
+#
+# Usage:
+#
+# mkisoimages.sh [-b] image-label image-name base-bits-dir [extra-bits-dir]
+#
+# Where -b is passed if the ISO image should be made "bootable" by
+# whatever standards this architecture supports (may be unsupported),
+# image-label is the ISO image label, image-name is the filename of the
+# resulting ISO image, base-bits-dir contains the image contents and
+# extra-bits-dir, if provided, contains additional files to be merged
+# into base-bits-dir as part of making the image.
+
+if [ "x$1" = "x-b" ]; then
+ # This is highly x86-centric and will be used directly below.
+ bootable="-o bootimage=i386;$4/boot/cdboot -o no-emul-boot"
+
+ # Make EFI system partition (should be done with makefs in the future)
+ dd if=/dev/zero of=efiboot.img bs=4k count=100
+ device=`mdconfig -a -t vnode -f efiboot.img`
+ newfs_msdos -F 12 -m 0xf8 /dev/$device
+ mkdir efi
+ mount -t msdosfs /dev/$device efi
+ mkdir -p efi/efi/boot
+ cp "$4/boot/loader.efi" efi/efi/boot/bootx64.efi
+ umount efi
+ rmdir efi
+ mdconfig -d -u $device
+ bootable="-o bootimage=i386;efiboot.img -o no-emul-boot $bootable"
+
+ shift
+else
+ bootable=""
+fi
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 [-b] image-label image-name base-bits-dir [extra-bits-dir]"
+ exit 1
+fi
+
+LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift
+NAME="$1"; shift
+
+publisher="The FreeBSD Project. http://www.FreeBSD.org/"
+echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$1/etc/fstab"
+makefs -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@"
+rm "$1/etc/fstab"
+rm -f efiboot.img
diff --git a/release/arm/BANANAPI.conf b/release/arm/BANANAPI.conf
new file mode 100644
index 0000000..15994f4
--- /dev/null
+++ b/release/arm/BANANAPI.conf
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-bananapi"
+KERNEL="A20"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="32m -b 1m"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+export BOARDNAME="BANANAPI"
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-bananapi"
+ UBOOT_FILES="u-boot-sunxi-with-spl.bin"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \
+ of=/dev/${mddev} bs=1k seek=8 conv=sync
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/BEAGLEBONE.conf b/release/arm/BEAGLEBONE.conf
new file mode 100644
index 0000000..f9bb162
--- /dev/null
+++ b/release/arm/BEAGLEBONE.conf
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-beaglebone"
+KERNEL="BEAGLEBONE"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="2m"
+FAT_TYPE="12"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-beaglebone"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/CUBIEBOARD.conf b/release/arm/CUBIEBOARD.conf
new file mode 100644
index 0000000..f3bd0fb
--- /dev/null
+++ b/release/arm/CUBIEBOARD.conf
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-cubieboard"
+KERNEL="CUBIEBOARD"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="32m -b 1m"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubieboard"
+ UBOOT_FILES="u-boot-sunxi-with-spl.bin"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \
+ of=/dev/${mddev} bs=1k seek=8 conv=sync
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/CUBIEBOARD2.conf b/release/arm/CUBIEBOARD2.conf
new file mode 100644
index 0000000..6b5a4ac
--- /dev/null
+++ b/release/arm/CUBIEBOARD2.conf
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-cubieboard2"
+KERNEL="A20"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="32m -b 1m"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+export BOARDNAME="CUBIEBOARD2"
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubieboard2"
+ UBOOT_FILES="u-boot-sunxi-with-spl.bin"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \
+ of=/dev/${mddev} bs=1k seek=8 conv=sync
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/CUBOX-HUMMINGBOARD.conf b/release/arm/CUBOX-HUMMINGBOARD.conf
new file mode 100644
index 0000000..d69ca8e
--- /dev/null
+++ b/release/arm/CUBOX-HUMMINGBOARD.conf
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-cubox-hummingboard"
+KERNEL="IMX6"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x12000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="50m -b 16384"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+export BOARDNAME="CUBOX-HUMMINGBOARD"
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubox-hummingboard"
+ UBOOT_FILES="u-boot.imx"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \
+ of=/dev/${mddev} bs=512 seek=2
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/GUMSTIX.conf b/release/arm/GUMSTIX.conf
new file mode 100644
index 0000000..38445b1
--- /dev/null
+++ b/release/arm/GUMSTIX.conf
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-duovero"
+KERNEL="GUMSTIX"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="2m"
+FAT_TYPE="12"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-duovero"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/PANDABOARD.conf b/release/arm/PANDABOARD.conf
new file mode 100644
index 0000000..0b238df
--- /dev/null
+++ b/release/arm/PANDABOARD.conf
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-pandaboard"
+KERNEL="PANDABOARD"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="2m"
+FAT_TYPE="12"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-pandaboard"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/RPI-B.conf b/release/arm/RPI-B.conf
new file mode 100644
index 0000000..b97b7d0
--- /dev/null
+++ b/release/arm/RPI-B.conf
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-rpi"
+KERNEL="RPI-B"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="17m"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi"
+ UBOOT_FILES="bootcode.bin config.txt fixup.dat fixup_cd.dat \
+ start.elf start_cd.elf u-boot.img"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ for _UF in ${UBOOT_FILES}; do
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/${_UF} \
+ ${FATMOUNT}/${_UF}
+ done
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi.dtb \
+ ${FATMOUNT}/rpi.dtb
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/RPI2.conf b/release/arm/RPI2.conf
new file mode 100644
index 0000000..886a5aa
--- /dev/null
+++ b/release/arm/RPI2.conf
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-rpi2"
+KERNEL="RPI2"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="50m"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi2"
+ UBOOT_FILES="bootcode.bin config.txt fixup.dat fixup_cd.dat \
+ fixup_x.dat start.elf start_cd.elf start_x.elf u-boot.bin"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ for _UF in ${UBOOT_FILES}; do
+ chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/${_UF} \
+ ${FATMOUNT}/${_UF}
+ done
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi2.dtb \
+ ${FATMOUNT}/rpi2.dtb
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm/WANDBOARD.conf b/release/arm/WANDBOARD.conf
new file mode 100644
index 0000000..1afdc72
--- /dev/null
+++ b/release/arm/WANDBOARD.conf
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+EMBEDDEDBUILD=1
+EMBEDDED_TARGET="arm"
+EMBEDDED_TARGET_ARCH="armv6"
+EMBEDDEDPORTS="sysutils/u-boot-wandboard"
+KERNEL="IMX6"
+WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x12000000"
+IMAGE_SIZE="1G"
+PART_SCHEME="MBR"
+FAT_SIZE="50m -b 16384"
+FAT_TYPE="16"
+MD_ARGS="-x 63 -y 255"
+NODOC=1
+export BOARDNAME="WANDBOARD"
+
+arm_install_uboot() {
+ UBOOT_DIR="/usr/local/share/u-boot/u-boot-wandboard"
+ UBOOT_FILES="u-boot.imx"
+ FATMOUNT="${DESTDIR%${KERNEL}}/fat"
+ UFSMOUNT="${DESTDIR%${KERNEL}}/ufs"
+ chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \
+ of=/dev/${mddev} bs=512 seek=2
+ chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}"
+ chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT}
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT}
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr
+ chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr.bin \
+ ${FATMOUNT}/ubldr.bin
+ chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot
+ sync
+ umount_loop ${CHROOTDIR}/${FATMOUNT}
+ umount_loop ${CHROOTDIR}/${UFSMOUNT}
+ chroot ${CHROOTDIR} rmdir ${FATMOUNT}
+ chroot ${CHROOTDIR} rmdir ${UFSMOUNT}
+
+ return 0
+}
diff --git a/release/arm64/make-memstick.sh b/release/arm64/make-memstick.sh
new file mode 100755
index 0000000..27ebf27
--- /dev/null
+++ b/release/arm64/make-memstick.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# This script generates a "memstick image" (image that can be copied to a
+# USB memory stick) from a directory tree. Note that the script does not
+# clean up after itself very well for error conditions on purpose so the
+# problem can be diagnosed (full filesystem most likely but ...).
+#
+# Usage: make-memstick.sh <directory tree> <image filename>
+#
+# $FreeBSD$
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+if [ $# -ne 2 ]; then
+ echo "make-memstick.sh /path/to/directory /path/to/image/file"
+ exit 1
+fi
+
+if [ ! -d ${1} ]; then
+ echo "${1} must be a directory"
+ exit 1
+fi
+
+if [ -e ${2} ]; then
+ echo "won't overwrite ${2}"
+ exit 1
+fi
+
+echo '/dev/ufs/FreeBSD_Install / ufs ro,noatime 1 1' > ${1}/etc/fstab
+makefs -B little -o label=FreeBSD_Install ${2}.part ${1}
+if [ $? -ne 0 ]; then
+ echo "makefs failed"
+ exit 1
+fi
+rm ${1}/etc/fstab
+
+mkimg -s mbr -p efi:=${1}/boot/boot1.efifat -p freebsd:=${2}.part -o ${2}
+rm ${2}.part
+
diff --git a/release/doc/Makefile b/release/doc/Makefile
new file mode 100644
index 0000000..75bc4fd
--- /dev/null
+++ b/release/doc/Makefile
@@ -0,0 +1,38 @@
+# $FreeBSD$
+#
+# The user can override the default language to build and install
+# with the RELNOTES_LANG variable.
+#
+.if defined(RELNOTES_LANG) && !empty(RELNOTES_LANG)
+SUBDIR+= ${RELNOTES_LANG}
+.else
+SUBDIR+= en_US.ISO8859-1
+.endif
+SUBDIR+= share/xml
+
+RELN_ROOT?= ${.CURDIR}
+
+.if exists(/usr/local/bin/svn)
+SVN?= /usr/local/bin/svn
+.elif exists(/usr/bin/svn)
+SVN?= /usr/bin/svn
+.else
+SVN?= /usr/bin/svnlite
+.endif
+
+SVNFLAGS?= -r HEAD
+
+update:
+.if !exists(${SVN})
+ @echo "--------------------------------------------------------------"
+ @echo ">>> Updating ${RELN_ROOT} requires ${SVN}."
+ @echo "--------------------------------------------------------------"
+ @exit 1
+.endif
+ @echo "--------------------------------------------------------------"
+ @echo ">>> Updating ${.CURDIR}"
+ @echo "--------------------------------------------------------------"
+ @(cd ${.CURDIR} && ${SVN} update ${SVNFLAGS})
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.subdir.mk"
diff --git a/release/doc/README b/release/doc/README
new file mode 100644
index 0000000..a46779d
--- /dev/null
+++ b/release/doc/README
@@ -0,0 +1,127 @@
+-*- text -*-
+RELNOTESng README
+Bruce A. Mah <bmah@freebsd.org>
+$FreeBSD$
+
+This is the top-level directory for RELNOTESng, a re-write of
+FreeBSD's *.TXT documentation files. They have been converted to
+DocBook, and versions of the documents can be now be built for various
+supported architectures. The output files can be rendered in any
+format supported by the FreeBSD Documentation Project (for example,
+ASCII text, PDF, PS, HTML).
+
+RELNOTESng requires that the FreeBSD doc/ sources are installed; it
+leverages off of much of the DocProj build infrastructure, including
+DocBook extensions and stylesheets. If the doc/ sources are not
+installed in /usr/src, their location should be specified with the
+DOC_PREFIX Makefile variable. RELNOTESng also requires the DocProj
+build tools, which can easily be installed with the textproc/docproj
+port in the Ports Collection.
+
+Notable files and directories:
+
+share/mk/doc.relnotes.mk
+ Common Makefile definitions for RELNOTESng. These definitions
+ mostly accommodate the fact that we're building DocProj-like
+ documents outside the doc/ tree.
+share/xml/catalog
+ Main SGML catalog for all language-neutral (and default EN)
+ stylesheet and entity files. Can be overridden if needed for
+ translations.
+share/xml/default.dsl
+ All documents build with this file as a stylesheet. All it
+ does is to make it possible to use the document catalogs to
+ locate the "real" stylesheet by reference, rather than having
+ to specify it by pathname.
+share/xml/release.dsl
+ Language-neutral stylesheet. This stylesheet supports
+ the arch= attribute on (all?) DocBook elements; elements with
+ an arch= attribute are only included in the output if their
+ value is equal to the value of the &arch; entity. In the
+ future, arch= could be a list of possible &arch; entity values
+ that match, such as "i386,sparc64".
+share/xml/release.ent
+ Release information. Need to update the entry definitions in
+ this file when rolling new revisions; these should take effect
+ in all documents.
+
+en_US.ISO8859-1/share/xml/release.dsl
+ Language-dependent stylesheet for en, but also the default for
+ translations if they don't override the settings here. This
+ stylesheet sets the email footer at the bottom of HTML pages,
+ as well as a few other parameters. If necessary for
+ translations, this file can be overridden with
+ */share/xml/release.dsl and */share/xml/catalog.
+
+*/relnotes/common/
+ Directory for multi-architecture release notes files.
+*/relnotes/*/
+ Directories for architecture-specific release notes files.
+
+*/hardware/common/
+ Directory for multi-architecture hardware notes files.
+*/hardware/*/
+ Directories for architecture-specific hardware notes files.
+
+*/installation/common/
+ Directory for multi-architecture installation notes files.
+ Note that the FreeBSD DocProj build infrastructure does
+ not handle documents (or subdirectories) named "install"
+ well, so we call our document "installation" and do
+ a hack when it gets installed into a distribution to fix
+ this up.
+*/installation/*/
+ Directories for architecture-specific release notes files.
+
+*/errata/
+ Directory for errata document.
+
+*/readme/
+ Directory for (introductory) document.
+
+If building the release notes "standalone" (in other words, not part
+of a release), it may be necessary (depending on the relative
+locations of the checked-out src/ and doc/ directories) to set the
+DOC_PREFIX Makefile variable to point to the top directory of the doc/
+tree. For example:
+
+ % make DOC_PREFIX=/usr/doc all
+
+All definition of the "current" version of FreeBSD is contained in the
+share/xml/release.ent file; release engineers should peruse the
+contents of this file carefully when doing version number bumps.
+
+When creating content for the architecture-dependent files, authors
+should use the arch= attribute to elements that are specific to a
+particular machine architecture. The value of this attribute should
+be a single word that indicates for which architecture the current
+element will be included. For example:
+
+ <para arch="sparc64">SPARC64-specific text</para>
+
+The currently-supported architectures are amd64, arm, i386, pc98,
+powerpc and sparc64. An element may appear for multiple architectures
+by specifying a comma-separated list of architectures
+(i.e. arch="sparc64,amd64").
+
+When creating a translation, make a new directory under this
+directory with a language code (paralleling the DocProj directory
+structure). If necessary, new language-dependent HTML footers can be
+generated by making a new language-dependent
+${LANG}/share/xml/release.dsl, a ${LANG}/share/xml/catalog that
+points to it, and a new definition in the Makefiles that adds
+${LANG}/share/xml/catalog to EXTRA_CATALOGS. Except for the Makefile
+changes, this is the same procedure that is used for creating a new
+translation for DocProj files.
+
+RELNOTESng is now enabled by default in the FreeBSD release-build
+process. It can be disabled by setting NODOC=YES when building a
+release (note that this is the same variable that disables DocProj
+documentation builds).
+
+Release builders can set which language gets built with the
+RELNOTES_LANG variable; note that this is different from the
+DOC_LANG variable because (at least initially) most languages
+will have localized DocProj files but not localized release notes.
+The default language, if none is specified, is en_US.ISO8859-1.
+
diff --git a/release/doc/en_US.ISO8859-1/Makefile b/release/doc/en_US.ISO8859-1/Makefile
new file mode 100644
index 0000000..82e5f33
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+RELN_ROOT?= ${.CURDIR}/..
+
+SUBDIR = relnotes
+SUBDIR+= hardware
+SUBDIR+= readme
+SUBDIR+= errata
+
+COMPAT_SYMLINK = en
+
+LANGCODE=en_US.ISO8859-1
+_LANGCODE=en_US.ISO8859-1
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/release/doc/en_US.ISO8859-1/errata/Makefile b/release/doc/en_US.ISO8859-1/errata/Makefile
new file mode 100644
index 0000000..036609a
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/errata/Makefile
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+RELN_ROOT?= ${.CURDIR}/../..
+.ifdef NO_LANGCODE_IN_DESTDIR
+DESTDIR?= ${DOCDIR}/errata
+.else
+DESTDIR?= ${DOCDIR}/en_US.ISO8859-1/errata
+.endif
+
+DOC?= article
+FORMATS?= html
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+# SGML content
+SRCS+= article.xml
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/release/doc/en_US.ISO8859-1/errata/article.xml b/release/doc/en_US.ISO8859-1/errata/article.xml
new file mode 100644
index 0000000..2fdf294
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/errata/article.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
+<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN"
+ "http://www.FreeBSD.org/release/XML/release.ent">
+%release;
+<!ENTITY security SYSTEM "../../share/xml/security.xml">
+<!ENTITY errata SYSTEM "../../share/xml/errata.xml">
+]>
+
+<article xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="5.0">
+ <info>
+ <title>&os; &release; Errata </title>
+
+ <author><orgname>The &os; Project</orgname></author>
+
+ <pubdate>$FreeBSD$</pubdate>
+
+ <copyright>
+ <year>2015</year>
+
+ <holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
+ </copyright>
+
+ <legalnotice xml:id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.intel;
+ &tm-attrib.sparc;
+ &tm-attrib.general;
+ </legalnotice>
+
+ <abstract>
+ <para>This document lists errata items for &os; &release;,
+ containing significant information discovered after the release
+ or too late in the release cycle to be otherwise included in the
+ release documentation.
+ This information includes security advisories, as well as news
+ relating to the software or documentation that could affect its
+ operation or usability. An up-to-date version of this document
+ should always be consulted before installing this version of
+ &os;.</para>
+
+ <para>This errata document for &os; &release;
+ will be maintained until the release of &os; &release.next;.</para>
+ </abstract>
+ </info>
+
+ <sect1 xml:id="intro">
+ <title>Introduction</title>
+
+ <para>This errata document contains <quote>late-breaking news</quote>
+ about &os; &release;
+ Before installing this version, it is important to consult this
+ document to learn about any post-release discoveries or problems
+ that may already have been found and fixed.</para>
+
+ <para>Any version of this errata document actually distributed
+ with the release (for example, on a CDROM distribution) will be
+ out of date by definition, but other copies are kept updated on
+ the Internet and should be consulted as the <quote>current
+ errata</quote> for this release. These other copies of the
+ errata are located at
+ <link xlink:href="https://www.FreeBSD.org/releases/" />,
+ plus any sites
+ which keep up-to-date mirrors of this location.</para>
+
+ <para>Source and binary snapshots of &os; &release.branch; also
+ contain up-to-date copies of this document (as of the time of
+ the snapshot).</para>
+
+ <para>For a list of all &os; CERT security advisories, see
+ <link xlink:href="https://www.FreeBSD.org/security/"/>.</para>
+ </sect1>
+
+ <sect1 xml:id="security">
+ <title>Security Advisories</title>
+
+ &security;
+ </sect1>
+
+ <sect1 xml:id="errata">
+ <title>Errata Notices</title>
+
+ &errata;
+ </sect1>
+
+ <sect1 xml:id="open-issues">
+ <title>Open Issues</title>
+
+ <para>No open issues.</para>
+ </sect1>
+
+ <sect1 xml:id="late-news">
+ <title>Late-Breaking News</title>
+
+ <para>No news.</para>
+ </sect1>
+</article>
diff --git a/release/doc/en_US.ISO8859-1/hardware/Makefile b/release/doc/en_US.ISO8859-1/hardware/Makefile
new file mode 100644
index 0000000..4648146
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/hardware/Makefile
@@ -0,0 +1,30 @@
+# $FreeBSD$
+
+RELN_ROOT?= ${.CURDIR}/../..
+
+.ifdef NO_LANGCODE_IN_DESTDIR
+DESTDIR?= ${DOCDIR}/hardware
+.else
+DESTDIR?= ${DOCDIR}/en_US.ISO8859-1/hardware
+.endif
+
+DOC?= article
+FORMATS?= html
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+JADEFLAGS+= -V %generate-article-toc%
+
+# SGML content
+SRCS+= article.xml
+SRCS+= ${DEV-AUTODIR}/catalog-auto
+SRCS+= ${DEV-AUTODIR}/dev-auto.ent
+
+CATALOGS+= -c ${DEV-AUTODIR}/catalog-auto
+
+URL_RELPREFIX?= ../../../..
+
+HWNOTES_MI= 1
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/release/doc/en_US.ISO8859-1/hardware/article.xml b/release/doc/en_US.ISO8859-1/hardware/article.xml
new file mode 100644
index 0000000..4b66434
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/hardware/article.xml
@@ -0,0 +1,1659 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "../../../share/xml/freebsd50.dtd" [
+<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN" "release.ent">
+%release;
+<!ENTITY % devauto PUBLIC "-//FreeBSD//ENTITIES Auto Generated Device Lists//EN" "nonexistent">
+%devauto;
+]>
+<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
+ <info><title>&os; &release.current; Hardware Notes</title>
+
+
+ <author><orgname>The &os; Documentation Project</orgname></author>
+
+ <pubdate>$FreeBSD$</pubdate>
+
+ <copyright>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <year>2009</year>
+ <year>2010</year>
+ <year>2011</year>
+ <year>2012</year>
+ <year>2013</year>
+ <year>2014</year>
+ <holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
+ </copyright>
+
+ <legalnotice xml:id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.amd;
+ &tm-attrib.fujitsu;
+ &tm-attrib.ibm;
+ &tm-attrib.intel;
+ &tm-attrib.sparc;
+ &tm-attrib.sun;
+ &tm-attrib.general;
+ </legalnotice>
+
+ </info>
+
+ <sect1 xml:id="intro">
+ <title>Introduction</title>
+
+ <para>This document contains the hardware compatibility notes for
+ &os; &release.current;. It lists the hardware platforms
+ supported by &os;, as well as the various types of hardware
+ devices (storage controllers, network interfaces, and so on),
+ along with known working instances of these devices.</para>
+ </sect1>
+
+ <sect1 xml:id="proc">
+ <title>Supported Processors and System Boards</title>
+
+ <para>This section provides some architecture-specific information
+ about the specific processors and systems that are supported by
+ each architecture.</para>
+
+ <sect2 xml:id="proc-amd64">
+ <title>amd64</title>
+
+ <para>Since mid-2003 &os;/&arch.amd64; has supported the AMD64
+ (<quote>Hammer</quote>) and &intel; EM64T architecture, and is
+ now one of the Tier-1 platforms (fully supported
+ architecture), which are expected to be Production Quality
+ with respects to all aspects of the &os; operating system,
+ including installation and development environments.</para>
+
+ <para>Note that there are two names for this architecture, AMD64
+ (AMD) and Intel EM64T (Extended Memory 64-bit Technology).
+ 64-bit mode of the two architectures are almost compatible
+ with each other, and &os;/&arch.amd64; supports them
+ both.</para>
+
+ <para>As of this writing, the following processors are
+ supported:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&amd.athlon;64 (<quote>Clawhammer</quote>).</para>
+ </listitem>
+
+ <listitem>
+ <para>&amd.opteron; (<quote>Sledgehammer</quote>).</para>
+ </listitem>
+
+ <listitem>
+ <para>&amd.sempron;.</para>
+ </listitem>
+
+ <listitem>
+ <para>&amd.turion;.</para>
+ </listitem>
+
+ <listitem>
+ <para>&amd.phenom;.</para>
+ </listitem>
+
+ <listitem>
+ <para>All multi-core &intel; &xeon; processors except
+ Sossaman have EM64T support.</para>
+ </listitem>
+
+ <listitem>
+ <para>The single-core &intel; &xeon;
+ processors <quote>Nocona</quote>, <quote>Irwindale</quote>,
+ <quote>Potomac</quote>, and <quote>Cranford</quote> have
+ EM64T support.</para>
+ </listitem>
+
+ <listitem>
+ <para>All &intel; &core; 2 (not &core; Duo) and later
+ processors</para>
+ </listitem>
+
+ <listitem>
+ <para>All &intel; &core; i range of processors</para>
+ </listitem>
+
+ <listitem>
+ <para>All &intel; &pentium; D processors</para>
+ </listitem>
+
+ <listitem>
+ <para>All &intel; &centrino; Duo and &centrino; Pro platforms</para>
+ </listitem>
+
+ <listitem>
+ <para>&intel; &pentium; 4s and &celeron; Ds using
+ the <quote>Cedar Mill</quote> core have EM64T
+ support.</para>
+ </listitem>
+
+ <listitem>
+ <para>Some &intel; &pentium; 4s and &celeron; Ds using
+ the <quote>Prescott</quote> core have EM64T support. See
+ the <link xlink:href="http://processorfinder.intel.com">Intel
+ Processor Spec Finder</link> for the definitive answer about
+ EM64T support in Intel processors.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>&intel; EM64T is an extended version of IA-32 (x86) and
+ different from &intel; IA-64 (Itanium) architecture. Some
+ &intel;'s old documentation refers to &intel; EM64T as
+ <quote>64-bit extension technology</quote> or
+ <quote>IA-32e</quote>.</para>
+
+ <para>Both Uniprocessor (UP) and Symmetric Multi-processor (SMP)
+ configurations are supported.</para>
+
+ <para>In many respects, &os;/&arch.amd64; is similar to
+ &os;/&arch.i386;, in terms of drivers supported. Generally,
+ drivers that already function correctly on other 64-bit
+ platforms should work.</para>
+
+ </sect2>
+
+ <sect2 xml:id="proc-i386">
+ <title>i386</title>
+
+ <para>&os;/&arch.i386; runs on a wide variety of <quote>IBM PC
+ compatible</quote> machines. Due to the wide range of
+ hardware available for this architecture, it is impossible
+ to exhaustively list all combinations of equipment supported
+ by &os;. Nevertheless, some general guidelines are
+ presented here.</para>
+
+ <para>Almost all &i386;-compatible processors with a floating
+ point unit are supported. All &intel; processors beginning
+ with the 80486 are supported, including the 80486, &pentium;,
+ &pentium; Pro, &pentium; II, &pentium; III, &pentium; 4, and
+ variants thereof, such as the &xeon; and &celeron; processors.
+ All &i386;-compatible AMD processors are also supported,
+ including the &am486;, &am5x86;, K5, &amd.k6; (and variants),
+ &amd.athlon; (including Athlon-MP, Athlon-XP, Athlon-4, and
+ Athlon Thunderbird), and &amd.duron; processors. The AMD
+ &Eacute;lan SC520 embedded processor is supported. The
+ Transmeta Crusoe is recognized and supported, as are
+ &i386;-compatible processors from Cyrix and NexGen.</para>
+
+ <para>There is a wide variety of motherboards available for this
+ architecture. Motherboards using the ISA, VLB, EISA, AGP, and
+ PCI expansion buses are well-supported. There is some
+ limited support for the MCA (<quote>MicroChannel</quote>)
+ expansion bus used in the IBM PS/2 line of PCs.</para>
+
+ <para>Symmetric multi-processor (SMP) systems are generally
+ supported by &os;, although in some cases, BIOS or motherboard
+ bugs may generate some problems. Perusal of the archives of
+ the &a.smp; may yield some clues.</para>
+
+ <para>&os; will take advantage of SMT (Symmetric MultiThreading,
+ also known as HyperThreading on &intel; CPUs) on the supported
+ CPUs. The <filename>GENERIC</filename> kernel which is
+ installed by default will automatically detect the additional
+ logical processors. The default &os; scheduler recognizes
+ processor topology on the system and selects logical and
+ physical processors to obtain optimal performance.
+ The &man.smp.4; manual page has more details.</para>
+
+ <para>&os; will take advantage of Physical Address Extensions
+ (PAE) support on CPUs that support this feature. A kernel
+ with the <literal>PAE</literal> feature enabled will detect
+ memory above 4 gigabytes and allow it to be used by the
+ system. This feature places constraints on the device drivers
+ and other features of &os; which may be used; consult the
+ &man.pae.4; manual page for more details.</para>
+
+ <para>&os; will generally run on i386-based laptops, albeit with
+ varying levels of support for certain hardware features such
+ as sound, graphics, power management, and PCCARD expansion
+ slots. These features tend to vary in idiosyncratic ways
+ between machines, and frequently require special-case support
+ in &os; to work around hardware bugs or other oddities. When
+ in doubt, a search of the archives of the &a.mobile; may be
+ useful.</para>
+
+ <para>Most modern laptops (as well as many desktops) use the
+ Advanced Configuration and Power Management (ACPI) standard.
+ &os; supports ACPI via the ACPI Component Architecture
+ reference implementation from &intel;, as described in the
+ &man.acpi.4; manual page. The use of ACPI causes
+ instabilities on some machines and it may be necessary to
+ disable the ACPI driver, which is normally loaded via a kernel
+ module. This may be accomplished by adding the following line
+ to <filename>/boot/device.hints</filename>:</para>
+
+ <programlisting>hint.acpi.0.disabled="1"</programlisting>
+
+ <para>Users debugging ACPI-related problems may find it useful
+ to disable portions of the ACPI functionality. The
+ &man.acpi.4; manual page has more information on how to do
+ this via loader tunables.</para>
+
+ <para>ACPI depends on a Differentiated System Descriptor Table
+ (DSDT) provided by each machine's BIOS. Some machines have
+ bad or incomplete DSDTs, which prevents ACPI from functioning
+ correctly. Replacement DSDTs for some machines can be found
+ at the <link xlink:href="http://acpi.sourceforge.net/dsdt/index.php">DSDT</link>
+ section of the <link xlink:href="http://acpi.sourceforge.net/">ACPI4Linux</link> project
+ Web site. &os; can use these DSDTs to override the DSDT
+ provided by the BIOS; see the &man.acpi.4; manual page for
+ more information.</para>
+ </sect2>
+
+ <sect2 xml:id="proc-pc98">
+ <title>pc98</title>
+
+ <para>NEC PC-9801/9821 series with almost all &i386;-compatible
+ processors, including 80486, &pentium;, &pentium; Pro,
+ &pentium; II, and variants. All &i386;-compatible processors
+ by AMD, Cyrix, IBM, and IDT are also supported.</para>
+
+ <para>NEC FC-9801/9821 series, and NEC SV-98 series (both of
+ them are compatible with PC-9801/9821 series) should be
+ supported.</para>
+
+ <para>EPSON PC-386/486/586 series, which are compatible with NEC
+ PC-9801 series are supported.</para>
+
+ <para>High-resolution mode is not supported. NEC
+ PC-98XA/XL/RL/XL^2, and NEC PC-H98 series are supported in
+ normal (PC-9801 compatible) mode only.</para>
+
+ <para>Although there are some multi-processor systems (such as
+ Rs20/B20), SMP-related features of &os; are not supported
+ yet.</para>
+
+ <para>PC-9801/9821 standard bus (called C-Bus), PC-9801NOTE
+ expansion bus (110pin), and PCI bus are supported. New Extend
+ Standard Architecture (NESA) bus (used in PC-H98, SV-H98, and
+ FC-H98 series) is not supported.</para>
+ </sect2>
+
+ <sect2 xml:id="proc-powerpc">
+ <title>powerpc</title>
+
+ <para>All Apple PowerPC machines with built-in USB are supported,
+ as well a limited selection of non-Apple machines,
+ including KVM on POWER7</para>
+
+ <para>SMP is supported on all systems with more than
+ 1 processor.</para>
+ </sect2>
+
+ <sect2 xml:id="proc-sparc64">
+ <title>sparc64</title>
+
+ <para>This section describes the systems currently known to be
+ supported by &os; on the Fujitsu &sparc64; and Sun &ultrasparc;
+ platforms.</para>
+
+ <para>SMP is supported on all systems with more than 1
+ processor.</para>
+
+ <para>When using the <filename>GENERIC</filename> kernel,
+ &os;/&arch.sparc64; systems not equipped with a framebuffer
+ supported by the &man.creator.4; (Sun Creator, Sun Creator3D
+ and Sun Elite3D) or &man.machfb.4; (Sun PGX and Sun PGX64
+ as well as the ATI Mach64 chips found onboard in for example
+ &sun.blade; 100, &sun.blade; 150, &sun.ultra; 5 and &sun.ultra; 10)
+ driver must use the serial console.</para>
+
+ <para>If you have a system that is not listed here, it may not
+ have been tested with &os; &release.current;. We encourage
+ you to try it and send a note to the &a.sparc; with your
+ results, including which devices work and which do not.</para>
+
+ <para>The following systems are fully supported by &os;:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Naturetech GENIALstation 777S</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.blade; 100</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.blade; 150</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.enterprise; 150</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.enterprise; 220R</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.enterprise; 250</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.enterprise; 420R</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.enterprise; 450</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; B100s (support for the on-board NICs first
+ appeared in 8.1-RELEASE)</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V100</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V120</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; t1 100/105</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; T1 AC200/DC200</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; t 1100</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; t 1120</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; t 1125</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; t 1400/1405</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; 120</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &netra; X1</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &sparcengine; Ultra AX1105</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &sparcengine; Ultra AXe</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &sparcengine; Ultra AXi</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &sparcengine; Ultra AXmp</para>
+ </listitem>
+
+ <listitem>
+ <para>Sun &sparcengine; CP1500</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 1</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 1E</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 2</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 5</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 10</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 30</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 60</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 80</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.ultra; 450</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following systems are partially supported by &os;. In
+ particular the fiber channel controllers in SBus-based systems are not
+ supported. However, it is possible to use these with a SCSI controller
+ supported by the &man.esp.4; driver (Sun ESP SCSI, Sun FAS Fast-SCSI
+ and Sun FAS366 Fast-Wide SCSI controllers).</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&sun.enterprise; 3500</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.enterprise; 4500</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Starting with 7.2-RELEASE, &arch.sparc64; systems based on Sun
+ &ultrasparc; III and beyond are also supported by &os;, which includes
+ the following known working systems:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&sun.blade; 1000</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.blade; 1500</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.blade; 2000</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.blade; 2500</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; 280R</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V210</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V215 (support first appeared in 7.3-RELEASE and 8.1-RELEASE)</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V240</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V245 (support first appeared in 7.3-RELEASE and 8.1-RELEASE)</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V250</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V440 (support for the on-board NICs first
+ appeared in 7.3-RELEASE and 8.0-RELEASE)</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V480 (501-6780 and 501-6790 centerplanes only, for
+ which support first appeared in 7.3-RELEASE and 8.1-RELEASE,
+ other centerplanes might work beginning with 8.3-RELEASE and 9.0-RELEASE)</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V880</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V890 (support first appeared in 7.4-RELEASE and 8.1-RELEASE,
+ non-mixed &ultrasparc; IV/IV+ CPU-configurations only)</para>
+ </listitem>
+
+ <listitem>
+ <para>&netra; 20/&netra; T4</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following Sun &ultrasparc; systems are not tested but
+ believed to be also supported by &os;:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&sun.fire; V125</para>
+ </listitem>
+
+ <listitem>
+ <para>&sun.fire; V490 (support first appeared in 7.4-RELEASE and 8.1-RELEASE,
+ non-mixed &ultrasparc; IV/IV+ CPU-configurations only)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Starting with 7.4-RELEASE and 8.1-RELEASE, &arch.sparc64; systems based on
+ Fujitsu &sparc64; V are also supported by &os;, which
+ includes the following known working systems:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Fujitsu &primepower; 250</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following Fujitsu &primepower; systems are not tested but
+ believed to be also supported by &os;:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Fujitsu &primepower; 450</para>
+ </listitem>
+
+ <listitem>
+ <para>Fujitsu &primepower; 650</para>
+ </listitem>
+
+ <listitem>
+ <para>Fujitsu &primepower; 850</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <!--
+
+ The "Supported Devices" section of the release notes.
+ Generally processor-independent, with conditional text
+ inclusion handling any architecture-dependent text.
+
+ Within each subsection describing a class of hardware
+ (i.e. Ethernet interfaces), list broad groups of devices
+ alphabetically as paragraphs sorted alphabetically (frequently
+ these groups will be arranged by manufacturer, i.e. 3Com
+ Ethernet interfaces).
+
+ Where applicable, a "Miscellaneous" section may follow all
+ other named sections.
+
+ These guidelines are not hard-and-fast rules, and exceptions
+ will occur. Following these guidelines (vague as they may be)
+ is highly recommended to try to keep the formatting of
+ this section consistent.
+
+ We give manpage references using the &man entities where
+ possible. If a driver has no manpage (and consequently no
+ &man entity, we simply give the name of the driver).
+ Please avoid doing &man entity conversions unless you
+ know for sure that an entity and manpage exist; sweeps through
+ this file to fix "missed" conversions are likely to break the
+ build.
+ -->
+
+ <sect1 xml:id="support">
+ <title>Supported Devices</title>
+
+ <para>This section describes the devices currently known to be
+ supported by &os;. Other configurations may also work, but
+ simply have not been tested yet. Feedback, updates, and
+ corrections to this list are encouraged.</para>
+
+ <para>Where possible, the drivers applicable to each device or
+ class of devices is listed. If the driver in question has a
+ manual page in the &os; base distribution (most should), it is
+ referenced here. Information on specific models of supported
+ devices, controllers, etc. can be found in the manual
+ pages.</para>
+
+ <note>
+ <para>The device lists in this document are being generated
+ automatically from &os; manual pages. This means that some
+ devices, which are supported by multiple drivers, may appear
+ multiple times.</para>
+ </note>
+
+ <sect2 xml:id="disk">
+ <title>Disk Controllers</title>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;, &arch.sparc64;]
+ IDE/ATA controllers (&man.ata.4; driver)</para>
+
+ <para>[&arch.pc98;] IDE/ATA controllers (wdc driver)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>On-board IDE controller</para>
+ </listitem>
+ </itemizedlist>
+
+ &hwlist.aac;
+
+ &hwlist.adv;
+
+ &hwlist.adw;
+
+ &hwlist.aha;
+
+ &hwlist.ahb;
+
+ &hwlist.ahc;
+
+ &hwlist.ahci;
+
+ &hwlist.ahd;
+
+ &hwlist.aic;
+
+ &hwlist.amr;
+
+ &hwlist.arcmsr;
+
+ &hwlist.bt;
+
+ &hwlist.ciss;
+
+ &hwlist.ct;
+
+ &hwlist.dpt;
+
+ <note>
+ <para>[&arch.amd64;, &arch.i386;] Booting from these
+ controllers is supported. EISA adapters are not
+ supported.</para>
+ </note>
+
+ &hwlist.esp;
+
+ &hwlist.hpt27xx;
+
+ &hwlist.hptiop;
+
+ &hwlist.hptmv;
+
+ &hwlist.hptrr;
+
+ &hwlist.ida;
+
+ &hwlist.iir;
+
+ &hwlist.ips;
+
+ &hwlist.isci;
+
+ &hwlist.isp;
+
+ &hwlist.mfi;
+
+ &hwlist.mlx;
+
+ <note>
+ <para>[&arch.amd64;, &arch.i386;] Booting from these
+ controllers is supported. EISA adapters are not
+ supported.</para>
+ </note>
+
+ &hwlist.mly;
+
+ &hwlist.mpr;
+
+ &hwlist.mps;
+
+ &hwlist.mpt;
+
+ &hwlist.mrsas;
+
+ &hwlist.mvs;
+
+ &hwlist.ncr;
+
+ &hwlist.ncv;
+
+ &hwlist.nsp;
+
+ &hwlist.pms;
+
+ &hwlist.pst;
+
+ &hwlist.siis;
+
+ &hwlist.stg;
+
+ &hwlist.sym;
+
+ &hwlist.trm;
+
+ &hwlist.twa;
+
+ &hwlist.twe;
+
+ &hwlist.tws;
+
+ &hwlist.vpo;
+
+ <para>[&arch.i386;] The wds(4) driver supports the WD7000 SCSI
+ controller.</para>
+
+ <para>With all supported SCSI controllers, full support is
+ provided for SCSI-I, SCSI-II, and SCSI-III peripherals,
+ including hard disks, optical disks, tape drives (including
+ DAT, 8mm Exabyte, Mammoth, and DLT), medium changers,
+ processor target devices and CD-ROM drives. WORM devices that
+ support CD-ROM commands are supported for read-only access by
+ the CD-ROM drivers (such as &man.cd.4;). WORM/CD-R/CD-RW
+ writing support is provided by &man.cdrecord.1;, which is a
+ part of the <package>sysutils/cdrtools</package> port in the Ports
+ Collection.</para>
+
+ <para>The following CD-ROM type systems are supported at this
+ time:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SCSI interface (also includes ProAudio Spectrum and
+ SoundBlaster SCSI) (&man.cd.4;)</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.i386;] Sony proprietary interface (all models)
+ (&man.scd.4;)</para>
+ </listitem>
+
+ <listitem>
+ <para>ATAPI IDE interface (&man.acd.4;)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.i386;] The following device is unmaintained:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Mitsumi proprietary CD-ROM interface (all models)
+ (&man.mcd.4;)</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 xml:id="ethernet">
+ <title>Ethernet Interfaces</title>
+
+ &hwlist.ae;
+
+ &hwlist.age;
+
+ &hwlist.ale;
+
+ &hwlist.aue;
+
+ &hwlist.axe;
+
+ <para>ASIX Electronics AX88178A/AX88179 USB Gigabit Ethernet
+ adapters (&man.axge.4; driver)</para>
+
+ &hwlist.bce;
+
+ <para>[&arch.amd64;, &arch.i386;] Broadcom BCM4401 based Fast
+ Ethernet adapters (&man.bfe.4; driver)</para>
+
+ &hwlist.bge;
+
+ &hwlist.bxe;
+
+ &hwlist.cas;
+
+ &hwlist.cdce;
+
+ <para>[&arch.amd64;, &arch.i386;] Crystal Semiconductor
+ CS89x0-based NICs (&man.cs.4; driver)</para>
+
+ &hwlist.cue;
+
+ &hwlist.cxgb;
+
+ &hwlist.dc;
+
+ &hwlist.de;
+
+ &hwlist.ed;
+
+ &hwlist.em;
+
+ &hwlist.ep;
+
+ <para>Agere ET1310 Gigabit Ethernet adapters
+ (&man.et.4; driver)</para>
+
+ &hwlist.ex;
+
+ &hwlist.fe;
+
+ &hwlist.fxp;
+
+ &hwlist.gem;
+
+ &hwlist.hme;
+
+ &hwlist.ie;
+
+ &hwlist.igb;
+
+ &hwlist.ipheth;
+
+ &hwlist.ixgb;
+
+ &hwlist.ixgbe;
+
+ &hwlist.jme;
+
+ &hwlist.kue;
+
+ &hwlist.lge;
+
+ &hwlist.msk;
+
+ &hwlist.mxge;
+
+ &hwlist.my;
+
+ &hwlist.nfe;
+
+ &hwlist.nge;
+
+ &hwlist.nxge;
+
+ &hwlist.oce;
+
+ &hwlist.pcn;
+
+ &hwlist.qlxgb;
+
+ &hwlist.qlxgbe;
+
+ &hwlist.qlxge;
+
+ &hwlist.re;
+
+ &hwlist.rl;
+
+ &hwlist.rue;
+
+ &hwlist.sf;
+
+ &hwlist.sfxge;
+
+ &hwlist.sge;
+
+ &hwlist.sis;
+
+ &hwlist.sk;
+
+ &hwlist.smsc;
+
+ &hwlist.sn;
+
+ &hwlist.snc;
+
+ &hwlist.ste;
+
+ &hwlist.stge;
+
+ &hwlist.ti;
+
+ &hwlist.tl;
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] SMC 83c17x
+ (EPIC)-based Ethernet NICs (&man.tx.4; driver)</para>
+
+ &hwlist.txp;
+
+ &hwlist.udav;
+
+ &hwlist.urndis;
+
+ &hwlist.vge;
+
+ &hwlist.vr;
+
+ &hwlist.vte;
+
+ &hwlist.vx;
+
+ &hwlist.vxge;
+
+ &hwlist.wb;
+
+ &hwlist.xe;
+
+ &hwlist.xl;
+
+ </sect2>
+
+ <sect2 xml:id="fddi">
+ <title>FDDI Interfaces</title>
+
+ <para>[&arch.i386;, &arch.pc98;] DEC DEFPA PCI (&man.fpa.4;
+ driver)</para>
+
+ <para>[&arch.i386;] DEC DEFEA EISA (&man.fpa.4; driver)</para>
+ </sect2>
+
+ <sect2 xml:id="atm">
+ <title>ATM Interfaces</title>
+
+ <para>[&arch.i386;, &arch.pc98;] Midway-based ATM interfaces
+ (&man.en.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.pc98; &arch.sparc64;] FORE Systems,
+ Inc. PCA-200E ATM PCI Adapters (hfa and &man.fatm.4;
+ drivers)</para>
+
+ <para>[&arch.i386;, &arch.pc98;] IDT NICStAR 77201/211-based ATM
+ Adapters (&man.idt.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.pc98; &arch.sparc64;] FORE Systems,
+ Inc. HE155 and HE622 ATM interfaces (&man.hatm.4;
+ driver)</para>
+
+ <para>[&arch.i386;, &arch.pc98;] IDT77252-based ATM cards
+ (&man.patm.4; driver)</para>
+ </sect2>
+
+ <sect2 xml:id="wlan">
+ <title>Wireless Network Interfaces</title>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] Cisco/Aironet
+ 802.11b wireless adapters (&man.an.4; driver)</para>
+
+ &hwlist.ath;
+
+ &hwlist.bwi;
+
+ &hwlist.bwn;
+
+ <para>[&arch.i386;, &arch.amd64;] Intel PRO/Wireless 2100
+ MiniPCI network adapter (&man.ipw.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.amd64;] Intel PRO/Wireless
+ 2200BG/2915ABG MiniPCI and 2225BG PCI network adapters
+ (&man.iwi.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.amd64;] Intel Dual Band Wireless AC
+ 3160/7260/7265 IEEE 802.11ac network adapters (&man.iwm.4;
+ driver)</para>
+
+ <para>[&arch.i386;, &arch.amd64;] Intel Wireless WiFi Link
+ 4965AGN IEEE 802.11n PCI network adapters
+ (&man.iwn.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.amd64;] Marvell Libertas IEEE 802.11b/g
+ PCI network adapters (&man.malo.4; driver)</para>
+
+ <para>Marvell 88W8363 IEEE 802.11n wireless network
+ adapters (&man.mwl.4; driver)</para>
+
+ &hwlist.otus;
+
+ &hwlist.ral;
+
+ &hwlist.rsu;
+
+ <para>Realtek RTL8188CE based PCIe IEEE 802.11b/g/n wireless network
+ adapters (&man.rtwn.4; driver)</para>
+
+ &hwlist.rum;
+
+ &hwlist.run;
+
+ &hwlist.uath;
+
+ &hwlist.upgt;
+
+ &hwlist.ural;
+
+ &hwlist.urtw;
+
+ &hwlist.urtwn;
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] Lucent
+ Technologies WaveLAN/IEEE 802.11b wireless network adapters
+ and workalikes using the Lucent Hermes, Intersil PRISM-II,
+ Intersil PRISM-2.5, Intersil Prism-3, and Symbol Spectrum24
+ chipsets (&man.wi.4; driver)</para>
+
+ <para>[&arch.i386;] NCR / AT&amp;T / Lucent Technologies WaveLan
+ T1-speed ISA/radio LAN cards (&man.wl.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.amd64;] Intel PRO/Wireless 3945ABG
+ MiniPCI network adapters (&man.wpi.4; driver)</para>
+
+ &hwlist.zyd;
+ </sect2>
+
+ <sect2 xml:id="misc-network">
+ <title>Miscellaneous Networks</title>
+
+ &hwlist.ce;
+
+ &hwlist.cx;
+
+ &hwlist.cp;
+
+ &hwlist.ctau;
+
+ &hwlist.cm;
+ </sect2>
+
+ <sect2 xml:id="serial">
+ <title>Serial Interfaces</title>
+
+ <para>[&arch.amd64;, &arch.i386;] <quote>PC standard</quote>
+ 8250, 16450, and 16550-based serial ports (&man.sio.4;
+ driver)</para>
+
+ &hwlist.uart;
+
+ &hwlist.scc;
+
+ <para>[&arch.amd64;, &arch.i386;] AST 4 port serial card using
+ shared IRQ</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>ARNET 8 port serial card using shared IRQ</para>
+ </listitem>
+
+ <listitem>
+ <para>ARNET (now Digiboard) Sync 570/i high-speed
+ serial</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.i386;] Boca multi-port serial cards</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Boca BB1004 4-Port serial card (Modems
+ <emphasis>not</emphasis> supported)</para>
+ </listitem>
+
+ <listitem>
+ <para>Boca IOAT66 6-Port serial card (Modems
+ supported)</para>
+ </listitem>
+
+ <listitem>
+ <para>Boca BB1008 8-Port serial card (Modems
+ <emphasis>not</emphasis> supported)</para>
+ </listitem>
+
+ <listitem>
+ <para>Boca BB2016 16-Port serial card (Modems
+ supported)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.i386;] Comtrol Rocketport card (&man.rp.4;
+ driver)</para>
+
+ <para>[&arch.i386;] Cyclades Cyclom-Y serial board (&man.cy.4;
+ driver)</para>
+
+ <para>[&arch.i386;] STB 4 port card using shared IRQ</para>
+
+ <para>[&arch.i386;] DigiBoard intelligent serial cards (digi
+ driver)</para>
+
+ <para>[&arch.amd64;, &arch.i386;] PCI-Based multi-port serial
+ boards (&man.puc.4; driver)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Actiontech 56K PCI</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Avlab Technology, PCI IO 2S
+ and PCI IO 4S</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Comtrol RocketPort 550</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Decision Computers PCCOM
+ 4-port serial and dual port RS232/422/485</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Dolphin Peripherals
+ 4025/4035/4036</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] IC Book Labs Dreadnought
+ 16x Lite and Pro</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Lava Computers
+ 2SP-PCI/DSerial-PCI/Quattro-PCI/Octopus-550</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Middle Digital, Weasle
+ serial port</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Moxa Industio CP-114,
+ Smartio C104H-PCI and C168H/PCI</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] NEC PK-UG-X001 and
+ PK-UG-X008</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Netmos NM9835
+ PCI-2S-550</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Oxford Semiconductor
+ OX16PCI954 PCI UART</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Syba Tech SD-LAB
+ PCI-4S2P-550-ECP</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] SIIG Cyber I/O PCI
+ 16C550/16C650/16C850</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] SIIG Cyber 2P1S PCI
+ 16C550/16C650/16C850</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] SIIG Cyber 2S1P PCI
+ 16C550/16C650/16C850</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] SIIG Cyber 4S PCI
+ 16C550/16C650/16C850</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] SIIG Cyber Serial (Single
+ and Dual) PCI 16C550/16C650/16C850</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Syba Tech
+ Ltd. PCI-4S2P-550-ECP</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] Titan PCI-200H and
+ PCI-800H</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] US Robotics (3Com) 3CP5609
+ modem</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] VScom PCI-400 and
+ PCI-800</para>
+ </listitem>
+ </itemizedlist>
+
+ &hwlist.rc;
+
+ <para>[&arch.i386;, &arch.amd64;] Specialix SI/XIO/SX multiport
+ serial cards, with both the older SIHOST2.x and the
+ <quote>enhanced</quote> (transputer based, aka JET) host cards
+ (ISA, EISA and PCI) are supported. Note that the newer SX+
+ PCI cards are not currently supported. (&man.si.4;
+ driver)</para>
+
+ <para>[&arch.pc98;] Internel serial interfaces (&man.sio.4;
+ driver)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>PC-9801 on-board</para>
+ </listitem>
+ <listitem>
+ <para>PC-9821 2'nd CCU (flags 0x12000000)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.pc98;] NEC PC-9861K, PC-9801-101 and Midori-Denshi
+ MDC-926Rs (&man.sio.4; driver)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>COM2 (flags 0x01000000)</para>
+ </listitem>
+
+ <listitem>
+ <para>COM3 (flags 0x02000000)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.pc98;] NEC PC-9801-120 (&man.sio.4; driver)</para>
+
+ <note>
+ <para>"flags 0x11000000" is necessary in kernel
+ configuration.</para>
+ </note>
+
+ <para>[&arch.pc98;] Microcore MC-16550, MC-16550II, MC-RS98
+ (&man.sio.4; driver)</para>
+
+ <note>
+ <para>"flags 0x14000?01" is necessary in kernel
+ configuration.</para>
+ </note>
+
+ <para>[&arch.pc98;] Media Intelligent RSB-2000, RSB-3000 and
+ AIWA B98-02 (&man.sio.4; driver)</para>
+
+ <note>
+ <para>"flags 0x15000?01" is necessary in kernel
+ configuration.</para>
+ </note>
+
+ <para>[&arch.pc98;] Media Intelligent RSB-384 (&man.sio.4;
+ driver)</para>
+
+ <note>
+ <para>"flags 0x16000001" is necessary in kernel
+ configuration.</para>
+ </note>
+
+ <para>[&arch.pc98;] I-O DATA RSA-98III (&man.sio.4;
+ driver)</para>
+
+ <note>
+ <para>"flags 0x18000?01" is necessary in kernel
+ configuration.</para>
+ </note>
+
+ <para>[&arch.pc98;] Hayes ESP98 (&man.sio.4; driver)</para>
+
+ <note>
+ <para>"options COM_ESP" and "flags 0x19000000" are necessary
+ in kernel configuration.</para>
+ </note>
+
+ </sect2>
+
+ <sect2 xml:id="sound">
+ <title>Sound Devices</title>
+
+ &hwlist.snd.ad1816;
+
+ &hwlist.snd.als4000;
+
+ &hwlist.snd.atiixp;
+
+ &hwlist.snd.audiocs;
+
+ &hwlist.snd.cmi;
+
+ &hwlist.snd.cs4281;
+
+ &hwlist.snd.csa;
+
+ &hwlist.snd.ds1;
+
+ &hwlist.snd.emu10k1;
+
+ &hwlist.snd.emu10kx;
+
+ &hwlist.snd.envy24;
+
+ &hwlist.snd.envy24ht;
+
+ &hwlist.snd.es137x;
+
+ &hwlist.snd.ess;
+
+ &hwlist.snd.fm801;
+
+ &hwlist.snd.gusc;
+
+ &hwlist.snd.hda;
+
+ &hwlist.snd.hdspe;
+
+ &hwlist.snd.ich;
+
+ &hwlist.snd.maestro;
+
+ &hwlist.snd.maestro3;
+
+ &hwlist.snd.mss;
+
+ &hwlist.snd.neomagic;
+
+ &hwlist.snd.sbc;
+
+ &hwlist.snd.solo;
+
+ &hwlist.snd.spicds;
+
+ &hwlist.snd.t4dwave;
+
+ &hwlist.snd.via8233;
+
+ &hwlist.snd.via82c686;
+
+ &hwlist.snd.vibes;
+
+ <para>[&arch.pc98;] NEC PC-9801-73, 86 and compatibles (nss
+ driver)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>NEC A-MATE internal sound</para>
+ </listitem>
+
+ <listitem>
+ <para>Q-Vision WaveStar, WaveMaster</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.pc98;] NEC X-MATE, CanBe, ValueStar internal (mss
+ driver)</para>
+
+ <para>[&arch.pc98;] Creative Technologies SoundBlaster(98)
+ (&man.sb.4; driver)</para>
+
+ <para>[&arch.pc98;] I-O DATA CD-BOX (&man.sb.4; driver)</para>
+
+ <para>[&arch.pc98;] MPU-401 and compatible interfaces (mpu
+ driver)</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Q-Vision WaveStar</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 xml:id="camera">
+ <title>Camera and Video Capture Devices</title>
+
+ &hwlist.bktr;
+
+ <para>[&arch.i386;] Connectix QuickCam</para>
+ </sect2>
+
+ <sect2 xml:id="usb">
+ <title>USB Devices</title>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] A
+ range of USB peripherals are supported; devices known to work
+ are listed in this section. Owing to the generic nature of
+ most USB devices, with some exceptions any device of a given
+ class will be supported, even if not explicitly listed
+ here.</para>
+
+ <note>
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ USB Ethernet adapters can be found in the section listing
+ <link linkend="ethernet">Ethernet
+ interfaces</link>.</para>
+ </note>
+
+ <note>
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ USB Bluetooth adapters can be found in <link linkend="bluetooth">Bluetooth</link> section.</para>
+ </note>
+
+ &hwlist.ohci;
+
+ &hwlist.uhci;
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] USB
+ 2.0 controllers using the EHCI interface (&man.ehci.4;
+ driver)</para>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ Hubs</para>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ Keyboards (&man.ukbd.4; driver)</para>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ Miscellaneous</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Assist Computer Systems PC Camera C-M1</para>
+ </listitem>
+
+ <listitem>
+ <para>ActiveWire I/O Board</para>
+ </listitem>
+
+ <listitem>
+ <para>Creative Technology Video Blaster WebCam Plus</para>
+ </listitem>
+
+ <listitem>
+ <para>D-Link DSB-R100 USB Radio (&man.ufm.4; driver)</para>
+ </listitem>
+
+ <listitem>
+ <para>Mirunet AlphaCam Plus</para>
+ </listitem>
+ </itemizedlist>
+
+ &hwlist.urio;
+
+ &hwlist.umodem;
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] Mice
+ (&man.ums.4; driver)</para>
+
+ &hwlist.ulpt;
+
+ &hwlist.ubsa;
+
+ &hwlist.ubser;
+
+ &hwlist.uftdi;
+
+ &hwlist.uplcom;
+
+ &hwlist.umct;
+
+ &hwlist.umass;
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] Audio Devices
+ (&man.uaudio.4; driver)</para>
+
+ &hwlist.uvisor;
+ </sect2>
+
+ <sect2 xml:id="firewire">
+ <title>IEEE 1394 (Firewire) Devices</title>
+
+ &hwlist.fwohci;
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.sparc64;] Serial Bus
+ Protocol 2 (SBP-2) storage devices (&man.sbp.4; driver)</para>
+ </sect2>
+
+ <sect2 xml:id="bluetooth">
+ <title>Bluetooth Devices</title>
+
+ &hwlist.ng.bt3c;
+
+ &hwlist.ng.ubt;
+ </sect2>
+
+ <sect2 xml:id="crypto-accel">
+ <title>Cryptographic Accelerators</title>
+
+ &hwlist.hifn;
+
+ &hwlist.safe;
+
+ &hwlist.ubsec;
+ </sect2>
+
+ <sect2 xml:id="misc">
+ <title>Miscellaneous</title>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ FAX-Modem/PCCARD</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>MELCO IGM-PCM56K/IGM-PCM56KH</para>
+ </listitem>
+
+ <listitem>
+ <para>Nokia Card Phone 2.0 (gsm900/dcs1800 HSCSD
+ terminal)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] Floppy drives
+ (&man.fdc.4; driver)</para>
+
+ <para>[&arch.amd64;, &arch.i386;] VGA-compatible video cards
+ (&man.vga.4; driver)</para>
+
+ <note>
+ <para>Information regarding specific video cards and
+ compatibility with <application>Xorg</application> can be
+ found at <uri xlink:href="http://www.x.org/">http://www.x.org/</uri>.</para>
+ </note>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ Keyboards including:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>[&arch.i386;] AT-style keyboards (&man.atkbd.4;
+ driver)</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] PS/2 keyboards
+ (&man.atkbd.4; driver)</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.pc98;] Standard keyboards</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ USB keyboards (&man.ukbd.4; driver)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ Pointing devices including:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;] Bus mice and
+ compatible devices (&man.mse.4; driver)</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;] PS/2 mice and compatible
+ devices, including many laptop pointing devices
+ (&man.psm.4; driver)</para>
+ </listitem>
+
+ <listitem>
+ <para>Serial mice and compatible devices</para>
+ </listitem>
+
+ <listitem>
+ <para>[&arch.amd64;, &arch.i386;, &arch.pc98;]
+ USB mice (&man.ums.4; driver)</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>&man.moused.8; has more information on using pointing
+ devices with &os;. Information on using pointing devices
+ with <application>Xorg</application> can be found at <uri xlink:href="http://www.x.org/">http://www.x.org/</uri>.</para>
+ </note>
+
+ <para>[&arch.amd64;, &arch.i386;] <quote>PC standard</quote>
+ parallel ports (&man.ppc.4; driver)</para>
+
+ <para>[&arch.pc98;] <quote>PC-9821 standard</quote> parallel
+ ports (&man.ppc.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.amd64;] PC-compatible joysticks
+ (&man.joy.4; driver)</para>
+
+ <para>[&arch.pc98;] Joystick port of SoundBlaster(98)
+ (&man.joy.4; driver)</para>
+
+ <para>[&arch.i386;, &arch.pc98;] PHS Data Communication
+ Card/PCCARD</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>NTT DoCoMo P-in Comp@ct</para>
+ </listitem>
+
+ <listitem>
+ <para>Panasonic KX-PH405</para>
+ </listitem>
+
+ <listitem>
+ <para>SII MC-P200</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>[&arch.i386;] Xilinx XC6200-based reconfigurable hardware
+ cards compatible with the HOT1 from <link xlink:href="http://www.vcc.com/">Virtual Computers</link> (xrpu
+ driver).</para>
+
+ <para>[&arch.pc98;] Power Management Controller of NEC PC-98
+ Note (pmc driver)</para>
+ </sect2>
+ </sect1>
+</article>
diff --git a/release/doc/en_US.ISO8859-1/readme/Makefile b/release/doc/en_US.ISO8859-1/readme/Makefile
new file mode 100644
index 0000000..35219fc
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/readme/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+RELN_ROOT?= ${.CURDIR}/../..
+.ifdef NO_LANGCODE_IN_DESTDIR
+DESTDIR?= ${DOCDIR}/readme
+.else
+DESTDIR?= ${DOCDIR}/en_US.ISO8859-1/readme
+.endif
+
+DOC?= article
+FORMATS?= html
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+#
+# SRCS lists the individual SGML files that make up the document. Changes
+# to any of these files will force a rebuild
+#
+
+# SGML content
+SRCS+= article.xml
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/release/doc/en_US.ISO8859-1/readme/article.xml b/release/doc/en_US.ISO8859-1/readme/article.xml
new file mode 100644
index 0000000..ffebcc3
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/readme/article.xml
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "../../../share/xml/freebsd50.dtd" [
+<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN" "release.ent">
+ %release;
+]>
+<!--
+ Local Variables:
+ mode: sgml
+ sgml-indent-data: t
+ sgml-omittag: nil
+ sgml-always-quote-attributes: t
+ End:
+-->
+<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
+ <info><title>&os; &release.current; README</title>
+
+
+ <author><orgname>The &os; Project</orgname></author>
+
+ <pubdate>$FreeBSD$</pubdate>
+
+ <copyright>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <year>2009</year>
+ <year>2010</year>
+ <year>2011</year>
+ <year>2012</year>
+ <year>2013</year>
+ <year>2014</year>
+ <year>2015</year>
+ <holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
+ </copyright>
+
+ <legalnotice xml:id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.intel;
+ &tm-attrib.opengroup;
+ &tm-attrib.sparc;
+ &tm-attrib.general;
+ </legalnotice>
+
+ <abstract>
+ <para>This document gives a brief introduction to &os;
+ &release.current;. It includes some information on how to
+ obtain &os;, a listing of various ways to contact the &os;
+ Project, and pointers to some other sources of
+ information.</para>
+ </abstract>
+ </info>
+
+ <sect1 xml:id="intro">
+ <title>Introduction</title>
+
+ <para>This distribution is a &release.type; of &os; &release.current;, the
+ latest point along the &release.branch; branch.</para>
+
+ <sect2>
+ <title>About &os;</title>
+
+ <para>&os; is an operating system based on 4.4 BSD Lite for
+ AMD64 and Intel EM64T based PC hardware (&arch.amd64;),
+ Intel, AMD, Cyrix or NexGen <quote>x86</quote> based PC hardware (&arch.i386;),
+ NEC PC-9801/9821 series PCs and compatibles (&arch.pc98;),
+ and &ultrasparc; machines (&arch.sparc64;). Versions
+ for the &arm; (&arch.arm;), &mips; (&arch.mips;), and
+ &powerpc; (&arch.powerpc;) architectures are currently under
+ development as well. &os; works with a wide variety of
+ peripherals and configurations and can be used for everything
+ from software development to games to Internet Service
+ Provision.</para>
+
+ <para>This release of &os; contains everything you need to run
+ such a system, including full source code for the kernel and
+ all utilities in the base distribution. With the source
+ distribution installed, you can literally recompile the entire
+ system from scratch with one command, making it ideal for
+ students, researchers, or users who simply want to see how it
+ all works.</para>
+
+ <para>A large collection of third-party ported software (the
+ <quote>Ports Collection</quote>) is also provided to make it
+ easy to obtain and install all your favorite traditional &unix;
+ utilities for &os;. Each <quote>port</quote> consists of a
+ set of scripts to retrieve, configure, build, and install a
+ piece of software, with a single command. Over &os.numports;
+ ports, from editors to programming languages to graphical
+ applications, make &os; a powerful and comprehensive operating
+ environment that extends far beyond what's provided by many
+ commercial versions of &unix;. Most ports are also available as
+ pre-compiled <quote>packages</quote>, which can be quickly
+ installed from the installation program.</para>
+ </sect2>
+
+ <sect2>
+ <title>Target Audience</title>
+
+ <para releasetype="current">This &release.type; is aimed primarily at early adopters
+ and various other users who want to get involved with the
+ ongoing development of &os;. While the &os; development team
+ tries its best to ensure that each &release.type; works as
+ advertised, &release.branch; is very much a
+ work-in-progress.</para>
+
+ <para releasetype="current">The basic requirements for using this &release.type; are
+ technical proficiency with &os; and an understanding of the
+ ongoing development process of &os; &release.branch; (as
+ discussed on the &a.current;).</para>
+
+ <para releasetype="current">For those more interested in doing business with &os; than
+ in experimenting with new &os; technology, formal releases
+ (such as &release.prev.stable;) are frequently more appropriate.
+ Releases undergo a period of testing and quality assurance
+ checking to ensure high reliability and dependability.</para>
+
+ <para releasetype="snapshot">This &release.type; is aimed primarily at early adopters
+ and various other users who want to get involved with the
+ ongoing development of &os;. While the &os; development team
+ tries its best to ensure that each &release.type; works as
+ advertised, &release.branch; is very much a
+ work-in-progress.</para>
+
+ <para releasetype="snapshot">The basic requirements for using this &release.type; are
+ technical proficiency with &os; and an understanding of the
+ ongoing development process of &os; &release.branch; (as
+ discussed on the &a.current;).</para>
+
+ <para releasetype="snapshot">For those more interested in doing business with &os; than
+ in experimenting with new &os; technology, formal releases
+ (such as &release.prev.stable;) are frequently more appropriate.
+ Releases undergo a period of testing and quality assurance
+ checking to ensure high reliability and dependability.</para>
+
+ <para releasetype="release">This &release.type; of &os; is suitable for all users. It
+ has undergone a period of testing and quality assurance
+ checking to ensure the highest reliability and
+ dependability.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="obtain">
+ <title>Obtaining &os;</title>
+
+ <para>&os; may be obtained in a variety of ways. This section
+ focuses on those ways that are primarily useful for obtaining a
+ complete &os; distribution, rather than updating an existing
+ installation.</para>
+
+ <sect2>
+ <title>CDROM and DVD</title>
+
+ <para>&os; -RELEASE distributions may be ordered on CDROM or DVD
+ from several publishers. This is frequently the most
+ convenient way to obtain &os; for new installations, as it
+ provides a convenient way to quickly reinstall the system if
+ necessary. Some distributions include some of the optional,
+ precompiled <quote>packages</quote> from the &os; Ports
+ Collection, or other extra material.</para>
+
+ <para>A list of the CDROM and DVD publishers known to the
+ project are listed in the <link xlink:href="&url.books.handbook;/mirrors.html"><quote>Obtaining
+ &os;</quote></link> appendix to the Handbook.</para>
+ </sect2>
+
+ <sect2>
+ <title>FTP</title>
+
+ <para>You can use FTP to retrieve &os; and any or all of its
+ optional packages from <uri xlink:href="ftp://ftp.FreeBSD.org/">ftp://ftp.FreeBSD.org/</uri>, which is the official
+ &os; release site, or any of its
+ <quote>mirrors</quote>.</para>
+
+ <para>Lists of locations that mirror &os; can be found in the
+ <link xlink:href="&url.books.handbook;/mirrors-ftp.html">FTP
+ Sites</link> section of the Handbook.
+ Finding a close (in networking terms) mirror from which to
+ download the distribution is highly recommended.</para>
+
+ <para>Additional mirror sites are always welcome. Contact
+ <email>freebsd-admin@FreeBSD.org</email> for more details on
+ becoming an official mirror site. You can also find useful
+ information for mirror sites at the <link xlink:href="&url.articles.hubs;/">Mirroring
+ &os;</link> article.</para>
+
+ <para>Mirrors generally contain the ISO images generally used to
+ create a CDROM of a &os; release. They usually also contain
+ floppy disk images (for applicable platforms), as well as the
+ files necessary to do an installation over the network.
+ Finally mirrors sites usually contain a set of packages for
+ the most current release.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="contacting">
+ <title>Contacting the &os; Project</title>
+
+ <sect2>
+ <title>Email and Mailing Lists</title>
+
+ <para>For any questions or general technical support issues,
+ please send mail to the &a.questions;.</para>
+
+ <para>If you're tracking the &release.branch; development efforts, you
+ <emphasis>must</emphasis> join the &a.current;, in order to
+ keep abreast of recent developments and changes that may
+ affect the way you use and maintain the system.</para>
+
+ <para>Being a largely-volunteer effort, the &os;
+ Project is always happy to have extra hands willing to help&mdash;there are already far more desired enhancements than
+ there is time to implement them. To contact the developers on
+ technical matters, or with offers of help, please send mail to
+ the &a.hackers;.</para>
+
+ <para>Please note that these mailing lists can experience
+ <emphasis>significant</emphasis> amounts of traffic. If you
+ have slow or expensive mail access, or are only interested in
+ keeping up with major &os; events, you may find it
+ preferable to subscribe instead to the &a.announce;.</para>
+
+ <para>All of the mailing lists can be freely joined by anyone
+ wishing to do so. Visit the <link xlink:href="&url.base;/mailman/listinfo">
+ &os; Mailman Info Page</link>. This will give you more
+ information on joining the various lists, accessing archives,
+ etc. There are a number of mailing lists targeted at special
+ interest groups not mentioned here; more information can be
+ obtained either from the Mailman pages or the <link xlink:href="&url.base;/support.html#mailing-list">mailing
+ lists section</link> of the &os; Web site.</para>
+
+ <important>
+ <para>Do <emphasis>not</emphasis> send email to the lists
+ asking to be subscribed. Use the Mailman interface
+ instead.</para>
+ </important>
+ </sect2>
+
+ <sect2>
+ <title>Submitting Problem Reports</title>
+
+ <para>Suggestions, bug reports and contributions of code are
+ always valued&mdash;please do not hesitate to report any
+ problems you may find. Bug reports with attached fixes are of
+ course even more welcome.</para>
+
+ <para>The preferred method to submit bug reports from a machine
+ with Internet connectivity is to use the
+ <application>Bugzilla</application> bug tracker.
+ <quote>Problem Reports</quote> (PRs) submitted in this way
+ will be filed and their progress tracked; the &os; developers
+ will do their best to respond to all reported bugs as soon as
+ possible. <link
+ xlink:href="https://bugs.FreeBSD.org/search/">A list of all
+ active PRs</link> is available on the &os; Web site; this
+ list is useful to see what potential problems other users have
+ encountered.</para>
+
+ <para>Note that &man.send-pr.1; is deprecated.</para>
+
+ <para>For more information, <link
+ xlink:href="&url.articles.problem-reports;/"><quote>Writing
+ &os; Problem Reports</quote></link>, available on the &os;
+ Web site, has a number of helpful hints on writing and
+ submitting effective problem reports.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="seealso">
+ <title>Further Reading</title>
+
+ <para>There are many sources of information about &os;; some are
+ included with this distribution, while others are available
+ on-line or in print versions.</para>
+
+ <sect2 xml:id="release-docs">
+ <title>Release Documentation</title>
+
+ <para>A number of other files provide more specific information
+ about this &release.type; distribution. These files are
+ provided in various formats. Most distributions will include
+ both ASCII text (<filename>.TXT</filename>) and HTML
+ (<filename>.HTM</filename>) renditions. Some distributions
+ may also include other formats such as Portable Document Format
+ (<filename>.PDF</filename>).
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>README.TXT</filename>: This file, which
+ gives some general information about &os; as well as
+ some cursory notes about obtaining a
+ distribution.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>RELNOTES.TXT</filename>: The release
+ notes, showing what's new and different in &os;
+ &release.current; compared to the previous release (&os;
+ &release.prev;).</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>HARDWARE.TXT</filename>: The hardware
+ compatibility list, showing devices with which &os; has
+ been tested and is known to work.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>ERRATA.TXT</filename>: Release errata.
+ Late-breaking, post-release information can be found in
+ this file, which is principally applicable to releases
+ (as opposed to snapshots). It is important to consult
+ this file before installing a release of &os;, as it
+ contains the latest information on problems which have
+ been found and fixed since the release was
+ created.</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>On platforms that support &man.bsdinstall.8; (currently
+ &arch.amd64;, &arch.i386;, &arch.pc98;, and &arch.sparc64;), these documents are generally available via the
+ Documentation menu during installation. Once the system is
+ installed, you can revisit this menu by re-running the
+ &man.bsdinstall.8; utility.</para>
+
+ <note>
+ <para>It is extremely important to read the errata for any
+ given release before installing it, to learn about any
+ <quote>late-breaking news</quote> or post-release problems.
+ The errata file accompanying each release (most likely right
+ next to this file) is already out of date by definition, but
+ other copies are kept updated on the Internet and should be
+ consulted as the <quote>current errata</quote> for this
+ release. These other copies of the errata are located at
+ <uri xlink:href="&url.base;/releases/">&url.base;/releases/</uri> (as
+ well as any sites which keep up-to-date mirrors of this
+ location).</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Manual Pages</title>
+
+ <para>As with almost all &unix; like operating systems, &os; comes
+ with a set of on-line manual pages, accessed through the
+ &man.man.1; command or through the <link xlink:href="http://www.FreeBSD.org/cgi/man.cgi">hypertext manual
+ pages gateway</link> on the &os; Web site. In general, the
+ manual pages provide information on the different commands and
+ APIs available to the &os; user.</para>
+
+ <para>In some cases, manual pages are written to give
+ information on particular topics. Notable examples of such
+ manual pages are &man.tuning.7; (a guide to performance tuning),
+ &man.security.7; (an introduction to &os; security), and
+ &man.style.9; (a style guide to kernel coding).</para>
+ </sect2>
+
+ <sect2>
+ <title>Books and Articles</title>
+
+ <para>Two highly-useful collections of &os;-related information,
+ maintained by the &os; Project,
+ are the &os; Handbook and &os; FAQ (Frequently Asked
+ Questions document). On-line versions of the <link xlink:href="&url.books.handbook;/">Handbook</link>
+ and <link xlink:href="&url.books.faq;/">FAQ</link>
+ are always available from the <link xlink:href="&url.base;/docs.html">&os; Documentation
+ page</link> or its mirrors. If you install the
+ <filename>doc</filename> distribution set, you can use a Web
+ browser to read the Handbook and FAQ locally. In particular,
+ note that the Handbook contains a step-by-step guide to
+ installing &os;.</para>
+
+ <para>A number of on-line books and articles, also maintained by
+ the &os; Project, cover more-specialized, &os;-related topics.
+ This material spans a wide range of topics, from effective use
+ of the mailing lists, to dual-booting &os; with other
+ operating systems, to guidelines for new committers. Like the
+ Handbook and FAQ, these documents are available from the &os;
+ Documentation Page or in the <filename>doc</filename>
+ distribution set.</para>
+
+ <para>A listing of other books and documents about &os; can be
+ found in the <link xlink:href="&url.books.handbook;/bibliography.html">bibliography</link>
+ of the &os; Handbook. Because of &os;'s strong &unix; heritage,
+ many other articles and books written for &unix; systems are
+ applicable as well, some of which are also listed in the
+ bibliography.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="acknowledgements">
+ <title>Acknowledgments</title>
+
+ <para>&os; represents the cumulative work of many hundreds, if not
+ thousands, of individuals from around the world who have worked
+ countless hours to bring about this &release.type;. For a
+ complete list of &os; developers and contributors, please see
+ <link xlink:href="&url.articles.contributors;/"><quote>Contributors
+ to &os;</quote></link> on the &os; Web site or any of its
+ mirrors.</para>
+
+ <para>Special thanks also go to the many thousands of &os; users
+ and testers all over the world, without whom this &release.type;
+ simply would not have been possible.</para>
+ </sect1>
+</article>
diff --git a/release/doc/en_US.ISO8859-1/relnotes/Makefile b/release/doc/en_US.ISO8859-1/relnotes/Makefile
new file mode 100644
index 0000000..c0f473e
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/relnotes/Makefile
@@ -0,0 +1,24 @@
+# $FreeBSD$
+
+RELN_ROOT?= ${.CURDIR}/../..
+
+.ifdef NO_LANGCODE_IN_DESTDIR
+DESTDIR?= ${DOCDIR}/relnotes
+.else
+DESTDIR?= ${DOCDIR}/en_US.ISO8859-1/relnotes
+.endif
+
+DOC?= article
+FORMATS?= html
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+JADEFLAGS+= -V %generate-article-toc%
+
+# SGML content
+SRCS+= article.xml
+
+URL_RELPREFIX?= ../../../..
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.xml b/release/doc/en_US.ISO8859-1/relnotes/article.xml
new file mode 100644
index 0000000..f860409
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/relnotes/article.xml
@@ -0,0 +1,1805 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "../../../share/xml/freebsd50.dtd" [
+<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN" "release.ent">
+ %release;
+<!ENTITY % sponsor PUBLIC "-//FreeBSD//ENTITIES Sponsor Specification//EN" "sponsor.ent">
+ %sponsor;
+<!ENTITY % vendor PUBLIC "-//FreeBSD//ENTITIES Vendor Specification//EN" "vendor.ent">
+ %vendor;
+<!ENTITY security SYSTEM "../../share/xml/security.xml">
+<!ENTITY errata SYSTEM "../../share/xml/errata.xml">
+]>
+<article xmlns="http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
+
+ <info>
+ <title>&os; &release.current; Release Notes</title>
+
+ <author>
+ <orgname>The &os; Project</orgname>
+ </author>
+
+ <pubdate>$FreeBSD$</pubdate>
+
+ <!-- Last rev: 288943 -->
+
+ <copyright>
+ <year>2015</year>
+ <holder role="mailto:doc@FreeBSD.org">The &os; Documentation
+ Project</holder>
+ </copyright>
+
+ <legalnotice xml:id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.ibm;
+ &tm-attrib.ieee;
+ &tm-attrib.intel;
+ &tm-attrib.sparc;
+ &tm-attrib.general;
+ </legalnotice>
+
+ <abstract>
+ <para>The release notes for &os; &release.current; contain
+ a summary of the changes made to the &os; base system on the
+ &release.branch; development line. This document lists
+ applicable security advisories that were issued since the last
+ release, as well as significant changes to the &os; kernel and
+ userland. Some brief remarks on upgrading are also
+ presented.</para>
+ </abstract>
+ </info>
+
+ <sect1 xml:id="intro">
+ <title>Introduction</title>
+
+ <para>This document contains the release notes for &os;
+ &release.current;. It describes recently added, changed, or
+ deleted features of &os;. It also provides some notes on
+ upgrading from previous versions of &os;.</para>
+
+ <para releasetype="current">The &release.type; distribution to
+ which these release notes apply represents the latest point
+ along the &release.branch; development branch since
+ &release.branch; was created. Information regarding pre-built,
+ binary &release.type; distributions along this branch can be
+ found at <uri
+ xlink:href="&release.url;">&release.url;</uri>.</para>
+
+ <para releasetype="snapshot">The &release.type; distribution to
+ which these release notes apply represents a point along the
+ &release.branch; development branch between &release.prev; and
+ the future &release.next;. Information regarding pre-built,
+ binary &release.type; distributions along this branch can be
+ found at <uri
+ xlink:href="&release.url;">&release.url;</uri>.</para>
+
+ <para releasetype="release">This distribution of &os;
+ &release.current; is a &release.type; distribution. It can be
+ found at <uri xlink:href="&release.url;">&release.url;</uri> or
+ any of its mirrors. More information on obtaining this (or
+ other) &release.type; distributions of &os; can be found in the
+ <link
+ xlink:href="&url.books.handbook;/mirrors.html"><quote>Obtaining
+ &os;</quote> appendix</link> to the <link
+ xlink:href="&url.books.handbook;/">&os;
+ Handbook</link>.</para>
+
+ <para>All users are encouraged to consult the release errata
+ before installing &os;. The errata document is updated with
+ <quote>late-breaking</quote> information discovered late in the
+ release cycle or after the release. Typically, it contains
+ information on known bugs, security advisories, and corrections
+ to documentation. An up-to-date copy of the errata for &os;
+ &release.current; can be found on the &os; Web site.</para>
+
+ <para>This document describes the most user-visible new or changed
+ features in &os; since &release.prev;. In general, changes
+ described here are unique to the &release.branch; branch unless
+ specifically marked as &merged; features.</para>
+
+ <para>Typical release note items document recent security
+ advisories issued after &release.prev;, new drivers or hardware
+ support, new commands or options, major bug fixes, or
+ contributed software upgrades. They may also list changes to
+ major ports/packages or release engineering practices. Clearly
+ the release notes cannot list every single change made to &os;
+ between releases; this document focuses primarily on security
+ advisories, user-visible changes, and major architectural
+ improvements.</para>
+ </sect1>
+
+ <sect1 xml:id="upgrade">
+ <title>Upgrading from Previous Releases of &os;</title>
+
+ <para arch="amd64,i386">Binary upgrades between RELEASE versions
+ (and snapshots of the various security branches) are supported
+ using the &man.freebsd-update.8; utility. The binary upgrade
+ procedure will update unmodified userland utilities, as well as
+ unmodified GENERIC kernels distributed as a part of an official
+ &os; release. The &man.freebsd-update.8; utility requires that
+ the host being upgraded have Internet connectivity.</para>
+
+ <para>Source-based upgrades (those based on recompiling the &os;
+ base system from source code) from previous versions are
+ supported, according to the instructions in
+ <filename>/usr/src/UPDATING</filename>.</para>
+
+ <important>
+ <para>Upgrading &os; should only be attempted after backing up
+ <emphasis>all</emphasis> data and configuration files.</para>
+ </important>
+ </sect1>
+
+ <sect1 xml:id="security-errata">
+ <title>Security and Errata</title>
+
+ <para>This section lists the various Security Advisories and
+ Errata Notices since &release.prev;.</para>
+
+ <sect2 xml:id="security">
+ <title>Security Advisories</title>
+
+ &security;
+ </sect2>
+
+ <sect2 xml:id="errata">
+ <title>Errata Notices</title>
+
+ &errata;
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="userland">
+ <title>Userland</title>
+
+ <para>This section covers changes and additions to userland
+ applications, contributed software, and system utilities.</para>
+
+ <sect2 xml:id="userland-config">
+ <title>Userland Configuration Changes</title>
+
+ <para revision="266463">The default &man.newsyslog.conf.5; now
+ includes files in the
+ <filename>/etc/newsyslog.conf.d/</filename> and
+ <filename>/usr/local/etc/newsyslog.conf.d/</filename>
+ directories by default for &man.newsyslog.8;.</para>
+
+ <para revision="270675">The &man.mailwrapper.8; utility has been
+ updated to use &man.mailer.conf.5; from the
+ <literal>LOCALBASE</literal> environment variable, which
+ defaults to <filename class="directory">/usr/local</filename>
+ if unset.</para>
+
+ <para revision="272350">The <literal>MK_ARM_EABI</literal>
+ &man.src.conf.5; option has been removed.</para>
+
+ <para revision="285169">The <application>ntp</application> suite
+ has been updated to version 4.2.8p3.</para>
+ </sect2>
+
+ <sect2 xml:id="userland-programs">
+ <title>Userland Application Changes</title>
+
+ <para revision="258838" contrib="sponsor" sponsor="&ff;,
+ &google;" sponsorurl="">The &man.casperd.8; daemon has been
+ added, which provides access to functionality that is not
+ available in the <quote>capability mode</quote>
+ sandbox.</para>
+
+ <para revision="260594">When unable to load a kernel module with
+ &man.kldload.8;, a message informing to view output of
+ &man.dmesg.8; is now printed, opposed to the previous output
+ <quote>Exec format error.</quote>.</para>
+
+ <para revision="260910">Allow &man.pciconf.8; to identify PCI
+ devices that are attached to a driver to be identified by
+ their device name instead of just the selector. Additionally,
+ an optional device argument to the <literal>-l</literal> flag
+ to restrict the output to only listing details about a single
+ device.</para>
+
+ <para revision="260913">A new flag, <quote>onifconsole</quote>
+ has been added to <filename>/etc/ttys</filename>. This allows
+ the system to provide a login prompt via serial console if the
+ device is an active kernel console, otherwise it is equivalent
+ to <literal>off</literal>.</para>
+
+ <para revision="260926">Support for displaying VPD for PCI
+ devices via &man.pciconf.8; has been added.</para>
+
+ <para revision="261498">&man.ping.8; protects against malicious
+ network packets using the Capsicum framework to drop
+ privileges.</para>
+
+ <para revision="265229">The &man.ps.1; utility has been
+ updated to include the <literal>-J</literal> flag, used to
+ filter output by matching &man.jail.8; IDs and names.
+ Additionally, argument <literal>0</literal> can be used to
+ <literal>-J</literal> to only list processes running on the
+ host system.</para>
+
+ <para revision="265249">The &man.top.1; utility has been updated
+ to filter by &man.jail.8; ID or name, in followup to the
+ &man.ps.1; change in <literal>r265229</literal>.</para>
+
+ <para revision="266209">The &man.pmcstat.8; utility has been
+ updated to include a new flag, <literal>-l</literal>, which
+ ends event collection after the specified number of
+ seconds.</para>
+
+ <para revision="270745">The &man.ps.1; utility has been updated
+ to include a new keyword, <quote>tracer</quote>, which
+ displays the <acronym>PID</acronym> of the tracing
+ process.</para>
+
+ <para revision="271482">Support for adding empty partitions has
+ been added to the &man.mkimg.1; utility.</para>
+
+ <para revision="272166">The &man.primes.6; utility has been
+ updated to correctly enumerate prime numbers between
+ <literal>4295098369</literal> and
+ <literal>3825123056546413050</literal>, which prior to this
+ change, it would be possible for returned values to be
+ incorrectly identified as prime numbers.</para>
+
+ <para revision="272198">The &man.mkimg.1; utility has been
+ updated to include three options used to print information
+ about &man.mkimg.1; itself:</para>
+
+ <informaltable frame="none" pgwide="0">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Output</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>--version</literal></entry>
+ <entry>The current version of the &man.mkimg.1;
+ utility</entry>
+ </row>
+
+ <row>
+ <entry><literal>--formats</literal></entry>
+ <entry>The disk image file formats supported by
+ &man.mkimg.1;</entry>
+ </row>
+
+ <row>
+ <entry><literal>--schemes</literal></entry>
+ <entry>The partition schemes supported by
+ &man.mkimg.1;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para revision="272488">Userland &man.ctf.5; support in
+ &man.dtrace.1; has been added. With this change,
+ &man.dtrace.1; is able to resolve type info for function and
+ <acronym>USDT</acronym> probe arguments, and function return
+ values.</para>
+
+ <para revision="274960">The &man.elfdump.1; utility has been
+ updated to support capability mode provided by
+ &man.capsicum.4;.</para>
+
+ <para revision="275680" contrib="sponsor" sponsor="&ff;">The
+ &man.fstyp.8; utility has been added, which is used to
+ determine the filesystem on a specified device.</para>
+
+ <para revision="276881">The <literal>libedit</literal> library
+ has been updated to support <acronym>UTF</acronym>-8, which
+ additionally provides unicode support to &man.sh.1;.</para>
+
+ <para revision="276893" contrib="sponsor" sponsor="&ff;">The
+ &man.mkimg.1; utility has been updated to support the
+ <acronym>MBR</acronym> <acronym>EFI</acronym> partition
+ type.</para>
+
+ <para revision="277166" arch="powerpc">The &man.ptrace.2; system
+ call has been updated include support for Altivec registers on
+ &os;/&arch.powerpc;.</para>
+
+ <para revision="278320">A new device control utility,
+ &man.devctl.8; has been added, which allows making
+ administrative changes to individual devices, such as
+ attaching and detaching drivers, and enabling and disabling
+ devices. The &man.devctl.8; utility uses the new
+ &man.devctl.3; library.</para>
+
+ <para revision="279122" contrib="sponsor"
+ sponsor="&juniper;">The &man.netstat.1; utility has been
+ updated to link against the &man.libxo.3; shared
+ library.</para>
+
+ <para revision="279139">A new flag, <literal>-c</literal>, has
+ been added to the &man.mkimg.1; utility, which allows
+ specifying the capacity of the target disk image.</para>
+
+ <para revision="279315" contrib="sponsor" sponsor="&ff;">The
+ &man.uefisign.8; utility has been added.</para>
+
+ <para revision="279571" contrib="sponsor"
+ sponsor="&scaleengine;">The &man.freebsd-update.8; utility has
+ been updated to prevent fetching updated binary patches when
+ a previous upgrade has not been thoroughly completed.</para>
+
+ <para revision="280870">A regression in the &man.libarchive.3;
+ library that would prevent a directory from being included in
+ the archive when <literal>--one-file-system</literal> is used
+ has been fixed.</para>
+
+ <para revision="281311" contrib="sponsor" sponsor="&ff;">The
+ &man.ar.1; utility has been updated to set
+ <literal>ARCHIVE_EXTRACT_SECURE_SYMLINKS</literal> and
+ <literal>ARCHIVE_EXTRACT_SECURE_NODOTDOT</literal> to disallow
+ directory traversal when extracting an archive, similar to
+ &man.tar.1;.</para>
+
+ <para revision="281617">A race condition in &man.wc.1; that
+ would cause final results to be sent to &man.stderr.4; when
+ receiving the <literal>SIGINFO</literal> signal has been
+ fixed.</para>
+
+ <para revision="282208" contrib="sponsor"
+ sponsor="&multiplay;">The &man.chflags.1;, &man.chgrp.1;,
+ &man.chmod.1;, and &man.chown.8; utilities now affect symbolic
+ links when the <literal>-R</literal> flag is specified, as
+ documented in &man.symlink.7;.</para>
+
+ <para revision="282608">The &man.date.1; utility has been
+ updated to print the modification time of the file passed as
+ an argument to the <literal>-r</literal> flag, improving
+ compatibility with the <acronym>GNU</acronym> &man.date.1;
+ utility behavior.</para>
+
+ <para revision="283961">The &man.pw.8; utility has been updated
+ with a new flag, <literal>-R</literal>, that sets the root
+ directory within which the utility will operate.</para>
+
+ <para revision="284297" contrib="sponsor"
+ sponsor="&clusterhq;">The &man.lockstat.1; utility has been
+ updated with several improvements:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Spin locks are now reported as the amount of time
+ spinning, instead of loop iterations.</para>
+ </listitem>
+
+ <listitem>
+ <para>Reader locks are now recognized as adaptive that can
+ spin on &os;.</para>
+ </listitem>
+
+ <listitem>
+ <para>Lock aquisition events for successful reader try-lock
+ events are now reported.</para>
+ </listitem>
+
+ <listitem>
+ <para>Spin and block events are now reported before lock
+ acquisition events.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para revision="284589" contrib="sponsor"
+ sponsor="&scaleengine;">The &man.fstyp.8; utility has been
+ updated to be able to detect &man.zfs.8; and &man.geli.8;
+ filesystems.</para>
+
+ <para revision="284883">The &man.mkimg.1; utility has been
+ updated to include support for <literal>NTFS</literal>
+ filesystems in both <acronym>MBR</acronym> and
+ <acronym>GPT</acronym> partitioning schemes.</para>
+
+ <para revision="285253">The &man.quota.1; utility has been
+ updated to include support for <acronym>IPv6</acronym>.</para>
+
+ <para revision="285420">The &man.jexec.8; utility has been
+ updated to include a new flag, <literal>-l</literal>, which
+ ensures a clean environment in the target jail when used.
+ Additionally, &man.jexec.8; will run a shell within the target
+ jail when run no commands are specified.</para>
+
+ <para revision="285550">The &man.w.1; utility has been updated
+ to display the full IPv6 remote address of the host from which
+ a user is connected.</para>
+
+ <para revision="285685">The &man.jail.8; framework has been
+ updated to allow mounting &man.linprocfs.5; and
+ &man.linsysfs.5; within a jail.</para>
+
+ <para revision="285772" contrib="sponsor"
+ sponsor="&emcisilon;">The &man.patch.1; utility has been
+ updated to include a new option to the <literal>-V</literal>
+ flag, <literal>none</literal>, which disables backup file
+ creation when applying a patch.</para>
+
+ <para revision="286010" contrib="sponsor" sponsor="&ff;">The
+ &man.ar.1; utility now enables deterministic mode
+ (<literal>-D</literal>) by default. This behavior can be
+ disabled by specifying the <literal>-U</literal> flag.</para>
+
+ <para revision="286289" contrib="sponsor"
+ sponsor="&scaleengine;">The &man.xargs.1; utility has been
+ updated to allow specifying <literal>0</literal> as an
+ argument to the <literal>-P</literal> (parallel mode) flag,
+ which allows creating as many concurrent processes as
+ possible.</para>
+
+ <para revision="286795">The &man.patch.1; utility has been
+ updated to remove the automatic checkout feature.</para>
+
+ <para revision="287473" contrib="sponsor" sponsor="&gandi;">A
+ new utility, &man.sesutil.8;, has been added, which is used
+ to manage &man.ses.4; devices.</para>
+
+ <para revision="287522">The &man.pciconf.8; utility has been
+ updated to use the PCI ID database from the <filename
+ role="package">misc/pciids</filename> package, if present,
+ falling back to the PCI ID database in the &os; base
+ system.</para>
+
+ <para revision="287842" contrib="sponsor"
+ sponsor="&scaleengine;">The &man.ifconfig.8; utility has been
+ updated to always exit with an error code if an important
+ &man.ioctl.2; fails.</para>
+ </sect2>
+
+ <sect2 xml:id="userland-contrib">
+ <title>Contributed Software</title>
+
+ <para revision="260445">&man.byacc.1; has been updated to
+ version 20140101.</para>
+
+ <para revision="261320"><application>OpenSSH</application> has
+ been updated to 6.5p1.</para>
+
+ <para revision="261344"><application>mdocml</application> has
+ been updated to version 1.12.3.</para>
+
+ <para revision="275718">The <application>binutils</application>
+ suite of utilities has been updated to include upstream
+ patches that add new relocations for &arch.powerpc;
+ support.</para>
+
+ <para revision="276398" contrib="sponsor" sponsor="&ff;">The
+ <application>ELF Tool Chain</application> has been updated to
+ upstream revision r3136.</para>
+
+ <para revision="276551">The <application>texinfo</application>
+ utility and <literal>info</literal> pages were removed from
+ the base system. The <filename
+ role="package">print/texinfo</filename> port should be
+ installed on systems where <literal>info</literal> pages are
+ needed.</para>
+
+ <para revision="276796" contrib="sponsor" sponsor="&ff;">The ELF
+ object manipulation tools
+ <application>addr2line</application>,
+ <application>elfcopy (strip)</application>,
+ <application>nm</application>,
+ <application>readelf</application>,
+ <application>size</application>, and
+ <application>strings</application> were switched to the
+ versions from the ELF Tool Chain project.</para>
+
+ <para revision="276881">The <literal>libedit</literal> library
+ has been updated to include <acronym>UTF-8</acronym> support,
+ adding <acronym>UTF-8</acronym> support to the &man.sh.1;
+ shell.</para>
+
+ <para revision="278433">The &man.xz.1; utility has been updated
+ to support multi-threaded compression.</para>
+
+ <para revision="280932" contrib="sponsor" sponsor="&ff;">The
+ <application>elftoolchain</application> utilities have been
+ updated to version 3179.</para>
+
+ <para revision="281316">The &man.xz.1; utility has been updated
+ to version 5.2.1.</para>
+
+ <para revision="281373">The &man.nvi.1; utility has been updated
+ to version 2.1.3.</para>
+
+ <para revision="281806">The &man.wpa.supplicant.8; and
+ &man.hostapd.8; utilities have been updated to version
+ 2.4.</para>
+
+ <para revision="282434" contrib="sponsor" sponsor="&ff;">The
+ &man.resolvconf.8; utility has been updated to version
+ 3.7.0.</para>
+
+ <para revision="284254"><application>bmake</application> has
+ been updated to version 20150606.</para>
+
+ <para revision="285229"><application>sendmail</application> has
+ been updated to 8.15.2. Starting with &os;&nbsp;11.0 and
+ sendmail 8.15, sendmail uses uncompressed IPv6 addresses by
+ default, i.e., they will not contain <quote>::</quote>. For
+ example, instead of <quote>::1</quote>, it will be
+ <quote>0:0:0:0:0:0:0:1</quote>. This permits a zero subnet to
+ have a more specific match, such as different map entries for
+ IPv6:0:0 versus IPv6:0. This change requires that
+ configuration data (including maps, files, classes, custom
+ ruleset, etc.) must use the same format, so make certain such
+ configuration data is upgrading. As a very simple check
+ search for patterns like 'IPv6:[0-9a-fA-F:]*::' and 'IPv6::'.
+ To return to the old behavior, set the m4 option
+ <literal>confUSE_COMPRESSED_IPV6_ADDRESSES</literal> or the cf
+ option <literal>UseCompressedIPv6Addresses</literal>.</para>
+
+ <para revision="285275">The &man.tcpdump.1; utility has been
+ updated to version 4.7.4.</para>
+
+ <para revision="285329"><application>OpenSSL</application> has
+ been updated to version 1.0.1p.</para>
+
+ <para revision="285642" contrib="sponsor" sponsor="&dell;">The
+ &man.ssh.1; utility has been updated to re-implement hostname
+ canonicalization before locating the host in
+ <filename>known_hosts</filename>.</para>
+
+ <para revision="285972">The &man.libarchive.3; library has been
+ updated to properly skip a sparse file entry in a &man.tar.1;
+ file, which would previously produce errors.</para>
+
+ <para revision="286503">The <application>apr</application>
+ library used by &man.svnlite.1; has been updated to version
+ 1.5.2.</para>
+
+ <para revision="286505">The <application>serf</application>
+ library used by &man.svnlite.1; has been updated to version
+ 1.3.8.</para>
+
+ <para revision="286505">The &man.svnlite.1; utility has been
+ updated to version 1.8.14.</para>
+
+ <para revision="286510">The <application>sqlite3</application>
+ library used by &man.svnlite.1; and &man.kerberos.8; has been
+ updated to version 3.8.11.1.</para>
+
+ <para revision="286750">Timezone data files have been updated to
+ version 2015f.</para>
+
+ <para revision="287168">The &man.acpi.4; subsystem has been
+ updated to version 20150818.</para>
+
+ <para revision="287917">The &man.unbound.8; utility has been
+ updated to version 1.5.4.</para>
+
+ <para revision="288090">&man.jemalloc.3; has been updated to
+ version 4.0.2.</para>
+
+ <para revision="288143">The &man.file.1; utility has been
+ updated to version 5.25.</para>
+
+ <para revision="288303">The &man.nc.1; utility has been updated
+ to the OpenBSD 5.8 version.</para>
+
+ <para revision="288943"><application>Clang</application> has
+ been updated to version 3.7.0.</para>
+
+ <para revision="288943"><application>LLVM</application> has
+ been updated to version 3.7.0.</para>
+
+ <para revision="288943"><application>LLDB</application> has
+ been updated to version 3.7.0.</para>
+
+ <para revision="288943"><application>libc++</application> has
+ been updated to version 3.7.0.</para>
+
+ <para revision="288943">The
+ <application>compiler_rt</application> utility has been
+ updated to version 3.7.0.</para>
+ </sect2>
+
+ <sect2 xml:id="userland-installer">
+ <title>Installation and Configuration Tools</title>
+
+ <para revision="271539">The &man.bsdinstall.8; partition editor
+ and &man.sade.8; utility have been updated to include native
+ <acronym>ZFS</acronym> support.</para>
+
+ <para revision="272274">The &os; installation utility,
+ &man.bsdinstall.8;, has been updated to set the
+ <literal>canmount</literal> &man.zfs.8; property to
+ <literal>off</literal> for the <filename
+ class="directory">/var</filename> dataset, preventing the
+ contents of directories within <filename
+ class="directory">/var</filename> from conflicting when
+ using multiple boot environments, such as that provided by
+ <filename role="package">sysutils/beadm</filename>.</para>
+
+ <para revision="274394">The &man.bsdconfig.8; utility has been
+ updated to skip the initial &man.tzsetup.8;
+ <acronym>UTC</acronym> versus wall-clock time prompt when run
+ in a virtual machine, determined when the
+ <literal>kern.vm_guest</literal> &man.sysctl.8; is set to
+ <literal>1</literal>.</para>
+
+ <para revision="275874">The &man.bsdinstall.8; utility has been
+ updated to use the new &man.dpv.3; library to display progress
+ when extracting the &os; distributions.</para>
+
+ <para revision="285557" contrib="sponsor"
+ sponsor="&scaleengine;">Support for detecting and implementing
+ aligning partitions on 1Mb boundaries has been added to
+ &man.bsdinstall.8;.</para>
+
+ <para revision="285679" contrib="sponsor"
+ sponsor="&scaleengine;">Support for detecting and implementing
+ a workaround for various laptops and motherboards that do not
+ boot properly from <acronym>GPT</acronym>-partitioned disks
+ has been added to &man.bsdinstall.8;. Additionally, the
+ <literal>active</literal> flag will be set on the partition
+ when needed.</para>
+
+ <para revision="285679" contrib="sponsor"
+ sponsor="&scaleengine;">Support for selecting the partitioning
+ scheme when installing on the <acronym>UFS</acronym>
+ filesystem has been added to &man.bsdinstall.8;.</para>
+ </sect2>
+
+ <sect2 xml:id="userland-rc">
+ <title><filename class="directory">/etc/rc.d</filename>
+ Scripts</title>
+
+ <para revision="270676">The &man.rc.8; subsystem has been
+ updated to allow configuring services in <filename
+ class="directory">&dollar;{LOCALBASE}/etc/rc.conf.d/</filename>.
+ If <literal>LOCALBASE</literal> is unset, it defaults to
+ <filename class="directory">/usr/local</filename>.</para>
+
+ <para revision="273955">A new &man.rc.8; script,
+ <filename>growfs</filename>, has been added, which will resize
+ the root filesystem on boot if <filename>/firstboot</filename>
+ exists.</para>
+
+ <para revision="275299">The <filename>mrouted</filename>
+ &man.rc.8; script has been removed from the base system. An
+ equivalent script is available from the <filename
+ role="package">net/mrouted</filename> port.</para>
+
+ <para revision="279463" contrib="sponsor"
+ sponsor="&sandvine;">A new &man.rc.8; script,
+ <filename>iovctl</filename>, has been added, which allows
+ automatically starting the &man.iovctl.8; utility at
+ boot.</para>
+
+ <para revision="287576" contrib="sponsor"
+ sponsor="&scaleengine;">The &man.service.8; utility has been
+ updated to honor entries within <filename
+ class="directory">/etc/rc.conf.d/</filename>.</para>
+
+ </sect2>
+
+ <sect2 xml:id="userland-periodic">
+ <title><filename class="directory">/etc/periodic</filename>
+ Scripts</title>
+
+ <para revision="271321">The daily &man.periodic.8; script
+ <filename>110.clean-tmps</filename> has been updated to avoid
+ crossing filesystem mount boundaries when cleaning files in
+ <filename class="directory">/tmp</filename>.</para>
+
+ <para revision="277216" contrib="sponsor" sponsor="&ff;">A new
+ &man.periodic.8; script,
+ <filename>510.status-world-kernel</filename>, has been added,
+ which evaluates the running userland and kernel versions from
+ the &man.uname.1; <literal>-U</literal> and
+ <literal>-K</literal> arguments, and prints an error if the
+ system userland and kernel are not in sync.</para>
+ </sect2>
+
+ <sect2 xml:id="userland-libraries">
+ <title>Runtime Libraries and API</title>
+
+ <para revision="265995">The Blowfish &man.crypt.3; default
+ format has been changed to
+ <literal>&dollar;2b&dollar;</literal>.</para>
+
+ <para revision="268461">The &man.readline.3; library is now
+ statically linked in software within the base system, and the
+ shared library is no longer installed, allowing the Ports
+ Collection to use a modern version of the library.</para>
+
+ <para revision="272273">The &man.strptime.3; library has been
+ updated to add support for <acronym>POSIX</acronym>-2001
+ features <literal>%U</literal> and
+ <literal>%W</literal>.</para>
+
+ <para revision="272842,272848" contrib="sponsor"
+ sponsor="&ff;">The &man.dl.iterate.phdr.3; library has been
+ changed to always return the path name of the
+ <acronym>ELF</acronym> object in the
+ <literal>dlpi_name</literal> structure member.</para>
+
+ <para revision="273562" contrib="sponsor"
+ sponsor="&juniper;">The &man.libxo.3; library has been
+ imported to the base system.</para>
+
+ <para revision="273806" contrib="sponsor" sponsor="&chelsio;">A
+ userland library for Chelsio Terminator 5 based iWARP cards
+ has been added, allowing userland <acronym>RDMA</acronym>
+ applications to work over compatible
+ <acronym>NIC</acronym>s.</para>
+
+ <para revision="274987">The &man.gpio.3; library has been added,
+ providing a wrapper around the &man.gpio.4; kernel
+ interface.</para>
+
+ <para revision="275800" contrib="sponsor" sponsor="&ff;">The
+ &man.procctl.2; system call has been updated to include
+ a facility for non-&man.init.8; processes to be declared as
+ the reaper of child processes and their decendants.</para>
+
+ <para revision="277610">The <literal>futimens()</literal> and
+ <literal>utimensat()</literal> system calls have been
+ added. See &man.utimensat.2; for more information.</para>
+
+ <para revision="278934">The &man.elf.3; compile-time dependency
+ has been removed from <filename>dtri.o</filename>, which
+ allows adding <application>DTrace</application> probes to
+ userland applications and libraries without also linking
+ against &man.elf.3;.</para>
+
+ <para revision="279186">The &man.setmode.3; function has been
+ updated to consistently set <literal>errno</literal> on
+ failure.</para>
+
+ <para revision="279663">The &man.qsort.3; functions have been
+ updated to be able to handle 32-bit aligned data on 64-bit
+ platforms, also providing a significant improvement in 32-bit
+ workloads.</para>
+
+ <para revision="281130">Several standard include headers have
+ been updated to use of <application>gcc</application>
+ attributes, such as <literal>__result_use_check()</literal>,
+ <literal>__alloc_size()</literal>, and
+ <literal>__nonnull()</literal>.</para>
+
+ <para revision="281845">Support for file verification in
+ <acronym>MAC</acronym> has been added.</para>
+
+ <para revision="282973" contrib="sponsor" sponsor="&ff;">The
+ <literal>libgomp</literal> library is now only built when
+ building <acronym>GCC</acronym> from the base system. An
+ up-to-date version is available in the Ports Collection as
+ <filename
+ role="package">devel/libiomp5-devel</filename>.</para>
+
+ <para revision="282988">The <filename>stdlib.h</filename> and
+ <filename>malloc.h</filename> headers have been updated to
+ make use of the <application>gcc</application>
+ <literal>alloc_align()</literal> attribute.</para>
+
+ <para revision="284483" contrib="sponsor"
+ sponsor="&scaleengine;">The Blowfish &man.crypt.3; library
+ has been updated to support &dollar;2y&dollar; hashes.</para>
+
+ <para revision="285277">The &man.execl.3; and &man.execlp.3;
+ library functions have been updated to use the
+ <literal>__sentinel</literal> <application>gcc</application>
+ attribute.</para>
+ </sect2>
+
+ <sect2 xml:id="userland-abi">
+ <title>ABI Compatibility</title>
+
+ <para revision="271982">The &linux; compatibility version has
+ been updated to <literal>2.6.18</literal>. The
+ <literal>compat.linux.osrelease</literal> &man.sysctl.8; is
+ evaluated when building the <filename
+ role="package">emulators/linux-c6</filename> and related
+ ports.</para>
+
+ <para revision="288669">The stack protector has been upgraded to
+ the "strong" level, elevating the protection against buffer
+ overflows. While this significantly improves the security of
+ the system, extensive testing was done to ensure there are no
+ measurable side effects in performance or
+ functionality.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="kernel">
+ <title>Kernel</title>
+
+ <para>This section covers changes to kernel configurations, system
+ tuning, and system control parameters that are not otherwise
+ categorized.</para>
+
+ <sect2 xml:id="kernel-bugfix">
+ <title>Kernel Bug Fixes</title>
+
+ <para revision="265876">A kernel bug that inhibited proper
+ functionality of the <literal>dev.cpu.0.freq</literal>
+ &man.sysctl.8; on &intel; processors with Turbo
+ Boost&nbsp;&trade; enabled has been fixed.</para>
+
+ <para revision="271697" arch="powerpc">Support for
+ &man.dtrace.1; stack tracing has been fixed for
+ &os;/&arch.powerpc;, using the <literal>trapexit()</literal>
+ and <literal>asttrapexit()</literal> functions instead of
+ checking within addressed kernel space.</para>
+
+ <para revision="271917">A kernel panic triggered when destroying
+ a &man.vnet.9; &man.jail.8; configured with &man.gif.4; has
+ been fixed.</para>
+
+ <para revision="271918">A kernel panic triggered when destroying
+ a &man.vnet.9; &man.jail.8; configured with &man.gre.4; has
+ been fixed.</para>
+
+ <para revision="272089">A bug in &man.ipfw.4; that could
+ potentially lead to a kernel panic when using &man.dummynet.4;
+ at layer 2 has been fixed.</para>
+
+ <para revision="280930" contrib="sponsor" sponsor="&mitail;">The
+ kernel <acronym>RPC</acronym> has been updated to include
+ several enhancements:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The 45 MiB limit on requests queued for
+ &man.nfsd.8; threads has been removed.</para>
+ </listitem>
+
+ <listitem>
+ <para>Avoids unnecessary throttling by not deferring
+ accounting for completed requests.</para>
+ </listitem>
+
+ <listitem>
+ <para>Fixes an integer overflow and signedness bugs.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para revision="281261" arch="powerpc">Support for
+ &man.dtrace.1; has been added for the
+ Book-E&nbsp;&trade;.</para>
+
+ <para revision="287886" contrib="sponsor"
+ sponsor="&multiplay;">The &man.kqueue.2; system call has been
+ updated to handle write events to files larger than 2
+ gigabytes.</para>
+ </sect2>
+
+ <sect2 xml:id="kernel-config">
+ <title>Kernel Configuration</title>
+
+ <para revision="266531">The <literal>IMAGACT_BINMISC</literal>
+ kernel configuration option has been enabled by default,
+ which enables application execution through emulators, such
+ as <application>Qemu</application>.</para>
+
+ <para revision="268045">The <literal>VT</literal> kernel
+ configuration file has been removed, and the &man.vt.4;
+ driver is included in the <literal>GENERIC</literal> kernel.
+ To enable &man.vt.4;, enter <literal>set kern.vty=vt</literal>
+ at the &man.loader.8; prompt during boot, or add
+ <literal>kern.vty=vt</literal> to &man.loader.conf.5; and
+ reboot the system.</para>
+
+ <para revision="277904">The &man.config.8; utility has been
+ updated to allow using a non-standard <filename
+ class="directory">src/</filename> tree, specified as an
+ argument to the <literal>-s</literal> flag.</para>
+
+ <para revision="277990" arch="powerpc64">The
+ &os;/&arch.powerpc64; kernel now builds as
+ a position-independent executable, allowing the kernel to be
+ loaded into and run from any physical or virtual
+ address.</para>
+
+ <important>
+ <para>This change requires an update to &man.loader.8;.
+ The userland and kernel must be updated before rebooting the
+ system.</para>
+ </important>
+
+ <para revision="278338" arch="arm">A new module for creating
+ <filename>rpi.dtb</filename> has been added for the Raspberry
+ Pi.</para>
+
+ <para revision="278340" arch="arm">The
+ <filename>rpi.dtb</filename> module is now installed to
+ <filename class="directory">/boot/dtb/</filename> by
+ default for the Raspberry Pi system.</para>
+
+ <para revision="279189" contrib="sponsor" sponsor="&ff;"
+ arch="powerpc">Kernel support for Vector-Scalar eXtension
+ (<acronym>VSX</acronym>) found on POWER7 and POWER8 hardware
+ has been added.</para>
+
+ <para revision="279252" contrib="sponsor" sponsor="&ff;"
+ arch="powerpc">The &man.pmap.9; implementation for 64-bit
+ &powerpc; processors has been overhaulded to improve
+ concurrency.</para>
+
+ <para revision="279824" arch="arm">A new module for creating
+ the <filename>dtb</filename> module for AM335x systems has
+ been added.</para>
+
+ <para revision="281495" contrib="sponsor" sponsor="&ff;">The
+ <literal>PAE_TABLES</literal> kernel configuration option has
+ been added for &os;/&arch.i386;, which instructs &man.pmap.9;
+ to use <acronym>PAE</acronym> format for page tables while
+ maintaining a 32-bit physical address size elsewhere in the
+ kernel. The use of this option can enhance application-level
+ security by enabling the creation of <quote>no execute</quote>
+ mappings on modern &arch.i386; processors. Unlike the
+ <literal>PAE</literal> option, <literal>PAE_TABLES</literal>
+ preserves kernel binary interface (<acronym>KBI</acronym>)
+ compatibility with non-<literal>PAE</literal> kernels,
+ allowing non-<literal>PAE</literal> kernel modules and drivers
+ to work with a <literal>PAE_TABLES</literal>-enabled kernel.
+ Additionally, system limits are tuned for 4GB maximum
+ <acronym>RAM</acronym>, avoiding kernel virtual address space
+ (<acronym>KVA</acronym>) exhaustion.</para>
+
+ <para revision="282215">The <literal>SIFTR</literal> kernel
+ configuration has been added, allowing building &man.siftr.4;
+ statically into the kernel.</para>
+
+ <para revision="282731" arch="arm">The &arch.arm; boot loader,
+ <filename>ubldr</filename>, is now relocatable. In addition,
+ <filename>ubldr.bin</filename> is now created during build
+ time, which is a stripped binary with an entry point of
+ <literal>0</literal>, providing the ability to specify the
+ load address by running <literal>go
+ &dollar;{loadaddr}</literal> in
+ <literal>u-boot</literal>.</para>
+
+ <para revision="282921" contrib="sponsor" sponsor="&intelcorp;"
+ arch="amd64,i386">The &man.nvd.4; and &man.nvme.4; drivers are
+ now included in the <filename>GENERIC</filename> kernel
+ configuration by default.</para>
+
+ <para revision="283959" contrib="sponsor"
+ sponsor="&limelight;">A new kernel configuration option,
+ <literal>EM_MULTIQUEUE</literal>, has been added which enables
+ multi-queue support in the &man.em.4; driver.</para>
+
+ <note>
+ <para>Multi-queue support in the &man.em.4; driver is not
+ officially supported by &intel;.</para>
+ </note>
+
+ <para revision="285142" contrib="sponsor"
+ sponsor="&netgate;">The <filename>GENERIC</filename> kernel
+ configuration has been updated to include the
+ <literal>IPSEC</literal> option by default.</para>
+
+ <para revision="285387" contrib="sponsor"
+ sponsor="&norse;, &dell;">Initial <acronym>NUMA</acronym>
+ affinity and policy configuration has been added. See
+ &man.numactl.1;, and &man.numa.getaffinity.2;, for usage
+ details.</para>
+
+ <para revision="286231">The &man.pms.4; driver has been added
+ to the <filename>GENERIC</filename> kernel configuration for
+ supported architectures.</para>
+
+ <para revision="287306" arch="arm">The
+ <filename>CUBIEBOARD2</filename> kernel configuration has been
+ renamed to <filename>A20</filename>.</para>
+
+ <para revision="288176" contrib="sponsor" sponsor="&ff;">Kernel
+ debugging symbols are now installed to <filename
+ class="directory">/usr/lib/debug/boot/kernel/</filename>.
+ To retain the previous behavior, add
+ <literal>KERN_DEBUGDIR=""</literal> to
+ &man.src.conf.5;.</para>
+ </sect2>
+
+ <sect2 xml:id="kernel-sysctl">
+ <title>System Tuning and Controls</title>
+
+ <para revision="275140" contrib="sponsor" sponsor="&ff;">The
+ &man.hwpmc.4; default and maximum callchain depths have been
+ increased. The default has been increased from 16 to 32, and
+ the maximum increased from 32 to 128.</para>
+
+ <para revision="279361">The <literal>kern.osrelease</literal>
+ and <literal>kern.osreldate</literal> are now configurable
+ &man.jail.8; parameters.</para>
+
+ <para revision="280308,280949" contrib="sponsor"
+ sponsor="&ix;, &ff;">The &man.devfs.5; device filesystem has
+ been changed to update timestamps for read/write operations
+ using seconds precision. A new &man.sysctl.8;,
+ <literal>vfs.devfs.dotimes</literal> has been added, which
+ when set to a non-zero value, enables default precision
+ timestamps for these operations.</para>
+
+ <para revision="282213" contrib="sponsor" sponsor="&ff;">A new
+ &man.sysctl.8;, <literal>kern.racct.enable</literal>, has been
+ added, which when set to a non-zero value allows using
+ &man.rctl.8; with the <literal>GENERIC</literal> kernel.
+ A new kernel configuration option,
+ <literal>RACCT_DISABLED</literal> has also been added.</para>
+
+ <para revision="282901" contrib="sponsor" sponsor="&ff;">The
+ <literal>GENERIC</literal> kernel configuration now includes
+ <literal>RACCT</literal> and <literal>RCTL</literal> by
+ default.</para>
+
+ <note>
+ <para>To enable <literal>RACCT</literal> and
+ <literal>RCTL</literal> on a system using the
+ <literal>GENERIC</literal> kernel configuration, add
+ <literal>kern.racct.enable=1</literal> to
+ &man.loader.conf.5;, and reboot the system.</para>
+ </note>
+
+ <para revision="283136" contrib="sponsor"
+ sponsor="&limelight;">A new &man.sysctl.8;,
+ <literal>net.inet.tcp.hostcache.purgenow</literal>, has
+ been added, which when set to <literal>1</literal> during
+ runtime will flush all
+ <literal>net.inet.tcp.hostcache</literal> entries.</para>
+
+ <para revision="285524">A new &man.sysctl.8;,
+ <literal>hw.model</literal>, has been added, which displays
+ <acronym>CPU</acronym> model information.</para>
+
+ <para revision="286591">The &man.uart.4; driver has been
+ updated to allow tuning pulses per second captured in the
+ CTS line during runtime, whereas previously only the DCD line
+ could be used without rebuilding the kernel.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="drivers">
+ <title>Devices and Drivers</title>
+
+ <para>This section covers changes and additions to devices and
+ device drivers since &release.prev;.</para>
+
+ <sect2 xml:id="drivers-device">
+ <title>Device Drivers</title>
+
+ <para revision="260903">Support for GPS ports has been added to
+ &man.uhso.4;.</para>
+
+ <para revision="265132">The &man.full.4; device has been added,
+ and the <literal>lindev(4)</literal> device has been removed.
+ Prior to this change, <literal>lindev(4)</literal> provided
+ only the <filename>/dev/full</filename> character device,
+ returning <literal>ENOSPC</literal> on write attempts. As
+ this device is not specific to &linux;, a native &os; version
+ has been added.</para>
+
+ <para revision="271705">Hardware context support has been
+ added to the <literal>drm/i915</literal> driver, adding
+ support for <application>Mesa</application> 9.2 and
+ later.</para>
+
+ <para revision="273178">The &man.vt.4; driver has been updated,
+ replacing the bitmapped <literal>kern.vt.spclkeys</literal>
+ &man.sysctl.8; with individual
+ <literal>kern.vt.kbd_*</literal> variants.</para>
+
+ <para revision="273598">The &man.hpet.4; driver has been updated
+ to create a
+ <filename>/dev/hpet<replaceable>N</replaceable></filename>
+ device, providing access to <acronym>HPET</acronym> from
+ userspace.</para>
+
+ <para revision="280183">The <literal>drm</literal> code has
+ been updated to match &linux; version 3.8.13.</para>
+
+ <para revision="281440">The &man.psm.4; driver has been updated
+ to include improved support for newer Synaptics&nbsp;&reg;
+ touchpads and the ClickPad&nbsp;&reg; mouse on newer
+ Lenovo&nbsp;&trade; laptops.</para>
+
+ <para revision="282783" arch="powerpc">Support for the Freescale
+ <acronym>PCI</acronym> Root Complex device has been
+ added.</para>
+
+ <para revision="285876">The &man.cyapa.4; driver has been added,
+ supporting the Cypress APA I2C trackpad.</para>
+
+ <para revision="285883">The &man.isl.4; driver has been added,
+ supporting the Intersil I2C ISL29018 digital ambient light
+ sensor.</para>
+ </sect2>
+
+ <sect2 xml:id="drivers-storage">
+ <title>Storage Drivers</title>
+
+ <para revision="265236" contrib="sponsor"
+ sponsor="&lsi;, &spectralogic;" sponsorurl="">The &man.mpr.4;
+ device has been added, providing support for LSI Fusion-MPT
+ 3 12Gb SCSI/SATA controllers.</para>
+
+ <para revision="265555" contrib="sponsor"
+ sponsor="&lsi;">The &man.mrsas.4; driver has been added,
+ providing support for LSI MegaRAID SAS controllers. The
+ &man.mfi.4; driver will attach to the controller, by default.
+ To enable &man.mrsas.4; add
+ <literal>hw.mfi.mrsas_enable=1</literal> to
+ <filename>/boot/loader.conf</filename>, which turns off
+ &man.mfi.4; device probing.</para>
+
+ <note>
+ <para>At this time, the &man.mfiutil.8; utility and the &os;
+ version of <application>MegaCLI</application> and
+ <application>StorCli</application> do not work with
+ &man.mrsas.4;.</para>
+ </note>
+
+ <para revision="275461" contrib="sponsor" sponsor="&ix;">The
+ &man.ctl.4; subsystem has been updated, increasing the ports
+ limit from <literal>128</literal> to <literal>256</literal>,
+ and <acronym>LUN</acronym> limit from <literal>256</literal>
+ to <literal>1024</literal>.</para>
+
+ <para revision="276526">The <literal>asr(4)</literal> driver has
+ been removed, and is no longer supported.</para>
+
+ <para revision="281387">The &man.hptnr.4; driver has been
+ updated to version 1.1.1.</para>
+
+ <para revision="285662">The &man.pms.4; driver has been added,
+ providing support for the PMC Sierra line of
+ <acronym>SAS</acronym>/<acronym>SATA</acronym> host bus
+ adapters.</para>
+
+ <para revision="287117" contrib="sponsor"
+ sponsor="&emcisilon;">The &man.ioat.4; driver has been added,
+ providing support for the <acronym>PSE</acronym> (Platform
+ Storage Extension).</para>
+
+ <para revision="287621" contrib="sponsor" sponsor="&ix;">The
+ <acronym>CTL</acronym> High Availability implementation has
+ been rewritten.</para>
+
+ <para revision="288310">The &man.ctl.4; driver has been updated
+ to support CD-ROM and removable devices.</para>
+ </sect2>
+
+ <sect2 xml:id="drivers-network">
+ <title>Network Drivers</title>
+
+ <para revision="258830">Support for Broadcom chipsets BCM57764,
+ BCM57767, BCM57782, BCM57786 and BCM57787 has been added to
+ &man.bge.4;.</para>
+
+ <para revision="260448">Support for the &intel; Centrino&trade;
+ Wireless-N 135 chipset has been added.</para>
+
+ <para revision="260552">Firmware for &intel; Centrino&trade;
+ Wireless-N 105 devices has been added to the base
+ system.</para>
+
+ <para revision="261975">The deprecated nve(4) driver has been
+ removed. Users of NVIDIA nForce MCP network adapters are
+ advised to use the &man.nfe.4; driver instead, which has been
+ the default driver for this hardware since
+ &os;&nbsp;7.0.</para>
+
+ <para revision="264601" contrib="sponsor"
+ sponsor="&darpa_afrl;">The <literal>if_nf10bmac(4)</literal>
+ device has been added, providing support for NetFPGA-10G
+ Embedded CPU Ethernet Core.</para>
+
+ <note>
+ <para>The <literal>if_nf10bmac(4)</literal> driver operates on
+ the FPGA, and is not suited for the PCI host
+ interface.</para>
+ </note>
+
+ <para revision="265348" contrib="sponsor"
+ sponsor="&netgate;">The &man.ath.hal.4; driver has been
+ updated to support the Atheros AR1111 chipset.</para>
+
+ <para revision="266770">Support for the &intel; Centrino&trade;
+ Wireless-N 105 chipset has been added.</para>
+
+ <para revision="266757" contrib="sponsor"
+ sponsor="&chelsio;">Support for the &man.cxgbe.4; Terminator
+ 5 (T5) 10G/40G cards has been added to &man.netmap.4;.</para>
+
+ <para revision="272730">The &man.alc.4; driver has been updated
+ to support AR816x and AR817x ethernet controllers.</para>
+
+ <para revision="272906">The &man.pf.4; packet filter default
+ hash has been changed from <literal>Jenkins</literal> to
+ <literal>Murmur3</literal>, providing a 3-percent performance
+ increase in packets-per-second.</para>
+
+ <para revision="273331">The &man.vxlan.4; driver has been added,
+ which creates a virtual Layer 2 (Ethernet) network overlaid in
+ a Layer 3 (IP/UDP) network. The &man.vxlan.4; driver is
+ analogous to &man.vlan.4;, but is designed to be better suited
+ for large, multiple-tenant datacenter environments.</para>
+
+ <para revision="274246" contrib="sponsor" sponsor="&yandex;">The
+ &man.gre.4; driver has been significantly overhauled, and has
+ been split into two separate modules, &man.gre.4; and
+ &man.me.4;.</para>
+
+ <para revision="278551">The &man.ral.4; driver has been updated
+ to support the RT5390 and RT5392 chipsets.</para>
+
+ <para revision="283514" contrib="sponsor"
+ sponsor="&solarflare;">The &man.sfxge.4; driver has been
+ updated to support Solarflare Flareon Ultra 7000-series
+ chipsets.</para>
+
+ <para revision="283766" contrib="sponsor"
+ sponsor="&limelight;">The &man.em.4; driver has been updated
+ with improved transmission queue hang detection.</para>
+
+ <para revision="284125">The &man.cdce.4; driver has been updated
+ to include support for the RTL8153 chipset.</para>
+
+ <para revision="286441">The &man.iwm.4; driver has been imported
+ from OpenBSD, providing support for &intel; 3160/7260/7265
+ wireless chipsets.</para>
+
+ <para revision="286829" contrib="sponsor"
+ sponsor="&limelight;">The &man.em.4; driver has been updated
+ to allow disabling <acronym>CRC</acronym> stripping.</para>
+
+ <para revision="287222">The &man.pf.4; implementation has been
+ updated to remove support for the <literal>scrub fragment
+ crop|drop-ovl</literal> filtering rule. Systems with this
+ rule in &man.pf.conf.5; will implicitly be converted to the
+ <literal>scrub fragment reassemble</literal> filtering rule,
+ without necessary intervention.</para>
+
+ <para revision="288654">The &man.lagg.4; driver has been updated
+ to remove support for the <literal>fec</literal>
+ protocol.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="hardware">
+ <title>Hardware Support</title>
+
+ <para>This section covers general hardware support for physical
+ machines, hypervisors, and virtualization environments, as well
+ as hardware changes and updates that do not otherwise fit in
+ other sections of this document.</para>
+
+ <sect2 xml:id="hardware-support">
+ <title>Hardware Support</title>
+
+ <para revision="268303">The &man.asmc.4; driver has been
+ updated to support the &apple;&nbsp;MacMini 3,1.</para>
+
+ <para revision="268351">Support for &os;/ia64 has been dropped
+ as of &os;&nbsp;11.</para>
+
+ <para revision="274386">An issue that could cause a system to
+ hang when entering <acronym>ACPI</acronym>
+ <literal>S3</literal> state (suspend to
+ <acronym>RAM</acronym>) has been corrected in the &man.acpi.4;
+ and &man.pci.4; drivers.</para>
+
+ <para revision="274733" arch="powerpc">The power management unit
+ subsystem has been updated to support power button events on
+ certain &arch.powerpc; hardware, such as aluminum
+ PowerBook&nbsp;&reg;.</para>
+
+ <para revision="275171,275190" arch="powerpc">The &man.hwpmc.4;
+ driver has been updated to correct performance counter
+ sampling on G4 (MPC74xxx) and G5 class processors.</para>
+
+ <para revision="275732" contrib="sponsor"
+ sponsor="&ff;,&netgate;">The
+ <application>OpenCrypto</application> framework has been
+ updated to include <literal>AES-ICM</literal> and
+ <literal>AES-GCM</literal> modes, both of which have also been
+ added to the &man.aesni.4; driver.</para>
+
+ <para revision="281713" arch="powerpc">The &man.hwpmc.4;
+ driver has been updated to support the Freescale e500
+ core.</para>
+
+ <para revision="283766">The &man.ig4.4; driver has been added,
+ providing support for the fourth generation &intel;
+ <acronym>I2C</acronym> SMBus.</para>
+
+ <para>The &man.uart.4; driver has been updated to support
+ <acronym>AMT</acronym> devices on newer systems.</para>
+
+ <para revision="285316" contrib="sponsor" sponsor="&ff;"
+ arch="arm64">Initial <acronym>SMP</acronym> support has been
+ added to the &os;/&arch.arm64; port.</para>
+ </sect2>
+
+ <sect2 xml:id="hardware-virtualization">
+ <title>Virtualization Support</title>
+
+ <para revision="260410">Support for the <quote>Virtual Interrupt
+ Delivery</quote> feature of &intel;&nbsp;VT-x is enabled if
+ supported by the CPU. This feature can be disabled by running
+ <literal>sysctl hw.vmm.vmx.use_apic_vid=0</literal>.
+ Additionally, to persist this setting across reboots, add
+ <literal>hw.vmm.vmx.use_apic_vid=0</literal> to
+ <filename>/etc/sysctl.conf</filename>.</para>
+
+ <para revision="260532">Support for <quote>Posted Interrupt
+ Processing</quote> is enabled if supported by the CPU. This
+ feature can be disabled by running <literal>sysctl
+ hw.vmm.vmx.use_apic_pir=0</literal>. Additionally, to
+ persist this setting across reboots, add
+ <literal>hw.vmm.vmx.use_apic_pir=0</literal> to
+ <filename>/etc/sysctl.conf</filename>.</para>
+
+ <para revision="260582">Unmapped IO support has been added to
+ &man.virtio_blk.4;.</para>
+
+ <para revision="260583">Unmapped IO support has been added to
+ &man.virtio_scsi.4;.</para>
+
+ <para revision="260847">The &man.virtio_random.4; driver has
+ been added to harvest entropy from the host system.</para>
+
+ <para revision="261504">&os;/&arch.i386; guests can be run under
+ bhyve.</para>
+
+ <para revision="267536" contrib="sponsor"
+ sponsor="&citrix.rd;">Support for running a &os;/&arch.amd64;
+ <application>Xen</application> guest instance as
+ <acronym>PVH</acronym> guest has been added.
+ <acronym>PVH</acronym> mode, short for <quote>Para-Virtualized
+ Hardware</quote>, uses para-virtualized drivers for boot and
+ I/O, and uses hardware virtualization extensions for all other
+ tasks, without the need for emulation.</para>
+
+ <para revision="273375">The &man.bhyve.8; hypervisor has been
+ updated to support &amd; processors with
+ <acronym>SVM</acronym> and <acronym>AMD-V</acronym> hardware
+ extensions.</para>
+
+ <para revision="273515">The &man.virtio.console.4; driver has
+ been added, which provides an interface to VirtIO console
+ devices through a &man.tty.4; device.</para>
+
+ <para revision="279957">The &man.bhyve.8; hypervisor has been
+ updated to support <literal>DSM TRIM</literal> commands for
+ virtual <acronym>AHCI</acronym> disks.</para>
+
+ <para revision="281439" arch="arm">Support for the
+ <application>QEMU</application> <literal>virt</literal> system
+ has been added.</para>
+
+ <para revision="282212" contrib="sponsor" sponsor="&msostc;">The
+ Hyper-V&trade; drivers have been updated with several
+ enhancements:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The &man.hv.vmbus.4; driver now has multi-channel
+ support.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &man.hv.storvsc.4; driver now has scatter/gather
+ support, in addition to performance improvements.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &man.hv.kvp.4; driver has received several bug
+ fixes.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para revision="282274">Support for &man.xen.4; para-virtualized
+ <literal>domU</literal> kernels has been removed.</para>
+
+ <para revision="284746" contrib="sponsor" sponsor="&msostc;">The
+ &man.hv.netvsc.4; driver has been updated to support checksum
+ offloading and <acronym>TSO</acronym>.</para>
+
+ <para revision="286062">The &man.xen.4; driver has been updated
+ to include support for <literal>blkif</literal> indirect
+ segment I/O.</para>
+ </sect2>
+
+ <sect2 xml:id="hardware-arm">
+ <title>ARM Support</title>
+
+ <para revision="260921">The &man.nand.4; device is enabled for
+ ARM devices by default.</para>
+
+ <para revision="266943" arch="arm">Support for the Exynos 5420
+ Octa system has been added.</para>
+
+ <para revision="267390" arch="arm">The <acronym>SMP</acronym>
+ option has been enabled for all Exynos 5 systems supported by
+ &os;.</para>
+
+ <para revision="268838" arch="arm">Support for the Toradex
+ Apalis i.MX6 development board has been added.</para>
+
+ <para revision="273264" arch="armv6">An issue that could cause
+ instability when detecting <acronym>SD</acronym> cards on the
+ Raspberry Pi <acronym>SOC</acronym> has been fixed.</para>
+
+ <para revision="275963">The <literal>bcm2835_cpufreq</literal>
+ driver has been added, which supports <acronym>CPU</acronym>
+ frequency and voltage control on the Raspberry Pi
+ <acronym>SOC</acronym>.</para>
+
+ <para revision="277042" arch="arm">Support to turn off the
+ BeagleBone Black system with the &man.shutdown.8;
+ <literal>-p</literal> flag or by invoking &man.poweroff.8; has
+ been added.</para>
+
+ <para revision="277644" arch="arm">Audio transmission drivers
+ have been added for Digital Audio Multiplexer
+ (<acronym>AUDMUXM</acronym>), Smart Direct Memory Access
+ Controller (<acronym>SDMA</acronym>), and Syncronous Serial
+ Interface (<acronym>SSI</acronym>).</para>
+
+ <para revision="280259" contrib="sponsor" sponsor="&ff;">Initial
+ support for the ARM AArch64 architecture has been
+ added.</para>
+
+ <para revision="282779" arch="arm">Kernel support for Thumb-2
+ userland has been added.</para>
+
+ <para revision="282827">Support for the hardware power button
+ on the BeagleBone Black system has been added.</para>
+
+ <para revision="284273" contrib="sponsor"
+ sponsor="&ff;">Initial
+ <acronym>ACPI</acronym> support has been added for
+ &os;/&arch.arm64;.</para>
+
+ <para revision="287225">Support for 1-Wire devices has been
+ added, providing support for 1-Wire hardware through
+ &man.gpio.4;. See &man.ow.4;, &man.owc.4;, and
+ &man.ow.temp.4; for more information.</para>
+
+ <para revision="287371" arch="arm64" contrib="sponsor"
+ sponsor="&abt;">Support for the HiSilicon HI6220 SoC has been
+ added.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="storage">
+ <title>Storage</title>
+
+ <para>This section covers changes and additions to file systems
+ and other storage subsystems, both local and networked.</para>
+
+ <sect2 xml:id="storage-general">
+ <title>General Storage</title>
+
+ <para revision="278037" contrib="sponsor" sponsor="&ix;">The
+ &man.ctl.4; <acronym>LUN</acronym> mapping has been rewritten,
+ replacing <acronym>iSCSI</acronym>-specific mapping mechanisms
+ with a new mechanism that works for any port.</para>
+
+ <para revision="278354" contrib="sponsor" sponsor="&ix;">The
+ &man.ctld.8; utility has been updated to allow controlling
+ non-<acronym>iSCSI</acronym> &man.ctl.4; ports.</para>
+
+ <para revision="275681" contrib="sponsor" sponsor="&ff;">The
+ &man.autofs.5; subsystem has been updated to include a new
+ &man.auto.master.5; map, <literal>-media</literal>, which
+ allows automatically mounting removable media, such as
+ <acronym>CD</acronym> drives or <acronym>USB</acronym> flash
+ drives.</para>
+
+ <para revision="279955" contrib="sponsor" sponsor="&ff;">The
+ &man.autofs.5; subsystem has been updated to include a new
+ &man.auto.master.5; map, <literal>-noauto</literal>, which
+ handles &man.fstab.5; entries set to
+ <literal>noauto</literal>.</para>
+
+ <para revision="286444">The <acronym>GELI</acronym> class has
+ been updated to support the <literal>BIO_DELETE</literal>
+ &man.g.bio.9; <literal>bio_cmd</literal> field, providing
+ <acronym>TRIM</acronym>/<acronym>UNMAP</acronym> support on
+ <acronym>GELI</acronym>-backed <acronym>SSD</acronym> storage
+ providers.</para>
+ </sect2>
+
+ <sect2 xml:id="storage-net">
+ <title>Networked Storage</title>
+
+ <para revision="270096" contrib="sponsor" sponsor="&ff;">The new
+ filesystem automount facility, &man.autofs.5;, has been added.
+ The new &man.autofs.5; facility is similar to that found in
+ other &unix;-like operating systems, such as OS&nbsp;X&trade;
+ and Solaris&trade;. The &man.autofs.5; facility uses
+ a &sun;-compatible &man.auto.master.5; configuration file, and
+ is administered with the &man.automount.8; userland utility,
+ and the &man.automountd.8; and &man.autounmountd.8;
+ daemons.</para>
+
+ <para revision="273849" contrib="sponsor" sponsor="&ff;">Support
+ for the <literal>timeo</literal>, <literal>actimeo</literal>,
+ <literal>noac</literal>, and <literal>proto</literal> options
+ have been added to &man.mount.nfs.8;.</para>
+ </sect2>
+
+ <sect2 xml:id="storage-zfs">
+ <title>ZFS</title>
+
+ <para revision="275748">The <literal>arc_meta_limit</literal>
+ statistics are now visible through the
+ <literal>kstat</literal> &man.sysctl.8;. As a result of this
+ change, the <literal>vfs.zfs.arc_meta_used</literal>
+ &man.sysctl.8; has been removed, and replaced with the
+ <literal>kstat.zfs.misc.arcstats.arc_meta_used</literal>
+ &man.sysctl.8;.</para>
+
+ <para revision="287099" contrib="sponsor"
+ sponsor="&clusterhq;">The &man.zfs.8; <literal>l2arc</literal>
+ code has been updated to take <literal>ashift</literal> into
+ account when gathering buffers to be written to the
+ <literal>l2arc</literal> device.</para>
+ </sect2>
+
+ <sect2 xml:id="storage-geom">
+ <title>&man.geom.4;</title>
+
+ <para revision="267359">Support for the
+ <literal>disklabel64</literal> partitioning scheme has been
+ added to &man.gpart.8;.</para>
+
+ <para revision="282465">Support for the
+ <literal>apple-boot</literal>, <literal>apple-hfs</literal>,
+ and <literal>apple-ufs</literal> <acronym>MBR</acronym>
+ partitioning schemes have been added to &man.gpart.8;.</para>
+
+ <para revision="285594" contrib="sponsor"
+ sponsor="&scaleengine;">The &man.gpart.8; utility has been
+ updated to include a new attribute for <acronym>GPT</acronym>
+ partitions, <literal>lenovofix</literal>, which when set,
+ which works around <acronym>BIOS</acronym> compatibility
+ issues reported on several Lenovo&nbsp;&trade; laptops.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="boot">
+ <title>Boot Loader Changes</title>
+
+ <para>This section covers the boot loader, boot menu, and other
+ boot-related changes.</para>
+
+ <sect2 xml:id="boot-loader">
+ <title>Boot Loader Changes</title>
+
+ <para revision="258431" contrib="sponsor" sponsor="&ff;">The
+ memory test run at boot time on &os;/&arch.amd64; platforms
+ has been disabled by default.</para>
+
+ <para revision="262955">A new &man.ttys.5; class,
+ <literal>3wire</literal>, has been added. This is similar to
+ the existing terminal classes, but does not have a defined
+ baudrate.</para>
+
+ <para revision="274085">The &man.vt.4; driver has been made the
+ default system console driver. The &man.syscons.4; driver is
+ still available, and can be enabled by adding
+ <literal>kern.vty=sc</literal> in &man.loader.conf.5;.
+ Alternatively, &man.syscons.4; can be enabled at boot time by
+ entering <literal>set kern.vty=sc</literal> at the
+ &man.loader.8; prompt.</para>
+
+ <para revision="279950">Support for <literal>bzipfs</literal>
+ has been added to the <acronym>EFI</acronym> loader.</para>
+
+ <para revision="281616">The boot loader has been updated to
+ support entering the <acronym>GELI</acronym> passphrase before
+ loading the kernel. To enable this behavior, add
+ <literal>geom_eli_passphrase_prompt="YES"</literal> to
+ &man.loader.conf.5;.</para>
+
+ <para revision="284683" contrib="sponsor" sponsor="&ff;"
+ arch="arm">The &man.ttys.5; file for &os;/&arch.arm; has been
+ updated to enable <filename>ttyu1</filename>,
+ <filename>ttyu2</filename>, and <filename>ttyu3</filename> by
+ default, if the callin port is an active console port.</para>
+ </sect2>
+
+ <sect2 xml:id="boot-menu">
+ <title>Boot Menu Changes</title>
+
+ <para>&nbsp;</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network">
+ <title>Networking</title>
+
+ <para>This section describes changes that affect networking in
+ &os;.</para>
+
+ <sect2 xml:id="network-protocols">
+ <title>Network Protocols</title>
+
+ <para revision="263140">Support for the IPX network transport
+ protocol has been removed, and will not be supported in
+ &os;&nbsp;11 and later releases.</para>
+
+ <para revision="272720" contrib="sponsor"
+ sponsor="&limelight;">Support for <acronym>PLPMTUD</acronym>
+ blackhole detection (<acronym>RFC</acronym> 4821) has been
+ added to the &man.tcp.4; stack, disabled by default. New
+ control tunables have been added:</para>
+
+ <informaltable frame="none" pgwide="0">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Tunable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>net.inet.tcp.pmtud_blackhole_detection</literal></entry>
+ <entry>Enables or disables <acronym>PLPMTUD</acronym>
+ blackhole detection</entry>
+ </row>
+
+ <row>
+ <entry><literal>net.inet.tcp.pmtud_blackhole_mss</literal></entry>
+ <entry><acronym>MSS</acronym> to try for IPv4</entry>
+ </row>
+
+ <row>
+ <entry><literal>net.inet.tcp.v6pmtud_blackhole_mss</literal></entry>
+ <entry><acronym>MSS to try for IPv6</acronym></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>New monitoring &man.sysctl.8;s haven been added:</para>
+
+ <informaltable frame="none" pgwide="0">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Tunable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>net.inet.tcp.pmtud_blackhole_activated</literal></entry>
+ <entry>Number of times the code was activated to attempt
+ downshifting the <acronym>MSS</acronym></entry>
+ </row>
+
+ <row>
+ <entry><literal>net.inet.tcp.pmtud_blackhole_min_activated</literal></entry>
+ <entry>Number of times the blackhole
+ <acronym>MSS</acronym> was used in an attempt to
+ downshift</entry>
+ </row>
+
+ <row>
+ <entry><literal>net.inet.tcp.pmtud_blackhole_failed</literal></entry>
+ <entry>Number of times that the blackhole failed to
+ connect after downshifting the
+ <acronym>MSS</acronym></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para revision="280971" contrib="sponsor"
+ sponsor="&netflix;, &nginx;">Support for <acronym>IP</acronym>
+ identification for atomic datagrams (<acronym>RFC</acronym>
+ 6864) has been added. Support for this feature can be toggled
+ with the <literal>net.inet.ip.rfc6864</literal>
+ &man.sysctl.8;, which is enabled by default.</para>
+
+ <para revision="285336" contrib="sponsor"
+ sponsor="&netgate;">The <acronym>IPSEC</acronym> has been
+ updated to include support for <acronym>AES</acronym> modes on
+ both software-only and hardware-backed (&man.aesni.4;)
+ systems.</para>
+
+ <para revision="287798" contrib="sponsor" sponsor="&dell;">The
+ network stack has been updated to fix handling of
+ <acronym>IPv6</acronym> On-Link redirects.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="ports">
+ <title>Ports Collection and Package Infrastructure</title>
+
+ <para>This section covers changes to the &os;&nbsp;Ports
+ Collection, package infrastructure, and package maintenance and
+ installation tools.</para>
+
+ <sect2 xml:id="ports-infrastructure">
+ <title>Infrastructure Changes</title>
+
+ <para>&nbsp;</para>
+ </sect2>
+
+ <sect2 xml:id="ports-packages ">
+ <title>Packaging Changes</title>
+
+ <para>&nbsp;</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="doc">
+ <title>Documentation</title>
+
+ <para>This section covers changes to the &os;&nbsp;Documentation
+ Project sources and toolchain.</para>
+
+ <sect2 xml:id="doc-sources">
+ <title>Documentation Source Changes</title>
+
+ <para>&nbsp;</para>
+ </sect2>
+
+ <sect2 xml:id="doc-toolchain">
+ <title>Documentation Toolchain Changes</title>
+
+ <para>&nbsp;</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="releng">
+ <title>Release Engineering and Integration</title>
+
+ <para>This section convers changes that are specific to the
+ &os;&nbsp;Release Engineering processes.</para>
+
+ <sect2 xml:id="releng-changes">
+ <title>Integration Changes</title>
+
+ <para revision="277458" contrib="sponsor" sponsor="&ff;">The
+ Release Engineering build tools have been updated to include
+ support for producing virtual machine disk images for various
+ cloud hosting providers.</para>
+
+ <para revision="278926">The Release Engineering build tools have
+ been updated to use multi-threaded &man.xz.1;. By default,
+ the number of &man.xz.1; threads is set to the number of cores
+ available.</para>
+
+ <para revision="281802" contrib="sponsor" sponsor="&ff;">The
+ Release Engineering build tools have been updated to include
+ support for building &os;/&arch.arm64; virtual machine and
+ memory stick installation images.</para>
+
+ <para revision="282693" contrib="sponsor" sponsor="&ff;">The
+ Release Engineering build tools have been updated to support
+ building &os;/&arch.arm; images without external utilities for
+ supported boards where a corresponding
+ <literal>u-boot</literal> port exists in the Ports
+ Collection.</para>
+
+ <para revision="283307" contrib="sponsor" sponsor="&ff;">The
+ &os;/&arch.i386; memory stick installation images are now
+ created using the &man.mkimg.1; utility, matching the way
+ the &os;/&arch.amd64; images are created.</para>
+ </sect2>
+ </sect1>
+</article>
diff --git a/release/doc/en_US.ISO8859-1/share/xml/catalog.xml b/release/doc/en_US.ISO8859-1/share/xml/catalog.xml
new file mode 100644
index 0000000..1bc6541
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/share/xml/catalog.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN"
+ "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+
+<!-- $FreeBSD$ -->
+
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+ <rewriteSystem systemIdStartString="http://www.FreeBSD.org/release/XML/lang/"
+ rewritePrefix="../../"/>
+ <rewriteURI uriStartString="http://www.FreeBSD.org/release/XML/lang/"
+ rewritePrefix="../../"/>
+</catalog>
diff --git a/release/doc/en_US.ISO8859-1/share/xml/release.xsl b/release/doc/en_US.ISO8859-1/share/xml/release.xsl
new file mode 100644
index 0000000..a854cd9
--- /dev/null
+++ b/release/doc/en_US.ISO8859-1/share/xml/release.xsl
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!-- $FreeBSD$ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'
+ xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ xmlns:db="http://docbook.org/ns/docbook"
+ exclude-result-prefixes="db">
+
+ <xsl:param name="release.url"/>
+ <xsl:param name="release.branch"/>
+ <xsl:param name="release.maillist"/>
+
+ <xsl:template name="user.footer.content">
+ <p align="center"><small>This file, and other release-related documents,
+ can be downloaded from <a href="{$release.url}"><xsl:value-of select="$release.url"/></a>.</small></p>
+
+ <p align="center"><small>For questions about FreeBSD, read the
+ <a href="http://www.FreeBSD.org/docs.html">documentation</a> before
+ contacting &lt;<a href="mailto:questions@FreeBSD.org">questions@FreeBSD.org</a>&gt;.</small></p>
+
+ <p align="center"><small>All users of FreeBSD <xsl:value-of select="$release.branch"/> should
+ subscribe to the &lt;<a href="mailto:{$release.maillist}@FreeBSD.org"><xsl:value-of select="$release.maillist"/>@FreeBSD.org</a>&gt;
+ mailing list.</small></p>
+
+ <p align="center"><small>For questions about this documentation,
+ e-mail &lt;<a href="mailto:doc@FreeBSD.org">doc@FreeBSD.org</a>&gt;.</small></p>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/release/doc/share/examples/Makefile.relnotesng b/release/doc/share/examples/Makefile.relnotesng
new file mode 100644
index 0000000..9607e28
--- /dev/null
+++ b/release/doc/share/examples/Makefile.relnotesng
@@ -0,0 +1,61 @@
+# -*- makefile -*-
+#
+# $FreeBSD$
+#
+# Sample makefile for rendering and uploading RELNOTESng files outside
+# the build tree.
+#
+
+ARCHS= amd64 i386 pc98 powerpc sparc64
+MULTITEXTS=
+UNITEXTS= hardware readme relnotes errata
+
+IMAGEDIR= .imagedir
+RHOST= freefall.freebsd.org
+RDIR= public_html/relnotes/CURRENT
+DOCDIR= ./release/doc
+LANG= en_US.ISO8859-1
+
+DOC_PREFIX?= /usr/doc
+CSS_SHEET?= ${DOC_PREFIX}/share/misc/docbook.css
+FORMATS?= html txt pdf
+
+BUILD_OPTIONS+= URLS_ABSOLUTE=YES
+
+all:
+ (cd ${DOCDIR}; ${MAKE} DOC_PREFIX=${DOC_PREFIX} FORMATS="${FORMATS}" ${BUILD_OPTIONS} all)
+
+lint:
+ (cd ${DOCDIR}; ${MAKE} DOC_PREFIX=${DOC_PREFIX} lint)
+
+image: all
+ @echo "#"
+ @echo "# Creating local image"
+ @echo "#"
+ rm -rf ${IMAGEDIR}
+ mkdir ${IMAGEDIR}
+ cp -p ${CSS_SHEET} ${IMAGEDIR}/docbook.css
+ for i in ${ARCHS}; do \
+ for j in ${MULTITEXTS}; do \
+ for k in ${FORMATS}; do \
+ cp -p ${DOCDIR}/${LANG}/$${j}/$${i}/article.$${k} ${IMAGEDIR}/$${j}-$${i}.$${k} ; \
+ done; \
+ done; \
+ done
+ for j in ${UNITEXTS}; do \
+ for k in ${FORMATS}; do \
+ cp -p ${DOCDIR}/${LANG}/$${j}/article.$${k} ${IMAGEDIR}/$${j}.$${k} ; \
+ done; \
+ done
+
+push: image
+ @echo "#"
+ @echo "# Pushing to ${RHOST}"
+ @echo "#"
+# (cd ${IMAGEDIR}; tar -cf - .) | gzip -c -9 | (ssh ${RHOST} "( cd ${RDIR}; gunzip -c | tar -xf -)" )
+ (cd ${IMAGEDIR}; rsync -azuv * ${RHOST}:${RDIR})
+ rm -rf ${IMAGEDIR}
+
+clean:
+ (cd ${DOCDIR}; ${MAKE} DOC_PREFIX=${DOC_PREFIX} FORMATS="${FORMATS}" clean)
+ rm -rf ${IMAGEDIR}
diff --git a/release/doc/share/misc/dev.archlist.txt b/release/doc/share/misc/dev.archlist.txt
new file mode 100644
index 0000000..5f62f48
--- /dev/null
+++ b/release/doc/share/misc/dev.archlist.txt
@@ -0,0 +1,178 @@
+#
+# Copyright (c) 2004-2006 The FreeBSD Project
+# 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.
+#
+# 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.
+#
+# $FreeBSD$
+#
+
+#
+# This file is used by man2hwnotes.pl to set which drivers are usable
+# on which architectures.
+#
+# Format:
+#
+# Empty lines, and lines beginning with "#" are ignored.
+# <Driver name><tab><arch>[,<arch>...]
+#
+aac i386,amd64
+adv i386,pc98,amd64
+adw i386,pc98,amd64
+aha i386
+ahb i386
+ahd i386,sparc64,amd64
+aic i386,pc98,amd64
+amd i386,pc98,amd64
+arcmsr i386,amd64
+asr i386
+ath i386,pc98,amd64,sparc64
+aue i386,pc98,amd64,powerpc
+axe i386,pc98,amd64,powerpc
+bce i386,amd64
+bge i386,pc98,sparc64,amd64
+bktr i386,pc98
+bt i386,amd64
+bxe i386,amd64
+cdce i386,pc98,amd64,powerpc
+ciss i386,amd64
+ce i386,pc98
+cm i386
+cnw i386,pc98,amd64
+cp i386,pc98
+ct pc98
+ctau i386
+cue i386,pc98,amd64,powerpc
+cx i386
+cxgb i386,amd64
+de i386,pc98,amd64
+dpt i386,amd64
+ed i386,pc98
+ep i386,pc98,amd64
+esp sparc64
+ex i386,amd64
+fe i386,pc98,amd64
+fwohci i386,sparc64,amd64,powerpc
+hifn i386,pc98,amd64
+hpt27xx i386,amd64
+hptiop i386,amd64
+hptmv i386,amd64
+hptrr i386,amd64
+ida i386
+ie i386
+iir i386,amd64
+ips i386,amd64
+isci i386,amd64
+ixgb i386,amd64
+kue i386,pc98,amd64,powerpc
+lge i386,pc98,amd64
+mfi i386,amd64
+mlx i386,amd64
+mly i386,amd64
+msk i386,amd64
+mxge i386,amd64
+my i386,pc98
+ncr i386,pc98,amd64
+ncv i386,pc98
+nfe i386,amd64
+ng_bt3c i386,pc98,amd64
+ng_ubt i386,pc98,amd64
+nsp i386,pc98
+nxge i386,amd64
+oce i386,amd64
+ohci i386,pc98,amd64,powerpc
+oltr i386
+otus i386,amd64
+pcn i386,pc98,amd64
+pst i386
+qlxgb amd64
+qlxgbe amd64
+qlxge amd64
+rc i386
+ral i386,amd64
+rsu i386,amd64
+rue i386,pc98,amd64
+rum i386,amd64
+run i386,amd64
+safe i386,pc98,amd64
+sbp i386,sparc64,amd64
+sfgxe amd64
+sn i386,amd64
+snc pc98
+snd_ad1816 i386,amd64
+snd_als4000 i386
+snd_atiixp i386,amd64
+snd_audiocs sparc64
+snd_cmi i386,amd64
+snd_cs4281 i386,amd64
+snd_csa i386,amd64
+snd_ds1 i386,amd64
+snd_emu10k1 i386,amd64
+snd_emu10kx i386,amd64
+snd_envy24 i386,amd64
+snd_envy24ht i386,amd64
+snd_es137x i386,sparc64,amd64
+snd_ess i386,amd64
+snd_fm801 i386,amd64
+snd_gusc i386,amd64
+snd_hda i386,amd64
+snd_hdspe i386,amd64
+snd_ich i386,amd64
+snd_maestro i386,amd64
+snd_maestro3 i386,amd64
+snd_mss i386
+snd_neomagic i386,amd64
+snd_sbc i386,amd64
+snd_solo i386,amd64
+snd_spicds i386,amd64
+snd_t4dwave i386,amd64,sparc64
+snd_via8233 i386,amd64
+snd_via82c686 i386,amd64
+snd_vibes i386,amd64
+stg i386,pc98
+ti i386,pc98,amd64,sparc64
+tl i386,pc98,amd64
+trm i386,amd64
+twa i386,amd64
+twe i386,amd64
+tws i386,amd64
+ubsa i386,pc98,amd64
+ubsec i386,pc98,amd64
+ubser i386,pc98,amd64
+ucycom i386,pc98,amd64
+udav i386,pc98,amd64
+uftdi i386,pc98,amd64
+uhci i386,pc98,amd64,powerpc
+ulpt i386,pc98,amd64,powerpc
+umass i386,pc98,amd64,powerpc
+umodem i386,pc98,amd64
+uplcom i386,pc98,amd64
+ural i386,amd64
+urio i386,pc98,amd64,powerpc
+uvisor i386,pc98,amd64
+uvscom i386,pc98,amd64
+vpo i386
+vx i386,pc98,amd64
+vxge i386,amd64
+wb i386,pc98,amd64
+xe i386,amd64
+zyd i386,amd64
diff --git a/release/doc/share/misc/man2hwnotes.pl b/release/doc/share/misc/man2hwnotes.pl
new file mode 100644
index 0000000..a64aae8
--- /dev/null
+++ b/release/doc/share/misc/man2hwnotes.pl
@@ -0,0 +1,533 @@
+#!/usr/bin/perl -w
+# Emacs should use -*- cperl -*- mode
+#
+# Copyright (c) 2003-2006 Simon L. Nielsen <simon@FreeBSD.org>
+# 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.
+#
+# 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.
+#
+# $FreeBSD$
+#
+
+# Parse the list of supported hardware out of section 4 manual pages
+# and output it on stdout as SGML/DocBook entities.
+
+# The script will look for the following line in the manual page:
+# .Sh HARDWARE
+# and make an entity of the content until the line containing:
+# .Sh
+#
+# For Lists only the first line will be printed. If there are
+# arguments to the .It command, only the argument will be printed.
+
+# Usage:
+# man2hwnotes.pl [-cl] [-d 0-6] [-a <archlist file>] [-o <outputfile>]
+# <manualpage> [<manualpage> ...]
+
+use strict;
+use Getopt::Std;
+use Digest::MD5 qw(md5_hex);
+
+# Section from manual page to extract
+my $hwlist_sect = "HARDWARE";
+
+# Override default archtecture list for some devices:
+my $archlist_file = "dev.archlist.txt";
+my %archlist;
+
+# Globals
+my $compat_mode = 0; # Enable compat for old Hardware Notes style
+my $debuglevel = 0;
+my $only_list_out = 0; # Should only lists be generated in the output?
+my @out_lines; # Single lines
+my @out_dev; # Device entities
+
+# Getopt
+my %options = ();
+if (!getopts("a:cd:lo:",\%options)) {
+ die("$!: Invalid command line arguments in ", __LINE__, "\n");
+}
+
+if (defined($options{c})) {
+ $compat_mode = 1;
+}
+if (defined($options{d})) {
+ $debuglevel = $options{d};
+}
+if (defined($options{a})) {
+ $archlist_file = $options{a};
+}
+if (defined($options{l})) {
+ $only_list_out = 1;
+}
+
+my $outputfile = $options{o};
+
+if ($debuglevel > 0) {
+ # Don't do output buffering in debug mode.
+ $| = 1;
+}
+
+load_archlist($archlist_file);
+
+if (defined($outputfile)) {
+ open(OLDOUT, ">&STDOUT") || die("$!: Could not open STDOUT in ", __LINE__, ".\n");
+ open(STDOUT, ">$outputfile") || die("$!: Could not open $outputfile in ", __LINE__, ".\n");
+}
+
+print <<EOT;
+<!--
+ These are automatically generated device lists for FreeBSD hardware notes.
+-->
+EOT
+
+if ($only_list_out) {
+ # Print the default device preamble entities
+ print "<!ENTITY hwlist.preamble.pre 'The'>\n";
+ print "<!ENTITY hwlist.preamble.post 'driver supports:'>\n";
+}
+
+foreach my $page (@ARGV) {
+ if ($page !~ m/\.4$/) {
+ dlog(2, "Skipped $page (not *.4)");
+ next;
+ }
+ dlog(2, "Parsing $page");
+ parse($page);
+
+ if (@out_lines) {
+ print join("\n", @out_lines), "\n";
+ }
+ if (@out_dev) {
+ print join("\n", @out_dev), "\n";
+ }
+
+ @out_lines = ();
+ @out_dev = ();
+}
+
+if (defined($outputfile)) {
+ open(STDOUT, ">&OLDOUT") || die("$!: Could not open STDOUT in ", __LINE__, ".\n");
+ close(OLDOUT) || die("$!: Could not close OLDOUT in ", __LINE__, ".\n");
+}
+
+sub normalize (@) {
+ my @lines = @_;
+
+ foreach my $l (@lines) {
+ $l =~ s/\\&//g;
+ $l =~ s:([\x21-\x2f\x5b-\x60\x7b-\x7f]):sprintf("&\#\%d;", ord($1)):eg;
+ # Make sure ampersand is encoded as &amp; since jade seems to
+ # be confused when it is encoded as &#38; inside an entity.
+ $l =~ s/&#38;/&amp;/g;
+ }
+ return (wantarray) ? @lines : join "", @lines;
+}
+
+sub parse {
+ my ($manpage) = @_;
+
+ my $cur_mansection;
+ my $found_hwlist = 0;
+ my %mdocvars;
+ $mdocvars{isin_hwlist} = 0;
+ $mdocvars{isin_list} = 0;
+ $mdocvars{first_para} = 1;
+ $mdocvars{parabuf} = "";
+ $mdocvars{listtype} = "";
+ $mdocvars{it_nr} = 0;
+
+ open(MANPAGE, "$manpage") || die("$!: Could not open $manpage in ", __LINE__, ".\n");
+ while(<MANPAGE>) {
+ chomp;
+ my $line = $_;
+
+ dlog(5, "Read '$line'");
+
+ # Find commands
+ if (s/^\.(.*)$/$1/) {
+ my $cmd = $1;
+
+ # Detect, and ignore, comment lines
+ if (s/^\\"(.*)$/$1/) {
+ next;
+ }
+
+ $cmd =~ s/^([^ ]+).*$/$1/;
+
+ if (/^Nm "?(\w+)"?/ && !defined($mdocvars{Nm})) {
+ dlog(3, "Setting Nm to $1");
+ $mdocvars{Nm} = $1;
+ # "_" cannot be used for an entity name.
+ $mdocvars{EntNm} = $1;
+ $mdocvars{EntNm} =~ s,_,.,g;
+
+ } elsif (/^Nm$/) {
+ if (defined($mdocvars{Nm}) && $mdocvars{Nm} ne "") {
+ parabuf_addline(\%mdocvars, "&man.".$mdocvars{EntNm}.".$cur_mansection;");
+ } else {
+ dlog(2, "Warning: Bad Nm call in $manpage");
+ }
+
+ } elsif (/^Sh (.+)$/) {
+ dlog(4, "Setting section to $1");
+ my $cur_section = $1;
+
+ flush_out(\%mdocvars);
+
+ if ($cur_section =~ /^${hwlist_sect}$/) {
+ dlog(2, "Found the device section ${hwlist_sect}");
+ $mdocvars{isin_hwlist} = 1;
+ $found_hwlist = 1;
+ add_sgmltag(\%mdocvars, "<!ENTITY hwlist.".$mdocvars{cur_manname}." '");
+ if ($only_list_out) {
+ add_sgmltag("<para xmlns=\"http://docbook.org/ns/docbook\">&hwlist.preamble.pre; " .
+ "&man.".$mdocvars{EntNm}.".$cur_mansection; " .
+ "&hwlist.preamble.post;</para>");
+ }
+ } elsif ($mdocvars{isin_hwlist}) {
+ dlog(2, "Found a HWLIST STOP key!");
+ add_sgmltag(\%mdocvars, "'>");
+ $mdocvars{isin_hwlist} = 0;
+ }
+ if ($mdocvars{isin_list}) {
+ dlog(1, "Warning: Still in list, but just entered new " .
+ "section. This is probably due to missing .El; " .
+ "check manual page for errors.");
+ # If we try to recover from this we will probably
+ # just end with bad SGML output and it really
+ # should be fixed in the manual page so we don't
+ # even try to "fix" this.
+ }
+
+
+ } elsif (/^Dt ([^ ]+) ([^ ]+)/) {
+ dlog(4, "Setting mansection to $2");
+ $mdocvars{cur_manname} = lc($1);
+ $cur_mansection = $2;
+
+ # "_" cannot be used for an entity name.
+ $mdocvars{cur_manname} =~ s,_,.,g;
+
+ } elsif (/^It ?(.*)$/) {
+ my $txt = $1;
+
+ $mdocvars{it_nr}++;
+
+ # Flush last item
+ if ($mdocvars{parabuf} ne "") {
+ add_listitem(\%mdocvars);
+ }
+
+ # Remove quotes, if any.
+ $txt =~ s/"(.*)"/$1/;
+
+ if ($mdocvars{listtype} eq "column") {
+ # Ignore first item when it is likely to be a
+ # header.
+ if ($mdocvars{it_nr} == 1 && $txt =~ m/^(Em|Sy) /) {
+ dlog(2, "Skipping header line in column list");
+ next;
+ }
+ # Only extract the first column.
+ $txt =~ s/ Ta /\t/g;
+ $txt =~ s/([^\t]+)\t.*/$1/;
+ }
+
+ # Remove Li commands
+ $txt =~ s/^Li //g;
+
+ parabuf_addline(\%mdocvars, normalize($txt));
+ } elsif (/^Bl/) {
+ $mdocvars{isin_list} = 1;
+ flush_out(\%mdocvars);
+ add_sgmltag(\%mdocvars, "<itemizedlist xmlns=\"http://docbook.org/ns/docbook\">");
+
+ if (/-tag/) {
+ $mdocvars{listtype} = "tag";
+ # YACK! Hack for ata(4)
+ if ($mdocvars{Nm} eq "ata") {
+ $mdocvars{listtype} = "tagHACK";
+ }
+ } elsif (/-bullet/) {
+ $mdocvars{listtype} = "bullet";
+ } elsif (/-column/) {
+ $mdocvars{listtype} = "column";
+ } else {
+ $mdocvars{listtype} = "unknown";
+ }
+ dlog(2, "Listtype set to $mdocvars{listtype}");
+ } elsif (/^El/) {
+ if ($mdocvars{parabuf} ne "") {
+ add_listitem(\%mdocvars);
+ }
+
+ add_sgmltag(\%mdocvars, "</itemizedlist>");
+ $mdocvars{isin_list} = 0;
+ } elsif (/^Tn (.+)$/) {
+ # For now we print TradeName text as regular text.
+ my ($txt, $punct_str) = split_punct_chars($1);
+
+ parabuf_addline(\%mdocvars, normalize($txt . $punct_str));
+ } elsif (/^Xr ([^ ]+) (.+)$/) {
+ my ($xr_sect, $punct_str) = split_punct_chars($2);
+ my $txt;
+
+ # We need to check if the manual page exist to avoid
+ # breaking the doc build just because of a broken
+ # reference.
+ #$txt = "&man.$1.$xr_sect;$punct_str";
+ $txt = "$1($xr_sect)$punct_str";
+ parabuf_addline(\%mdocvars, normalize($txt));
+ } elsif (/^Dq (.+)$/) {
+ my ($txt, $punct_str) = split_punct_chars($1);
+
+ parabuf_addline(\%mdocvars,
+ normalize("<quote xmlns=\"http://docbook.org/ns/docbook\">$txt</quote>$punct_str"));
+ } elsif (/^Sx (.+)$/) {
+ if ($mdocvars{isin_hwlist}) {
+ dlog(1, "Warning: Reference to another section in the " .
+ "$hwlist_sect section in " . $mdocvars{Nm} .
+ "(${cur_mansection})");
+ }
+ parabuf_addline(\%mdocvars, normalize($1));
+ } elsif (/^Pa (.+)$/) {
+ my ($txt, $punct_str) = split_punct_chars($1);
+
+ $txt = make_ulink($txt) . $punct_str;
+ parabuf_addline(\%mdocvars, normalize($txt));
+ } elsif (/^Pp/) {
+ dlog(3, "Got Pp command - forcing new para");
+ flush_out(\%mdocvars);
+ } elsif (/^Fx (.+)/) {
+ dlog(3, "Got Fx command");
+ parabuf_addline(\%mdocvars, "FreeBSD $1");
+ } elsif (/^Fx/) {
+ dlog(3, "Got Fx command");
+ parabuf_addline(\%mdocvars, "FreeBSD");
+ } elsif (/^Em (.+)$/) {
+ my ($txt, $punct_str) = split_punct_chars($1);
+
+ parabuf_addline(\%mdocvars,
+ normalize("<emphasis xmlns=\"http://docbook.org/ns/docbook\">$txt</emphasis>$punct_str"));
+ } else {
+ # Ignore all other commands.
+ dlog(3, "Ignoring unknown command $cmd");
+ }
+ } else {
+ # This is then regular text
+ parabuf_addline(\%mdocvars, normalize($_));
+ }
+ }
+ close(MANPAGE) || die("$!: Could not close $manpage in ", __LINE__, ".\n");
+ if (! $found_hwlist) {
+ dlog(2, "Hardware list not found in $manpage");
+ }
+}
+
+sub dlog {
+ my ($level, $txt) = @_;
+
+ if ($level <= $debuglevel) {
+ print STDERR "$level: $txt\n";
+ }
+}
+
+# Output a SGML tag.
+sub add_sgmltag {
+ my ($mdocvars, $txt) = (@_);
+
+ # We only care about the HW list for now.
+ if (${$mdocvars}{isin_hwlist}) {
+ push(@out_dev, $txt);
+ }
+}
+
+# Add a text entity, and return the used entity name.
+sub add_txt_ent {
+ my ($itemtxt) = (@_);
+ my ($entity_name);
+
+ # Convert mdoc(7) minus
+ $itemtxt =~ s/\\-/-/g;
+
+ $itemtxt =~ s/'/&lsquo;/g;
+
+ $entity_name = "hwlist." . md5_hex($itemtxt);
+ dlog(4, "Adding '$itemtxt' as entity $entity_name");
+ push(@out_lines, "<!ENTITY $entity_name '$itemtxt'>");
+
+ return ($entity_name);
+}
+sub flush_out {
+ my ($mdocvars) = (@_);
+ my ($entity_name, $out);
+ my $para_arch = "";
+
+ if (!${$mdocvars}{isin_hwlist} || ${$mdocvars}{parabuf} eq "") {
+ return;
+ }
+
+ $entity_name = add_txt_ent(${$mdocvars}{parabuf});
+ ${$mdocvars}{parabuf} = "";
+ if(defined($archlist{${$mdocvars}{Nm}})) {
+ if ($compat_mode) {
+ $para_arch = ' arch="' . $archlist{${$mdocvars}{Nm}} . '"';
+ } else {
+ $para_arch = '[' . $archlist{${$mdocvars}{Nm}} . '] ';
+ }
+ }
+ if ($compat_mode) {
+ $out = "<para xmlns=\"http://docbook.org/ns/docbook\"".$para_arch.">&".$entity_name.";</para>";
+ } else {
+ if (${$mdocvars}{first_para}) {
+ $out = "<para xmlns=\"http://docbook.org/ns/docbook\">".$para_arch."&".$entity_name.";</para>";
+ } else {
+ $out = "<para xmlns=\"http://docbook.org/ns/docbook\">&".$entity_name.";</para>";
+ }
+ ${$mdocvars}{first_para} = 0;
+ }
+
+ dlog(4, "Flushing parabuf");
+ add_sgmltag($mdocvars, $out);
+}
+
+# Add a new list item from the "parabuf".
+sub add_listitem {
+ my ($mdocvars) = (@_);
+ my ($listitem, $entity_name);
+ my $para_arch = "";
+
+ $entity_name = add_txt_ent(${$mdocvars}{parabuf});
+ ${$mdocvars}{parabuf} = "";
+
+ if ($compat_mode) {
+ if(defined($archlist{${$mdocvars}{Nm}})) {
+ $para_arch = ' arch="' . $archlist{${$mdocvars}{Nm}} . '"';
+ }
+ }
+ $listitem = "<listitem><para".$para_arch.">&".$entity_name.";</para></listitem>";
+ dlog(4, "Adding '$listitem' to out_dev");
+ push(@out_dev, $listitem);
+
+}
+
+# Add a line to the "paragraph buffer"
+sub parabuf_addline {
+ my $mdocvars = shift;
+ my ($txt) = (@_);
+
+ dlog(5, "Now in parabuf_addline for '$txt'");
+
+ # We only care about the HW list for now.
+ if (!${$mdocvars}{isin_hwlist}) {
+ dlog(6, "Exiting parabuf_addline due to: !\${\$mdocvars}{isin_hwlist}");
+ return;
+ }
+ if ($txt eq "") {
+ dlog(6, "Exiting parabuf_addline due to: \$txt eq \"\"");
+ return;
+ }
+
+ if ($only_list_out && !${$mdocvars}{isin_list}) {
+ dlog(6, "Exiting parabuf_addline due to: ".
+ "\$only_list_out && !\${\$mdocvars}{isin_list}");
+ return;
+ }
+
+ # We only add the first line for "tag" lists
+ if (${$mdocvars}{parabuf} ne "" && ${$mdocvars}{isin_list} &&
+ ${$mdocvars}{listtype} eq "tag") {
+ dlog(6, "Exiting parabuf_addline due to: ".
+ "\${\$mdocvars}{parabuf} ne \"\" && \${\$mdocvars}{isin_list} && ".
+ "\${\$mdocvars}{listtype} eq \"tag\"");
+ return;
+ }
+
+ if (${$mdocvars}{parabuf} ne "") {
+ ${$mdocvars}{parabuf} .= " ";
+ }
+
+ dlog(4, "Adding '$txt' to parabuf");
+
+ ${$mdocvars}{parabuf} .= $txt;
+}
+
+sub load_archlist {
+ my ($file) = (@_);
+
+ my $lineno = 0;
+
+ dlog(2, "Parsing archlist $file");
+
+ open(FILE, "$file") || die("$!: Could not open archlist $file in ", __LINE__, ".\n");
+ while(<FILE>) {
+ chomp;
+ $lineno++;
+
+ if (/^#/ || $_ eq "") {
+ next;
+ }
+
+ if (/(\w+)\t([\w,]+)/) {
+ dlog(4, "For driver $1 setting arch to $2");
+ $archlist{$1} = $2;
+ } else {
+ dlog(1, "Warning: Could not parse archlist line $lineno");
+ }
+ }
+
+ close(FILE);
+}
+
+# Check if a character is a mdoc(7) punctuation character.
+sub is_punct_char {
+ my ($str) = (@_);
+
+ return (length($str) == 1 && $str =~ /[\.,:;()\[\]\?!]/);
+}
+
+# Split out the punctuation characters of a mdoc(7) line.
+sub split_punct_chars {
+ my ($str) = (@_);
+ my (@stritems, $stritem, $punct_str);
+
+ $punct_str = "";
+ @stritems = split(/ /, $str);
+
+ while (defined($stritem = $stritems[$#stritems]) &&
+ is_punct_char($stritem)) {
+ $punct_str = $stritem . $punct_str;
+ pop(@stritems);
+ }
+
+ return (join(' ', @stritems), $punct_str);
+}
+
+# Create a ulink, if the string contains an URL.
+sub make_ulink {
+ my ($str) = (@_);
+
+ $str =~ s,(http://[^ ]+),<link xmlns=\"http://docbook.org/ns/docbook\" xlink:href="$1"></link>,;
+
+ return $str;
+}
diff --git a/release/doc/share/mk/doc.relnotes.mk b/release/doc/share/mk/doc.relnotes.mk
new file mode 100644
index 0000000..ae8a31f
--- /dev/null
+++ b/release/doc/share/mk/doc.relnotes.mk
@@ -0,0 +1,54 @@
+# $FreeBSD$
+
+DOC_PREFIX?= ${RELN_ROOT}/../../../doc
+
+# XXX
+RELEASETYPE!= grep -o 'release.type "[a-z]*"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[a-z.]* "\([a-z]*\)"|\1|'
+RELEASEURL!= grep -o 'release.url \"[^\"]*\"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[^ ]* "\([^"]*\)"|\1|'
+RELEASEBRANCH!= grep -o 'release.branch "\([^"]*\)"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[^ ]* "\([^"]*\)"|\1|'
+RELEASEMAILLIST!= grep -o 'release.maillist "\([^"]*\)"' ${RELN_ROOT}/share/xml/release.ent | sed 's|[^ ]* "\([^"]*\)"|\1|'
+.if ${RELEASETYPE} == "current"
+PROFILING+= --param profile.attribute "'releasetype'" --param profile.value "'current'"
+.elif ${RELEASETYPE} == "snapshot"
+PROFILING+= --param profile.attribute "'releasetype'" --param profile.value "'snapshot'"
+.elif ${RELEASETYPE} == "release"
+PROFILING+= --param profile.attribute "'releasetype'" --param profile.value "'release'"
+.endif
+XSLTPROCFLAGS+= --param release.url "'${RELEASEURL}'"
+XSLTPROCFLAGS+= --param release.branch "'${RELEASEBRANCH}'"
+XSLTPROCFLAGS+= --param release.maillist "'${RELEASEMAILLIST}'"
+XSLTPROCFLAGS+= --param toc.section.depth "'3'"
+
+# Find the RELNOTESng document catalogs
+EXTRA_CATALOGS+= file://${RELN_ROOT}/${LANGCODE}/share/xml/catalog.xml \
+ file://${RELN_ROOT}/share/xml/catalog.xml
+
+XSLXHTML= http://www.FreeBSD.org/release/XML/share/xml/release.xsl
+
+#
+# Automatic device list generation:
+#
+.if exists(${RELN_ROOT}/../man4)
+MAN4DIR?= ${RELN_ROOT}/../man4
+.elif exists(${RELN_ROOT}/../../man4)
+MAN4DIR?= ${RELN_ROOT}/../../man4
+.else
+MAN4DIR?= ${RELN_ROOT}/../../share/man/man4
+.endif
+MAN4PAGES?= ${MAN4DIR}/*.4 ${MAN4DIR}/man4.*/*.4
+ARCHLIST?= ${RELN_ROOT}/share/misc/dev.archlist.txt
+DEV-AUTODIR= ${RELN_ROOT:S/${.CURDIR}/${.OBJDIR}/}/share/xml
+CLEANFILES+= ${DEV-AUTODIR}/dev-auto.ent
+
+MAN2HWNOTES_CMD=${RELN_ROOT}/share/misc/man2hwnotes.pl
+.if defined(HWNOTES_MI)
+MAN2HWNOTES_FLAGS=
+.else
+MAN2HWNOTES_FLAGS= -c
+.endif
+
+# Dependency that the article makefiles can use to pull in
+# dev-auto.ent.
+${DEV-AUTODIR}/catalog-auto ${DEV-AUTODIR}/dev-auto.ent: ${MAN4PAGES} \
+ ${ARCHLIST} ${MAN2HWNOTES_CMD}
+ cd ${RELN_ROOT}/share/xml && make MAN2HWNOTES_FLAGS=${MAN2HWNOTES_FLAGS} dev-auto.ent
diff --git a/release/doc/share/xml/Makefile b/release/doc/share/xml/Makefile
new file mode 100644
index 0000000..b2c1b6d
--- /dev/null
+++ b/release/doc/share/xml/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+RELN_ROOT?= ${.CURDIR}/../..
+
+.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
+
+dev-auto.ent: ${MAN4PAGES} ${ARCHLIST} ${MAN2HWNOTES_CMD}
+ ${PERL} ${MAN2HWNOTES_CMD} ${MAN2HWNOTES_FLAGS} -a ${ARCHLIST} -o ${.TARGET} ${MAN4PAGES}
+
+all: dev-auto.ent
diff --git a/release/doc/share/xml/catalog.xml b/release/doc/share/xml/catalog.xml
new file mode 100644
index 0000000..74f8ccd
--- /dev/null
+++ b/release/doc/share/xml/catalog.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- $FreeBSD$ -->
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+ <rewriteSystem systemIdStartString="http://www.FreeBSD.org/release/XML/"
+ rewritePrefix="../../"/>
+ <rewriteURI uriStartString="http://www.FreeBSD.org/release/XML/"
+ rewritePrefix="../../"/>
+
+ <public publicId="-//FreeBSD//ENTITIES Release Specification//EN" uri="release.ent"/>
+ <public publicId="-//FreeBSD//ENTITIES Sponsor Specification//EN" uri="sponsor.ent"/>
+ <public publicId="-//FreeBSD//ENTITIES Vendor Specification//EN" uri="vendor.ent"/>
+ <public publicId="-//FreeBSD//ENTITIES Auto Generated Device Lists//EN" uri="dev-auto.ent"/>
+</catalog>
diff --git a/release/doc/share/xml/errata.xml b/release/doc/share/xml/errata.xml
new file mode 100644
index 0000000..efc21a1
--- /dev/null
+++ b/release/doc/share/xml/errata.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <colspec colwidth="40%"/>
+ <colspec colwidth="30%"/>
+ <colspec colwidth="30%"/>
+ <thead>
+ <row>
+ <entry>Errata</entry>
+ <entry>Date</entry>
+ <entry>Topic</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><para>No errata notices.</para></entry>
+ <entry><para>&nbsp;</para></entry>
+ <entry><para>&nbsp;</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
diff --git a/release/doc/share/xml/release.ent b/release/doc/share/xml/release.ent
new file mode 100644
index 0000000..f72b4d0
--- /dev/null
+++ b/release/doc/share/xml/release.ent
@@ -0,0 +1,82 @@
+<!-- -*- sgml -*-
+
+ $FreeBSD$
+
+ OS Release Information -->
+
+<!-- Version of the OS we're describing. This needs to be updated
+ with each new release. -->
+<!ENTITY release.current "11.0-CURRENT">
+
+<!-- The previous version used for comparison in the "What's New"
+ section. For -CURRENT, we might point back to the last
+ branchpoint. -->
+<!ENTITY release.prev "10.0-RELEASE">
+
+<!-- The previous stable release, useful for pointing user's at the
+ release they SHOULD be running if they don't want the bleeding
+ edge. -->
+<!ENTITY release.prev.stable "9.3-RELEASE">
+
+<!-- The next version to be released, usually used for snapshots. -->
+<!ENTITY release.next "11.0-RELEASE">
+
+<!-- The name of this branch. -->
+<!ENTITY release.branch "11-CURRENT">
+
+<!-- The URL for obtaining this version of FreeBSD. -->
+<!ENTITY release.url "https://www.FreeBSD.org/snapshots/">
+
+<!-- The URL for Security Advisories and Errata Notices. -->
+<!ENTITY security.url "https://www.FreeBSD.org/security/advisories">
+
+<!-- The recommended mailing list to track. -->
+<!ENTITY release.maillist "current">
+
+<!-- The type of release (usually this will be either "snapshot"
+ or "release" -->
+<!-- WARNING: Do not forget to also change the release type in
+ doc.relnotes.mk when updating this -->
+<!ENTITY release.type "snapshot">
+<!ENTITY % release.type.current "INCLUDE">
+<!ENTITY % release.type.snapshot "IGNORE">
+<!ENTITY % release.type.release "IGNORE">
+
+<![%release.type.current;[
+<!ENTITY release '&release.current;'>
+]]>
+<![%release.type.snapshot;[
+<!ENTITY release '&release.prev;'>
+]]>
+<![%release.type.release;[
+<!ENTITY release '&release.current;'>
+]]>
+<!ENTITY release ''>
+
+<!-- The manpaths for man page references -->
+<!ENTITY release.man.url "https://www.FreeBSD.org/cgi/man.cgi">
+<!ENTITY release.manpath.xorg "7.5.1">
+<!ENTITY release.manpath.netbsd "5.1">
+<!ENTITY release.manpath.freebsd-ports "Ports">
+<!ENTITY release.manpath.freebsd "10-current">
+
+<!-- Text constants which probably don't need to be changed.-->
+
+<!-- Name of our OS. This is almost certainly going to remain
+ FreeBSD, but we might want to try to do some other formatting or
+ other fancy markup on it in the future. -->
+<!ENTITY os "FreeBSD">
+
+<!-- Architecture names -->
+<!ENTITY arch.amd64 "amd64">
+<!ENTITY arch.arm "arm">
+<!ENTITY arch.arm64 "aarch64">
+<!ENTITY arch.i386 "i386">
+<!ENTITY arch.mips "mips">
+<!ENTITY arch.pc98 "pc98">
+<!ENTITY arch.powerpc "powerpc">
+<!ENTITY arch.powerpc64 "powerpc64">
+<!ENTITY arch.sparc64 "sparc64">
+
+<!-- The marker for MFCs. -->
+<!ENTITY merged "MERGED">
diff --git a/release/doc/share/xml/release.xsl b/release/doc/share/xml/release.xsl
new file mode 100644
index 0000000..f76ae68
--- /dev/null
+++ b/release/doc/share/xml/release.xsl
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<!-- $FreeBSD$ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'
+ xmlns="http://www.w3.org/TR/xhtml1/transitional"
+ xmlns:db="http://docbook.org/ns/docbook"
+ exclude-result-prefixes="db">
+
+ <xsl:import href="http://www.FreeBSD.org/XML/share/xml/freebsd-xhtml.xsl"/>
+
+ <xsl:import href="http://www.FreeBSD.org/release/XML/lang/share/xml/release.xsl"/>
+
+ <xsl:param name="release.url"/>
+ <xsl:param name="release.branch"/>
+ <xsl:param name="release.maillist"/>
+
+ <xsl:template name="paragraph">
+ <xsl:param name="class" select="''"/>
+ <xsl:param name="content"/>
+
+ <xsl:variable name="p">
+ <p>
+ <xsl:choose>
+ <xsl:when test="$class != ''">
+ <xsl:call-template name="common.html.attributes">
+ <xsl:with-param name="class" select="$class"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="locale.html.attributes"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:if test="@arch">
+ <xsl:value-of select="concat('[', @arch, ']')"/>
+ <xsl:value-of select='" "'/>
+ </xsl:if>
+ <xsl:copy-of select="$content"/>
+ <xsl:value-of select='" "'/>
+ <xsl:if test="@revision">
+ <xsl:element name="a">
+ <xsl:attribute name="href">
+ <xsl:value-of select="concat('http://svn.freebsd.org/viewvc/base?view=revision&#38;revision=', @revision)"/>
+ </xsl:attribute>
+ <xsl:value-of select="concat('[r', @revision, ']')"/>
+ </xsl:element>
+ </xsl:if>
+ <xsl:if test="@contrib">
+ <xsl:element name="span">
+ <xsl:attribute name="class">
+ <xsl:value-of select="'contrib'"/>
+ </xsl:attribute>
+ <xsl:choose>
+ <xsl:when test="@contrib = 'sponsor'">
+ <xsl:if test="@sponsor != ''">
+ (Sponsored by
+ <xsl:choose>
+ <xsl:when test="@sponsorurl != ''">
+ <xsl:element name="a">
+ <xsl:attribute name="href">
+ <xsl:value-of select="@sponsorurl"/>
+ </xsl:attribute>
+ <xsl:value-of select="concat(@sponsor, ')')"/>
+ </xsl:element>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat(@sponsor, ')')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:when>
+ <xsl:when test="@contrib = 'vendor'">
+ <xsl:if test="@vendor != ''">
+ (Contributed / provided by
+ <xsl:choose>
+ <xsl:when test="@vendorurl != ''">
+ <xsl:element name="a">
+ <xsl:attribute name="href">
+ <xsl:value-of select="@vendorurl"/>
+ </xsl:attribute>
+ <xsl:value-of select="concat(@vendor, ')')"/>
+ </xsl:element>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat(@vendor, ')')"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:element>
+ </xsl:if>
+ </p>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$html.cleanup != 0">
+ <xsl:call-template name="unwrap.p">
+ <xsl:with-param name="p" select="$p"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$p"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/release/doc/share/xml/security.xml b/release/doc/share/xml/security.xml
new file mode 100644
index 0000000..74a8cd7
--- /dev/null
+++ b/release/doc/share/xml/security.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <colspec colwidth="40%"/>
+ <colspec colwidth="30%"/>
+ <colspec colwidth="30%"/>
+ <thead>
+ <row>
+ <entry>Advisory</entry>
+ <entry>Date</entry>
+ <entry>Topic</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><para>No advisories.</para></entry>
+ <entry><para>&nbsp;</para></entry>
+ <entry><para>&nbsp;</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>
diff --git a/release/doc/share/xml/sponsor.ent b/release/doc/share/xml/sponsor.ent
new file mode 100644
index 0000000..a76ef88
--- /dev/null
+++ b/release/doc/share/xml/sponsor.ent
@@ -0,0 +1,55 @@
+<!-- -*- sgml -*-
+
+ $FreeBSD$
+
+ Sponsors of various works.
+
+ Please keep the entity list sorted alphabetically.
+
+-->
+
+<!ENTITY abt "ABT Systems, Ltd.">
+<!ENTITY afrl "AFRL">
+
+<!ENTITY chelsio "Chelsio Communications">
+
+<!ENTITY citrix "Citrix Systems">
+<!ENTITY citrix.rd "Citrix Systems R&amp;D">
+
+<!ENTITY clusterhq "ClusterHQ">
+
+<!ENTITY darpa "DARPA">
+<!ENTITY darpa_afrl "DARPA, AFRL">
+<!ENTITY dell "Dell, Inc.">
+
+<!ENTITY emcisilon "EMC / Isilon Storage Division">
+
+<!ENTITY ff "The&nbsp;&os;&nbsp;Foundation">
+<!ENTITY ff.url "https://www.FreeBSDFoundation.org/">
+
+<!ENTITY gandi "Gandi.net">
+<!ENTITY google "Google">
+
+<!ENTITY juniper "Juniper Networks, Inc.">
+
+<!ENTITY intelcorp "Intel Corporation">
+<!ENTITY ix "iXsystems">
+
+<!ENTITY limelight "Limelight Networks">
+<!ENTITY lsi "LSI">
+
+<!ENTITY msostc "Microsoft Open Source Technology Center">
+<!ENTITY mitail "MIT Computer Science &amp; Artificial Intelligence Laboratory">
+<!ENTITY multiplay "Multiplay">
+
+<!ENTITY netflix "Netflix">
+<!ENTITY netgate "Netgate">
+<!ENTITY nginx "Nginx, Inc.">
+<!ENTITY norse "Norse Corporation">
+
+<!ENTITY sandvine "Sandvine, Inc.">
+<!ENTITY scaleengine "ScaleEngine, Inc.">
+<!ENTITY solarflare "Solarflare Communications, Inc.">
+<!ENTITY spectralogic "Spectra Logic">
+
+<!ENTITY yandex "Yandex LLC">
diff --git a/release/doc/share/xml/vendor.ent b/release/doc/share/xml/vendor.ent
new file mode 100644
index 0000000..75c879b
--- /dev/null
+++ b/release/doc/share/xml/vendor.ent
@@ -0,0 +1,9 @@
+<!-- -*- sgml -*-
+
+ $FreeBSD$
+
+ Vendors and contributors.
+
+ Please keep the entity list sorted alphabetically.
+
+-->
diff --git a/release/i386/make-memstick.sh b/release/i386/make-memstick.sh
new file mode 100755
index 0000000..27979ae7
--- /dev/null
+++ b/release/i386/make-memstick.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# This script generates a "memstick image" (image that can be copied to a
+# USB memory stick) from a directory tree. Note that the script does not
+# clean up after itself very well for error conditions on purpose so the
+# problem can be diagnosed (full filesystem most likely but ...).
+#
+# Usage: make-memstick.sh <directory tree> <image filename>
+#
+# $FreeBSD$
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+if [ $# -ne 2 ]; then
+ echo "make-memstick.sh /path/to/directory /path/to/image/file"
+ exit 1
+fi
+
+if [ ! -d ${1} ]; then
+ echo "${1} must be a directory"
+ exit 1
+fi
+
+if [ -e ${2} ]; then
+ echo "won't overwrite ${2}"
+ exit 1
+fi
+
+echo '/dev/ufs/FreeBSD_Install / ufs ro,noatime 1 1' > ${1}/etc/fstab
+makefs -B little -o label=FreeBSD_Install ${2}.part ${1}
+if [ $? -ne 0 ]; then
+ echo "makefs failed"
+ exit 1
+fi
+rm ${1}/etc/fstab
+
+mkimg -s gpt -b ${1}/boot/pmbr -p freebsd-boot:=${1}/boot/gptboot -p freebsd-ufs:=${2}.part -p freebsd-swap::1M -o ${2}
+rm ${2}.part
+
diff --git a/release/i386/mkisoimages.sh b/release/i386/mkisoimages.sh
new file mode 100644
index 0000000..a250105
--- /dev/null
+++ b/release/i386/mkisoimages.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Module: mkisoimages.sh
+# Author: Jordan K Hubbard
+# Date: 22 June 2001
+#
+# $FreeBSD$
+#
+# This script is used by release/Makefile to build the (optional) ISO images
+# for a FreeBSD release. It is considered architecture dependent since each
+# platform has a slightly unique way of making bootable CDs. This script
+# is also allowed to generate any number of images since that is more of
+# publishing decision than anything else.
+#
+# Usage:
+#
+# mkisoimages.sh [-b] image-label image-name base-bits-dir [extra-bits-dir]
+#
+# Where -b is passed if the ISO image should be made "bootable" by
+# whatever standards this architecture supports (may be unsupported),
+# image-label is the ISO image label, image-name is the filename of the
+# resulting ISO image, base-bits-dir contains the image contents and
+# extra-bits-dir, if provided, contains additional files to be merged
+# into base-bits-dir as part of making the image.
+
+if [ "x$1" = "x-b" ]; then
+ # This is highly x86-centric and will be used directly below.
+ bootable="-o bootimage=i386;$4/boot/cdboot -o no-emul-boot"
+ shift
+else
+ bootable=""
+fi
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 [-b] image-label image-name base-bits-dir [extra-bits-dir]"
+ exit 1
+fi
+
+LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift
+NAME="$1"; shift
+
+publisher="The FreeBSD Project. http://www.FreeBSD.org/"
+echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$1/etc/fstab"
+makefs -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@"
+rm "$1/etc/fstab"
diff --git a/release/pc98/mkisoimages.sh b/release/pc98/mkisoimages.sh
new file mode 100644
index 0000000..074fe09
--- /dev/null
+++ b/release/pc98/mkisoimages.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Module: mkisoimages.sh
+# Author: Jordan K Hubbard
+# Date: 22 June 2001
+#
+# $FreeBSD$
+#
+# This script is used by release/Makefile to build the (optional) ISO images
+# for a FreeBSD release. It is considered architecture dependent since each
+# platform has a slightly unique way of making bootable CDs. This script
+# is also allowed to generate any number of images since that is more of
+# publishing decision than anything else.
+#
+# Usage:
+#
+# mkisoimages.sh [-b] image-label image-name base-bits-dir [extra-bits-dir]
+#
+# Where -b is passed if the ISO image should be made "bootable" by
+# whatever standards this architecture supports (may be unsupported),
+# image-label is the ISO image label, image-name is the filename of the
+# resulting ISO image, base-bits-dir contains the image contents and
+# extra-bits-dir, if provided, contains additional files to be merged
+# into base-bits-dir as part of making the image.
+
+if [ "x$1" = "x-b" ]; then
+ # This is highly x86-centric and will be used directly below.
+ bootable="-o generic-bootimage=$4/boot/cdboot"
+ shift
+else
+ bootable=""
+fi
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 [-b] image-label image-name base-bits-dir [extra-bits-dir]"
+ exit 1
+fi
+
+LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift
+NAME="$1"; shift
+
+publisher="The FreeBSD Project. http://www.FreeBSD.org/"
+echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$1/etc/fstab"
+makefs -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@"
+rm "$1/etc/fstab"
diff --git a/release/picobsd/Version b/release/picobsd/Version
new file mode 100644
index 0000000..871bd81
--- /dev/null
+++ b/release/picobsd/Version
@@ -0,0 +1 @@
+VER=0.500
diff --git a/release/picobsd/bridge/PICOBSD b/release/picobsd/bridge/PICOBSD
new file mode 100644
index 0000000..bc1185d
--- /dev/null
+++ b/release/picobsd/bridge/PICOBSD
@@ -0,0 +1,118 @@
+#
+# $FreeBSD$
+#
+# Line starting with #PicoBSD contains PicoBSD build parameters
+#marker def_sz init MFS_inodes floppy_inodes
+#PicoBSD 8000 init 8192 32768
+options MD_ROOT_SIZE=8000 # same as def_sz
+
+hints "PICOBSD.hints"
+
+# values accessible through getenv()
+# env "PICOBSD.env"
+
+#cpu I486_CPU
+cpu I586_CPU
+cpu I686_CPU
+ident PICOBSD
+
+options SMP
+device apic
+
+options SCHED_4BSD # mandatory to have one scheduler
+#options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+#options INET6
+options FFS #Berkeley Fast Filesystem
+#options BOOTP #Use BOOTP to obtain IP address/hostname
+options MD_ROOT #MD is a potential root device
+
+#options NFS #Network Filesystem
+#options NFS_ROOT #NFS usable as root device, NFS required
+
+#options MSDOSFS #MSDOS Filesystem
+#options CD9660 #ISO 9660 Filesystem
+#options CD9660_ROOT #CD-ROM usable as root, CD9660 required
+#options DEVFS #Device Filesystem
+#options PROCFS #Process filesystem
+options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
+
+#options DDB
+
+options IPFIREWALL
+options IPFIREWALL_DEFAULT_TO_ACCEPT
+options IPDIVERT # divert (for natd)
+
+# Support for bridging and bandwidth limiting
+options DUMMYNET
+device if_bridge
+# Running with less than 1000 seems to give poor timing on
+# qemu, so we set HZ explicitly.
+options HZ=1000
+
+device random # used by ssh
+device pci
+
+# Floppy drives
+device fdc
+
+# ATA and ATAPI devices
+#device ata
+#device atadisk # ATA disk drives
+#device atapicd # ATAPI CDROM drives
+#options ATA_STATIC_ID #Static device numbering
+
+# atkbdc0 controls both the keyboard and the PS/2 mouse
+device atkbdc # At keyboard controller
+device atkbd
+#device psm # do we need the mouse ??
+
+device vga # VGA screen
+
+# syscons is the default console driver, resembling an SCO console
+device sc
+
+# Serial (COM) ports
+device uart
+
+# Audio support
+#device pcm
+
+# PCCARD (PCMCIA) support
+#device card # pccard bus
+#device pcic # PCMCIA bridge
+
+# Parallel port
+#device ppc
+#device ppbus # Parallel port bus (required)
+#device lpt # Printer
+#device plip # TCP/IP over parallel
+#device ppi # Parallel port interface device
+
+#
+# The following Ethernet NICs are all PCI devices.
+#
+device miibus
+device fxp # Intel EtherExpress PRO/100B (82557, 82558)
+device nfe # nVidia nForce MCP on-board Ethernet
+#device xl # 3Com
+device rl # RealTek 8129/8139
+device re # RealTek 8139C+/8169/8169S/8110S
+device sis # National/SiS
+device dc # DEC/Intel 21143 and various workalikes
+device ed
+
+device loop # Network loopback
+device ether # Ethernet support
+device tun # Packet tunnel.
+#device vn #Vnode driver (turns a file into a device)
+device pty # Pseudo-ttys (telnet etc)
+device md # Memory "disks"
+#device gif 4 # IPv6 and IPv4 tunneling
+device tap
+
+#options DEVICE_POLLING
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+device bpf # Berkeley packet filter
diff --git a/release/picobsd/bridge/PICOBSD.hints b/release/picobsd/bridge/PICOBSD.hints
new file mode 100644
index 0000000..4f1b403
--- /dev/null
+++ b/release/picobsd/bridge/PICOBSD.hints
@@ -0,0 +1,39 @@
+# $FreeBSD$
+hint.fdc.0.at="isa"
+hint.fdc.0.port="0x3F0"
+hint.fdc.0.irq="6"
+hint.fdc.0.drq="2"
+hint.fd.0.at="fdc0"
+hint.fd.0.drive="0"
+hint.ata.0.at="isa"
+hint.ata.0.port="0x1F0"
+hint.ata.0.irq="14"
+hint.ata.1.at="isa"
+hint.ata.1.port="0x170"
+hint.ata.1.irq="15"
+hint.atkbdc.0.at="isa"
+hint.atkbdc.0.port="0x060"
+hint.atkbd.0.at="atkbdc"
+hint.atkbd.0.irq="1"
+hint.psm.0.at="atkbdc"
+hint.psm.0.irq="12"
+hint.vga.0.at="isa"
+hint.sc.0.at="isa"
+hint.npx.0.at="nexus"
+hint.npx.0.port="0x0F0"
+hint.npx.0.irq="13"
+hint.uart.0.at="isa"
+hint.uart.0.port="0x3F8"
+hint.uart.0.flags="0x10"
+hint.uart.0.irq="4"
+hint.uart.1.at="isa"
+hint.uart.1.port="0x2F8"
+hint.uart.1.irq="3"
+hint.ed.0.at="isa"
+hint.ed.0.port="0x280"
+hint.ed.0.irq="5"
+hint.ed.0.maddr="0xd8000"
+hint.ed.1.at="isa"
+hint.ed.1.port="0x300"
+hint.ed.1.irq="5"
+hint.ed.1.maddr="0xd0000"
diff --git a/release/picobsd/bridge/config b/release/picobsd/bridge/config
new file mode 100644
index 0000000..af409a1
--- /dev/null
+++ b/release/picobsd/bridge/config
@@ -0,0 +1,6 @@
+# configuration for picobsd build script.
+# $FreeBSD$
+# it should only contain variable definitions -- it is sourced
+# by the shell much like rc.conf* files
+
+fd_size="4096"
diff --git a/release/picobsd/bridge/crunch.conf b/release/picobsd/bridge/crunch.conf
new file mode 100644
index 0000000..fce2897
--- /dev/null
+++ b/release/picobsd/bridge/crunch.conf
@@ -0,0 +1,183 @@
+#
+# $FreeBSD$
+#
+# Configuration file for "bridge" images..
+#
+# Depending on your needs, you will almost surely need to
+# add/remove/change programs according to your needs.
+# Remember that some programs require matching kernel options to
+# enable device drivers etc.
+#
+# To figure out how much space is used by each program, do
+#
+# size build_dir-bridge/crunch/*lo
+#
+# Remember that programs require libraries, which add up to the
+# total size. The final binary is build_dir-bridge/mfs.tree/stand/crunch
+# and you can check which libraries it uses with
+#
+# ldd build_dir-bridge/mfs.tree/stand/crunch
+
+# crunchgen configuration to build the crunched binary, see "man crunchgen"
+# We need to specify generic build options, the places where to look
+# for sources, and the list of program and libraries we want to put
+# in the crunched binary.
+#
+# NOTE: the string "/usr/src" below will be automatically replaced with
+# the path set in the 'build' script.
+
+# Default build options. Basically tell the Makefiles
+# that to use the most compact possible version of the code.
+
+buildopts -DWITHOUT_PAM -DRELEASE_CRUNCH -DPPP_NO_NETGRAPH
+buildopts -DTRACEROUTE_NO_IPSEC -DNO_INET6
+buildopts -DWITHOUT_KERBEROS -DWITHOUT_OPENSSL
+
+# Directories where to look for sources of various binaries.
+# @__CWD__@ is a magic keyword in the picobsd's (Makefile.conf)
+# which is replaced with the directory with the picobsd configuration
+# corresponding to your image. This way you can have custom sources
+# in that directory overriding system programs.
+
+srcdirs @__CWD__@/src
+
+# Some programs are especially written for PicoBSD and reside in
+# release/picobsd/tinyware.
+# Put this entry near the head of the list to override standard binaries.
+
+srcdirs /usr/src/release/picobsd/tinyware
+
+# Other standard locations for sources.
+# If a program uses its own source directory, add
+
+srcdirs /usr/src/bin
+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
+srcdirs /usr/src/libexec
+
+# For programs that reside in different places, the best option
+# is to use the command "special XXX srcdir YYY" where XXX is the
+# program name and YYY is the directory path.
+# "special XXX ..." can be used to specify more options, see again
+# the crunchgen manpage.
+
+#--- Basic configuraton
+# init is always necessary (unless you have a replacement, oinit)
+progs init
+
+# fsck is almost always necessary, unless you have everything on the
+# image and use 'tar' or something similar to read/write raw blocks
+# from the floppy.
+
+progs fsck
+
+# ifconfig is needed if you want to configure interfaces.
+progs ifconfig
+
+# You will also need a shell and a bunch of utilities.
+# The standard shell is not that large, but you need many
+# external programs. In fact most of them do not take much space
+# as they merely issue a system call, and print the result.
+# For a more compact version of shell and utilities, you could
+# try busybox, however most system management commands in busybox
+# will not work as they use linux-specific interfaces.
+
+progs sh
+ln sh -sh
+
+# the small utilities
+progs echo
+progs pwd mkdir rmdir
+progs chmod chown
+ln chown chgrp
+progs mv ln cp rm ls
+progs cat tail tee
+progs test
+ln test [
+
+progs less
+ln less more
+progs mount
+progs minigzip
+ln minigzip gzip
+progs kill
+progs df
+progs ps
+progs ns # this is the picobsd version
+ln ns netstat
+progs vm
+progs hostname
+progs login
+progs getty
+progs stty
+progs w
+progs msg
+ln msg dmesg
+progs reboot
+
+progs sysctl
+progs swapon
+progs pwd_mkdb
+progs umount
+progs du
+progs passwd
+
+progs route
+
+# If you want to run natd, remember the alias library
+#progs natd
+#libs_so -lalias # natd
+
+# ppp is rather large. Note that as of Jan.01, RELEASE_CRUNCH
+# makes ppp not use libalias, so you cannot have aliasing.
+#progs ppp
+
+# You need an editor. ee is relatively small, though there are
+# smaller ones. vi is much larger.
+# The editor also usually need a curses library.
+progs ee
+
+progs arp
+
+# these require libgeom
+# progs bsdlabel fdisk mdconfig
+
+progs kldload kldunload kldstat
+progs kldxref
+#progs grep
+progs date
+progs ping
+#progs routed
+progs ipfw
+progs traceroute
+progs mdmfs
+ln mdmfs mount_mfs
+# Various filesystem support -- remember to enable the kernel parts
+# progs mount_msdosfs
+progs mount_nfs
+# progs mount_cd9660
+ln mount_nfs nfs
+ln mount_cd9660 cd9660
+#progs newfs
+#ln newfs mount_mfs
+# ln mount_msdosfs msdos
+
+# For a small ssh client/server use dropbear
+
+# Now the libraries
+libs_so -lc # the C library
+libs_so -ll # used by sh (really ?)
+libs_so -lufs # used by mount
+### ee uses ncurses but as a dependency
+#libs_so -lncurses
+libs_so -lm
+libs_so -ledit -lutil
+libs_so -lcrypt
+libs_so -lkvm
+libs_so -lz
+libs_so -lbsdxml
+libs_so -lsbuf
+libs_so -ljail # used by ifconfig
diff --git a/release/picobsd/bridge/floppy.tree.exclude b/release/picobsd/bridge/floppy.tree.exclude
new file mode 100644
index 0000000..adfc6cc
--- /dev/null
+++ b/release/picobsd/bridge/floppy.tree.exclude
@@ -0,0 +1,2 @@
+etc/snmpd.conf
+etc/ppp
diff --git a/release/picobsd/build/Makefile.conf b/release/picobsd/build/Makefile.conf
new file mode 100644
index 0000000..7340663
--- /dev/null
+++ b/release/picobsd/build/Makefile.conf
@@ -0,0 +1,61 @@
+# $FreeBSD$
+#
+# Makefile for building PICOBSD kernels and running crunchgen
+#
+# Needs SRC pointing to the source tree,
+# MY_TREE ponting to my tree
+# BUILDDIR pointing to the build directory
+# PICO_OBJ pointing to the object directory
+# When building a kernel, also need ${name} from the environment
+# and CONFIG may indicate an alternate config program
+
+BINMAKE?=make
+SRC?=/usr/src
+CONFIG?=config
+MODULES?=-DNO_MODULES # do not build them as a default
+KERNCONF ?= PICOBSD
+
+# caller will set MODULES to empty if modules are needed.
+# Indeed, it can be used to specify other Makefile options as well.
+
+# These 3 variables determine where the kernel is built.
+# If config were smart enough, we could place the config
+# file in some other place than ${SRC}/sys/${TARGET_ARCH}/conf, but
+# at the moment (Oct.2001) this is not possible yet.
+CONF=${SRC}/sys/${TARGET_ARCH}/conf
+#CONF=${BUILDDIR}/conf # XXX does not work yet
+CONFFILE=PICOBSD-${name}
+
+# We can, however, compile the kernel somewhere else
+#COMPILE=${CONF}/../compile/${CONFFILE}
+COMPILE=${BUILDDIR}/${CONFFILE}
+
+KERNFILE=${COMPILE}/kernel
+
+${BUILDDIR}/kernel: ${KERNFILE}
+ cp -p ${.OODATE} ${.TARGET}
+ strip ${.TARGET}
+ strip --remove-section=.note --remove-section=.comment ${.TARGET}
+
+${KERNFILE}: ${COMPILE} do_a_make_in_the_kernel_directory_anyways
+
+do_a_make_in_the_kernel_directory_anyways:
+ (cd ${COMPILE}; ${BINMAKE} KERNEL=kernel ${MODULES} )
+
+${COMPILE}: ${CONF}/${CONFFILE}
+ (cd ${CONF}; ${CONFIG} -d ${COMPILE} ${CONFFILE}; \
+ cd ${COMPILE}; ${BINMAKE} KERNEL=kernel ${MODULES} depend )
+
+${CONF}/${CONFFILE}: ${KERNCONF}
+ # -mkdir -p ${CONF} # XXX not needed yet.
+ cp ${.OODATE} ${.TARGET}
+ [ -f PICOBSD.hints ] && cp PICOBSD.hints ${CONF}/
+
+# This part creates crunch1.conf and crunch.mk from crunch.conf
+${BUILDDIR}/crunch.mk: ${BUILDDIR}/crunch1.conf
+ -(cd ${BUILDDIR}/crunch ; \
+ crunchgen -p ${PICO_OBJ} -o -m ${.TARGET} ${.OODATE} )
+
+${BUILDDIR}/crunch1.conf: ${MY_TREE}/crunch.conf
+ (cd ${BUILDDIR}/crunch ; cat ${.OODATE} | \
+ sed -e "s@/usr/src@${SRC}@" -e "s+@__CWD__@+${MY_TREE}+" > ${.TARGET} )
diff --git a/release/picobsd/build/config b/release/picobsd/build/config
new file mode 100644
index 0000000..6d85381
--- /dev/null
+++ b/release/picobsd/build/config
@@ -0,0 +1,17 @@
+# config variables for PicoBSD floppies.
+# This file is sourced by the main build script. It should
+# only contain assignment to shell variables.
+#
+# The type-specific "config" file is sourced after this one, so
+# you can override things there.
+
+# STAND_LINKS contains the list of links to be created on the mfs image.
+# o_no_devfs is set to an empty string to inform the build script that
+# we are using devfs (this need to be done in a less confusing way sometime...)
+
+STAND_LINKS=${STAND_LINKS:-"bin sbin usr/bin usr/sbin usr/libexec \
+ usr/local/bin"}
+
+o_no_devfs="" # we have devfs.
+
+# fd_size="2880" # use this variable to set floppy sizes (in KBytes)
diff --git a/release/picobsd/build/mfs.mtree b/release/picobsd/build/mfs.mtree
new file mode 100644
index 0000000..9d6748a
--- /dev/null
+++ b/release/picobsd/build/mfs.mtree
@@ -0,0 +1,72 @@
+#
+# $FreeBSD$
+#
+/set type=dir uname=root gname=wheel mode=0755
+.
+ cdrom
+ ..
+ dev
+ ..
+ dos
+ ..
+ etc
+ ..
+ fd
+ ..
+ home
+ user
+ ..
+ ..
+ mnt
+ ..
+ mnt1
+ ..
+ mnt2
+ ..
+ proc
+ ..
+ root
+ ..
+ stand
+ ..
+ start_floppy
+ ..
+ tftpboot
+ ..
+ tmp mode=01777
+ ..
+ usr
+ local
+ etc
+ ..
+ lib
+ snmp
+ ..
+ ..
+ ..
+ share
+ misc
+ ..
+ locale
+ ..
+ syscons
+ ..
+ nls
+ ..
+ ..
+ ..
+ var
+ db
+ ..
+ empty
+ ..
+ run
+ ..
+ spool
+ lock
+ ..
+ ..
+ ..
+ wd
+ ..
+..
diff --git a/release/picobsd/build/picobsd b/release/picobsd/build/picobsd
new file mode 100755
index 0000000..2b04be4
--- /dev/null
+++ b/release/picobsd/build/picobsd
@@ -0,0 +1,1095 @@
+#!/bin/sh -
+#
+# $FreeBSD$
+# This file requires sysutils/makefs to run
+#
+# The PicoBSD build script. Invoked as
+#
+# picobsd [options] image_type [site_name]
+#
+# CWARNFLAGS can be used to pass -Wall or similar options
+#
+# Where image_type is a directory with the picobsd config info,
+# and ${image_type}/floppy.tree.${site_name} contains
+# optional site-specific configuration.
+#
+# For Options, see the bottom of the file where the processing is
+# done. The picobsd(8) manpage might be of some help, but code and docs
+# tend to lose sync over time.
+#
+# This script depends on the following files:
+#
+# in ${PICO_TREE} :
+# Makefile.conf Makefile used to build the kernel
+# config shell variables, sourced here.
+# mfs.mtree mtree config file
+# floppy.tree/ files which go on the floppy
+# mfs_tree/ files which go onto the mfs
+#
+# in ${MY_TREE} :
+# PICOBSD kernel config file
+# config shell variables, sourced here.
+# crunch.conf crunchgen configuration
+# mfs.mtree overrides ${PICO_TREE}/mfs.mtree
+# floppy.tree.exclude files from floppy.tree/ which we do not need here.
+# floppy.tree/ local additions to ${PICO_TREE}/mfs_free
+# floppy.tree.${site}/ same as above, site specific.
+# mfs_tree/ local additions to the mfs_free
+# buildtree.mk optional Makefile to build an extension for floppy tree
+# (generated in buildtree/ )
+
+#
+#--- The main entry point is at the end.
+#
+
+# There are two initialization functions:
+#
+# + set_defaults
+# is run on entry to the script, and is used to set default values
+# for all variables that do not depend on image type and source tree.
+#
+# + set_build_parameters
+# is run after command line parsing
+#
+# VARIABLE NAMES:
+# + variables that control operation (e.g. verbosity) and are generally
+# set from the command line have o_ ("option") as a name prefix
+#
+# + variables that contain pathnames and values that should not change
+# have c_ ("constant") as a name prefix
+#
+# + variables exported to Makefiles and subshells are CAPITAL
+#
+# + variables local to the script are lowercase, possibly with
+# an l_ ("local") prefix.
+#
+# There are unfortunately exceptions:
+# name, l_usrtree, l_objtree
+
+# SRC points to your FreeBSD source tree.
+# l_usrtree points to the /usr subdir for the source tree.
+# Normally /usr or ${SRC}/../usr
+# l_objtree points to the obj tree. Normally ${l_usrtree}/obj-pico-${o_arch}
+# c_label is either bsdlabel or disklabel
+# PICO_TREE is where standard picobsd stuff resides.
+# Normally ${SRC}/release/picobsd
+# You can set SRC with --src <directory>
+# It is not recommended to override the other variables.
+
+# MY_TREE (set later) is where this floppy type resides.
+# BUILDDIR is the build directory
+
+# log something on stdout if verbose.
+o_verbose=0 # this needs to be here!
+log() { # message
+ local foo
+ [ ${o_verbose} -gt 0 ] && printf "\n*** %s\n" "$*"
+ [ ${o_verbose} -gt 1 ] && read -p "=== Press enter to continue" foo
+ return 0
+}
+
+# unconditionally log and wait for input
+logverbose() { # message
+ local foo
+ printf "\n*** %s\n" "$*" >&2
+ read -p "=== Press enter to continue" foo
+ return 0
+}
+
+# set some default values for variables.
+# needs to be done as the first thing in the script.
+
+set_defaults() { # no arguments
+ # EDITOR is the editor you use
+ # fd_size floppy size in KB (default to 1440). You can use 1480,
+ # 1720, 2880, etc. but beware that only 1440 and 1480 will boot
+ # from 1.44M floppy drives (1480 will not work on vmware).
+ EDITOR=${EDITOR:-vi}
+ fd_size=${fd_size:-1440}
+
+ o_all_in_mfs="yes" # put all files in mfs so you can boot
+ # and run the image via diskless boot.
+ o_clean="" # set if you want to clean prev.builds.
+ o_interactive="" # default is interactive
+ o_verbose=0 # verbose level, 0 is silent
+ o_tarv="" # tar verbose flag, "" or "v"
+ o_init_src="" # set to build libs and includes.
+ o_makeopts=${MAKEOPTS:--s} # make options, be silent by default
+ o_no_devfs= # default is use devfs.
+ # You should only set it when building 4.x images
+ o_do_modules="" # do not build modules
+ o_arch=`uname -m` # default to amd64 or i386 ...
+
+ SRC="/usr/src" # default location for sources
+ c_startdir=`pwd` # directory where we start
+ # used to lookup config and create BUILDDIR
+
+ # XXX 6.x/7.x have a single /boot/boot block, which is the concatenation
+ # of the old two. For the time being, we keep these, but this should
+ # be fixed at some point.
+
+ # blocks
+ c_boot1=/boot/boot1 # boot blocks (in case you want custom ones)
+ c_boot2=/boot/boot2
+
+ c_reply=${c_reply:-`mktemp "/tmp/reply.XXXXXXXXXX"`}
+ # file where User replies will be put
+ c_mnt=`mktemp -d "/tmp/picobsd.XXXXXXXXXX"`
+ # mountpoint used to build memory filesystems
+ c_fs=fs.PICOBSD # filename used for the memory filesystem
+ c_img=picobsd.bin # filename used for the picobsd image
+ c_iso=picobsd.iso # filename used for the ISO image
+ generate_iso="NO" # don't generate the iso image
+
+ # select the right disklabel program
+ case `uname -r` in
+ 4.*)
+ c_label="disklabel"
+ ;;
+ *)
+ c_label="bsdlabel"
+ ;;
+ esac
+
+ set -e
+
+ trap fail 2
+ #trap fail 3
+ #trap fail 6
+ trap fail 15
+}
+
+# use the new build infrastructure to create libraries
+# and also to build a specific target
+create_includes_and_libraries2() { # opt_dir opt_target
+ local no
+ log "create_includes_and_libraries2() for ${SRC} $1"
+
+ no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" # WITHOUT_CDDL=1"
+ no="$no -DWITHOUT_CASPER"
+ no="$no -DMALLOC_PRODUCTION"
+
+ ( cd ${SRC};
+ # make -DNOCLEAN -DNOPROFILE -DNOGAMES -DNOLIBC_R -DPICOBSD buildworld
+ if [ -d "$1" ] ; then
+ cd $1 ; ${BINMAKE} ${o_par} $2 # specific target, e.g. ld-elf.so
+ else
+ export MAKEOBJDIRPREFIX=${l_objtree}
+ make ${o_par} $no toolchain
+
+ # XXX do we need any of these ?
+ eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
+ [ ${o_arch} != `uname -m` ] && \
+ (cd ${l_objtree}; ln -s . ${o_arch}.${o_arch} || true )
+ fi
+ )
+}
+
+
+# set_type <the_type> [the_site] looks in user or system directories
+# for the directory named as the first argument, reads the configuration
+# files and sets variables according to the config.
+# Also sets MY_TREE and BUILDDIR and SITE
+
+set_type() { # the_type the_site
+ local a i
+
+ log "set_type() : Type '$1' site '$2'"
+ THETYPE=$1
+ SITE=$2
+ a=$1
+ name="" # clear in case of errors
+ for i in ${c_startdir}/${a} ${PICO_TREE}/${a} ; do
+ log "set_type: checking $i"
+ [ -d $i -a -f $i/crunch.conf ] || continue
+ # look for a kernel config file, privilege arch-specific
+ l_kernconf=$i/PICOBSD.${o_arch}
+ [ -f $l_kernconf ] || l_kernconf=$i/PICOBSD
+ [ -f $l_kernconf ] || continue
+ set -- `cat $l_kernconf | \
+ awk '/^#PicoBSD/ {print $2, $3, $4, $5, $6}'`
+ [ x"$1" != "x" ] || continue
+ MFS_SIZE=$1
+ name=`(cd $i ; pwd) `
+ name=`basename $name`
+ MY_TREE=$i
+ BUILDDIR=${c_startdir}/build_dir-${name}-${o_arch}
+ log "Matching file $name in $i"
+ return ;
+ done
+ logverbose "Type $a NOT FOUND"
+}
+
+clean_tree() {
+ log "clean_tree()"
+ if [ -z "${name}" ] ; then
+ echo "---> Wrong floppy type"
+ exit 3
+ fi
+ rm -rf ${BUILDDIR}
+}
+
+# prepare a message to be printed in the dialog menus.
+set_msgs() { # OK
+ log "set_msgs()"
+
+ MSG1="Type: ${THETYPE} name $name"
+
+ MSG="PicoBSD build -- Current parameters:\n\n\t1. ${MSG1}\n\
+\t2. MFS size: ${MFS_SIZE} kB\n\
+\t3. Site-info: ${SITE}\n\t4. Full-path: ${MY_TREE}\n"
+}
+
+# Main build procedure. Builds both the disk image and the ISO
+build_image() {
+ log "build_image() <${name}>"
+ [ -n "${name}" ] || fail $? bad_type
+ clear
+ set_msgs
+ printf "${MSG}---> We'll use the sources living in ${SRC}\n\n"
+
+ # read config variables from a global and then a type-specific file
+ # basically STAND_LINKS and MY_DEVS, but can also override other
+ # variables.
+ #
+ . ${PICO_TREE}/build/config
+ [ -f "${MY_TREE}/config" ] && . ${MY_TREE}/config
+ [ -f "${o_additional_config}" ] && . ${o_additional_config}
+
+ # location of the object directory
+ PICO_OBJ=${l_objtree}/picobsd/${THETYPE}
+ log "PICO_OBJ is ${PICO_OBJ}"
+
+ # create build directory and subtree
+ mkdir -p ${BUILDDIR}/crunch
+ # remove any old stuff
+ rm -f ${BUILDDIR}/kernel.gz ${BUILDDIR}/${c_fs}
+ # invoke commands to build a kernel
+ do_kernel
+ # fill a subdirectory with things that go into the floppy
+ # (mostly /etc and similar stuff)
+ populate_floppy_fs
+ # populate it and produce a file with the MFS image
+ populate_mfs_tree # things which go into mfs
+ # create, mount and fill a filesystem with floppy image
+ fill_floppy_image # copies everything into the floppy
+}
+
+# Set build parameters interactively
+
+main_dialog() {
+ local ans i l
+
+ log "main_dialog()"
+ while true ; do
+ set_msgs
+ rm ${c_reply}
+ dialog --menu "PicoBSD build menu -- (29 sep 2001)" 19 70 12 \
+ N "--> READY, build it <---" \
+ T "${MSG1}" \
+ K "edit Kernel config file" \
+ E "Edit crunch.conf file" \
+ S "MFS Size: ${MFS_SIZE}kB" \
+ F "Floppy size: ${fd_size}kB" \
+ $ "Site-info: ${SITE}" \
+ Q "Quit" \
+ 2> ${c_reply}
+ ans=`cat ${c_reply}`
+ rm ${c_reply}
+ case ${ans} in
+ T)
+ l=""
+ for i in ${c_startdir} ${c_startdir}/* ${PICO_TREE}/* ; do
+ if [ -d $i -a -f $i/PICOBSD -a -f $i/crunch.conf ]; then
+ l="$l `basename $i` `basename $i`"
+ fi
+ done
+ log $l
+ { dialog --menu "Setup the type of configuration" 12 70 5 $l \
+ 2> ${c_reply} && set_type "`cat ${c_reply}`" ${SITE} ; } || true
+ ;;
+
+ K) ${EDITOR} ${MY_TREE}/PICOBSD ;;
+
+ E) ${EDITOR} ${MY_TREE}/crunch.conf ;;
+
+ S)
+ { dialog --title "MFS Size setup" --inputbox \
+"MFS size depends on what you need to put on the MFS image. Typically \
+ranges between 820kB (for very small bridge/router images) to \
+as much as 2500kB kB for a densely packed image. \
+Keep in mind that this memory is \
+totally lost to other programs. Usually you want to keep \
+this as small as possible. " 10 70 2> ${c_reply} \
+ && MFS_SIZE=`cat ${c_reply}` ; } || true
+ ;;
+
+ \$)
+ { dialog --title "Site info setup" --inputbox \
+ "Please enter the full path to the directory \
+ containing site-specific setup. \
+ This directory tree must contain files that replace \
+ standard ones in floppy.tree/ and mfs.tree/ . " \
+ 10 70 2> ${c_reply} && SITE=`cat ${c_reply}` ; } || true
+ ;;
+
+ F)
+ { dialog --menu "Set floppy size" 15 70 4 \
+ 1440 "1.44MB" 1720 "1.72MB" 2880 "2.88MB" 4096 "4MB" \
+ 2> ${c_reply} && fd_size=`cat ${c_reply}` ; } || true
+ ;;
+
+ N) break 2
+ ;;
+
+ Q) exit 0 ;;
+
+ *) echo "Unknown option \"${ans}\". Try again."
+ sleep 2
+ clear
+ ;;
+ esac
+ done
+}
+
+# Call the build procedure
+# Install image
+do_install() {
+ log "do_install()"
+
+ if [ "${o_interactive}" = "NO" ] ; then
+ echo "+++ Build completed +++"
+ cat .build.reply || true
+ return
+ fi
+ dialog --title "Build ${THETYPE} completed" --inputbox \
+"\nThe build process was completed successfuly.\n\
+`cat .build.reply` \n\n\
+Now we are going to install the image on the floppy.\n\
+Please insert a blank floppy in /dev/fd0.\\n
+WARNING: the contents of the floppy will be permanently erased!\n\
+\n\
+Your options:\n\
+ * ^C or [Cancel] to abort,\n\
+ * Enter to install ${c_img},\n\
+" 20 80 2> ${c_reply}
+ if [ "$?" = "0" ]; then
+ echo "Writing ${c_img}..."
+ dd if=${BUILDDIR}/${c_img} of=/dev/fd0.${fd_size}
+ else
+ echo "Ok, the image is in ${c_img}"
+ fi
+ echo "Done."
+}
+
+
+#-------------------------------------------------------------------
+
+# invoke the picobsd Makefile to compile the kernel.
+# if MODULES is set (value is irrelevant) the makefile will build modules.
+do_kernel() { # OK
+ log "do_kernel() Preparing kernel \"$name\" in $MY_TREE"
+ (cd $MY_TREE; export name SRC BUILDDIR # used in this makefile ;
+ # export CONFIG
+ export WARNS CWARNFLAGS
+ [ "${o_do_modules}" = "yes" ] && export MODULES=""
+ # kernel build not parallelizable yet
+ ${BINMAKE} KERNCONF=${l_kernconf} \
+ -f ${PICO_TREE}/build/Makefile.conf ) || \
+ fail $? missing_kernel
+}
+
+# Populate the variable part of the floppy filesystem. Must be done before
+# the MFS because its content might need to be copied there as well.
+#
+# This involves fetching files from three subtrees, in this order:
+#
+# 1. a standard one, from which type-specific files are excluded;
+# 2. a type-specific one;
+# 3. a site-specific one.
+#
+# Files are first copied to a local tree and then compressed.
+
+populate_floppy_fs() { # OK
+ local dst excl srcdir
+
+ log "populate_floppy_fs()"
+ dst=${BUILDDIR}/floppy.tree
+ log "pwd=`pwd` Populating floppy filesystem..."
+
+ rm -rf ${dst} || true # clean relics from old compilations.
+ mkdir ${dst} # create a clean tree
+
+ # compute exclude list for generic tree
+ excl=${MY_TREE}/floppy.tree.exclude
+ if [ -f ${excl} ] ; then
+ log "Files excluded from generic tree: `echo;cat ${excl}`"
+ excl="--exclude-from ${excl}"
+ else
+ excl=""
+ fi
+ # copy from the floppy trees into the destination
+ for FLOPPY_TREE in ${PICO_TREE}/floppy.tree ${MY_TREE}/floppy.tree \
+ ${MY_TREE}/floppy.tree.${SITE} ; do
+ if [ -d ${FLOPPY_TREE} ] ; then
+ (cd ${FLOPPY_TREE} ; tar -cf - \
+ --exclude .svn ${excl} . ) | \
+ (cd ${dst} ; tar x${o_tarv}f - )
+ log "Copied from ${FLOPPY_TREE}"
+ fi
+ excl="" # reset the exclude list.
+ done
+
+ # add local manipulation
+ if [ -f ${MY_TREE}/buildtree.mk ] ; then
+ log "building local floppy tree"
+ ${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk floppy.tree
+ fi
+
+ # compress the files in etc/, just in case
+ # XXX this should be done in the makefile.
+ # gzip returns an error if it fails to compress some file
+ (cd $dst ; gzip -9 etc/*
+ log "Compressed files in etc/ `echo; ls -l etc`"
+ ) || true
+}
+
+# Copy the specified files to the destination filesystem.
+# Each file is specified as a pair "src dst", dst is assumed to be
+# a directory (and created with mkdir -p) if it has a trailing /
+# Be careful to escape metacharacters.
+# You can use ${CROSS} to point to the root of the cross build
+# (remember that it might be incomplete)
+
+do_copyfiles() { # rootdir varname
+ log Copy files to $1
+ local root=$1
+ local srcs dst
+ local CROSS=${_SHLIBDIRPREFIX}
+ eval set "\${${2}}"
+ srcs=""
+ for dst in $* ; do
+ [ -z "$srcs" ] && srcs=$dst && continue
+ eval srcs="$srcs" # expand wildcard and vars
+ case x"$dst" in
+ */ ) mkdir -p ${root}/${dst} ;;
+ # * ) mkdir -p `dirname ${root}/${dst}` ;;
+ esac
+ cp -p ${srcs} ${root}/${dst} || true
+ srcs=""
+ done
+}
+
+# do_links is a helper function to create links between programs
+# in stand/
+# This is done reading the names and destination from variable
+# links in a config file, in the format
+# : dst names
+
+do_links() { # rootdir varname
+ local root=$1
+ local l i dst
+ eval l="\${${2}}"
+ dst=""
+ log "Create links for ${l}"
+ (cd ${root}/stand
+ for i in $l ; do
+ if [ "$dst" = ":" -o "$i" = ":" ] ; then
+ dst=$i
+ elif [ -n "${dst}" ] ; then
+ ln -s ${dst} ${i}
+ fi
+ done
+ )
+}
+
+# find_progs is a helper function to locate the named programs
+# or libraries in ${o_objdir} or ${_SHLIBDIRPREFIX},
+# and return the full pathnames.
+# Called as "find_progs [[-L libpath] [-P binpath]] prog1 prog2 ... "
+# On return it sets ${u_progs} to the list of programs, and ${u_libs}
+# to the list of shared libraries used.
+#
+# '-L path' can be used to specify a search path for libraries
+# (which searches in $path/lib:$path/usr/lib:$path/usr/local/lib
+# '-P binpath' can be used to specify a search path for programs
+# (which searches in a lot of places in the subtree)
+# -L must be the first, followed by -P
+#
+# You can use it e.g. in a local confign file by writing
+#
+# do_copyfiles_user() {
+# local dst=$1
+# find_progs nvi sed less grep
+# cp -p ${u_progs} ${dst}/bin
+# cp -p ${u_libs} ${dst}/lib
+# mkdir -p ${dst}/libexec
+# find_progs ld-elf.so.1
+# cp -p ${u_progs} ${dst}/libexec # ignore errors
+# }
+
+# find programs and required libraries. Accept -L libs -P path <progs>
+# if no argument default to objdir/SHLIBDIRPREFIX for both
+find_progs() { # programs
+ # logverbose "find_progs: called with $*"
+ # rev.284898 removed _SHLIBDIRPREFIX so we need to reconstruct
+ # its value in i1
+ local i1=${_SHLIBDIRPREFIX:-${l_objtree}/${SRC}/tmp}
+ local i=`realpath ${o_objdir:-${i1}/..}`
+
+ # default values for -L and -P
+ local dir="-P $i"
+ local ldir="-L $i"
+
+ while [ "$1" != "" ] ; do
+ if [ x"$1" = "x-L" -a -d "$2" ] ; then # set lib search path
+ ldir="-L $2"; shift; shift
+ elif [ x"$1" = "x-P" -a -d "$2" ] ; then # set prog search path
+ dir="-P $2"; shift; shift
+ else
+ break
+ fi
+ done
+
+ # Results are returned in global variables
+ u_libs=""
+ u_progs="`find_progs_helper $dir $*`"
+ [ -z "${u_progs}" ] && return 1 # not found, error
+
+ # use objdump to find libraries.
+ # Iterate to fetch recursive dependencies.
+ local tmp="${u_progs}"
+ local old_libs=""
+ local pass=1
+ while [ $pass -lt 10 ] ; do
+ pass=$(($pass + 1))
+ i="`objdump -x ${tmp} | \
+ awk '$1 == "NEEDED" { print $2 }' | sort | uniq | tr '\n' ' '`"
+ if [ "$old_libs" = "$i" ] ; then
+ # logverbose "find_progs: have `echo ${u_libs} | wc -w`/`echo ${i} | wc -w` libraries for: $my_progs ($u_progs)"
+ # logverbose "they are ($i) $u_libs"
+ return 0
+ else
+ # logverbose "old--- $old_libs --- new +++ $i +++"
+ fi
+ u_libs="`find_progs_helper $ldir $i`"
+ old_libs="$i"
+ tmp="$tmp $u_libs"
+ done
+ log "WARNING: Too many passes, giving up"
+}
+
+# prints to stdout files and libs in the search paths
+find_progs_helper() { # first arg is either -P or -L
+ local ty=$1 dir=$2 ; shift; shift
+ local progs="`echo $* | tr ' ' '\n' | sort -u | tr '\n' ' '`"
+ # first, extract absolute pathnames or files in this directory
+
+ # accumulate others in $names
+ local names=""
+ local i
+ for i in $progs ; do
+ [ -f "$i" ] && echo `realpath $i` && continue
+ names="${names} $i"
+ done
+ # if nothing left, we are done
+ [ -z "${names}" ] && return 0
+
+ local depth p
+ local places="" # places to search
+ if [ x-P = "x$ty" ] ; then # search programs
+ depth=2
+ p=". local/bin local/sbin local/libexec \
+ bin sbin usr/bin usr/sbin libexec gnu/usr.bin \
+ secure/usr.bin secure/usr.sbin secure/libexec "
+ else
+ depth=3
+ p="lib usr/lib gnu/lib secure/lib"
+ fi
+ for i in $p ; do
+ i="${dir}/${i}"
+ [ -d "${i}" ] && places="${places} `realpath ${i}`"
+ done
+ # logverbose "--- looking into $places"
+ places=`echo ${places} | tr ' ' '\n' | sort -u`
+ for i in $names ; do
+ find ${places} -maxdepth $depth -type f -name ${i} | head -1
+ done
+}
+
+# Populate the memory filesystem with binaries and non-variable
+# configuration files.
+# First do an mtree pass, then create directory links and device entries,
+# then run crunchgen etc. to build the binary and create links.
+# Then copy the specific/generic mfs_tree.
+# Finally, if required, make a copy of the floppy.tree onto /fd
+
+populate_mfs_tree() {
+ local i j a dst MFS_TREE
+
+ log "populate_mfs_tree()"
+ dst=${BUILDDIR}/mfs.tree
+ rm -rf ${dst} || true # clean relics from old compilations.
+ mkdir ${dst} # create a fresh tree
+
+ log "pwd=`pwd`, Populating MFS tree..."
+
+ # use type-specific mfs.mtree, default to generic one.
+ a=${MY_TREE}/mfs.mtree
+ [ -f ${a} ] || a=${PICO_TREE}/build/mfs.mtree
+ log "Running mtree using $a..."
+ mtree -deU -f $a -p ${dst} > /dev/null || fail $? mtree
+
+ # Create symlinks using relative pathnames, so it is possible
+ # to follow them also when building the image.
+ # Note that names in STAND_LINKS should not have a leading /
+ for i in ${STAND_LINKS}; do
+ j=`echo $i | sed -E 's:^[^/]+::;s:/[^/]+:../:g'`
+ ln -s ${j}stand ${dst}/$i
+ done
+ ln -s ../../dev/null ${dst}/var/run/log
+ ln -s ../../../etc/termcap ${dst}/usr/share/misc/termcap
+
+ ### now build the crunched binaries ###
+ (
+ cd ${BUILDDIR}/crunch
+ log "Making and installing crunch1 from `pwd` src ${SRC}..."
+ a=${BUILDDIR}/crunch1.conf
+ ( export BUILDDIR SRC MY_TREE PICO_OBJ ;
+ ${BINMAKE} \
+ -f ${PICO_TREE}/build/Makefile.conf ${BUILDDIR}/crunch.mk )
+ log "Libs are ${LIBS} "
+ export SRC # used by crunch.mk
+ # export LIBS CFLAGS
+ log "Now make -f crunch.mk"
+ ${BINMAKE} ${o_makeopts} -f ${BUILDDIR}/crunch.mk
+ strip --remove-section=.note --remove-section=.comment crunch1
+ mv crunch1 ${dst}/stand/crunch
+ chmod 555 ${dst}/stand/crunch
+ log "Making links for binaries..."
+ for i in `crunchgen -l $a` ; do
+ ln ${dst}/stand/crunch ${dst}/stand/${i};
+ done
+ # rm $a # do not remove!
+ ) || fail $? crunch
+
+ log "Setting up host key for sshd:"
+ for K in rsa1 rsa dsa ; do
+ if [ $K = rsa1 ] ; then
+ i=ssh_host_key
+ else
+ i=ssh_host_${K}_key
+ fi
+ if [ -f ${BUILDDIR}/floppy.tree/etc/$i.gz ] ; then
+ log "Using existing host key $i"
+ else
+ log "Generating new host key $i"
+ ssh-keygen -t $K -f ${BUILDDIR}/floppy.tree/etc/$i \
+ -N "" -C "root@picobsd"
+ gzip -9 ${BUILDDIR}/floppy.tree/etc/${i}* || true
+ fi
+ done
+
+ log "Copy generic and site-specific MFS tree..."
+ for MFS_TREE in ${PICO_TREE}/mfs_tree ${MY_TREE}/mfs_tree ; do
+ if [ -d ${MFS_TREE} ] ; then
+ log "Copy ${MFS_TREE} ..."
+ (cd ${MFS_TREE} ; tar -cf - --exclude .svn . ) | \
+ (cd ${dst} ; tar x${o_tarv}f - )
+ fi
+ done
+
+ if [ -f ${MY_TREE}/buildtree.mk ] ; then
+ log "building local floppy tree"
+ ${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk mfs.tree
+ fi
+
+ if [ "${o_all_in_mfs}" = "yes" ]; then
+ log "Copy generic floppy_tree into MFS..."
+ # ignore failure in case the floppy is empty
+ cp -Rp ${BUILDDIR}/floppy.tree/* ${dst}/fd || true
+ fi
+
+ # 4.x compatibility - create device nodes
+ if [ -n "${o_no_devfs}" ] ; then
+ # create device entries using MAKEDEV
+ (cd ${dst}/dev
+ ln -s ${SRC}/etc/MAKEDEV ; chmod 555 MAKEDEV
+ # log `pwd`
+ sh ./MAKEDEV ${MY_DEVS}
+ rm MAKEDEV
+ )
+ fi
+ if [ "`id -u`" = "0" ] ; then
+ log "Fixing permissions"
+ (cd ${dst}; chown -R root . )
+ fi
+
+ log "for a shared 'crunch' take libraries and dynamic loader as well"
+ # /stand/crunch is our main binary, we extract its libs
+ find_progs ${dst}/stand/crunch
+ if [ -n "${u_libs}" ] ; then
+ mkdir -p ${dst}/lib && (cp -p ${u_libs} ${dst}/lib || log "copy libs ${u_libs} failed" )
+ mkdir -p ${dst}/libexec
+ create_includes_and_libraries2 libexec/rtld-elf
+ find_progs ld-elf.so.1 && ( cp -p ${u_progs} ${dst}/libexec || log "copy ${u_progs} failed" )
+ fi
+
+ [ -n "${copy_files}" ] && do_copyfiles ${dst} copy_files
+ do_copyfiles_user ${dst} || true
+ [ -n "${links}" ] && do_links ${dst} links
+ strip ${dst}/libexec/* ${dst}/lib/* 2> /dev/null || true
+ # strip ${dst}/stand/* 2> /dev/null || true
+ # The 'import_files' mechanism is deprecated, as it requires
+ # root permissions to follow the symlinks, and also does
+ # not let you rename the entries.
+ if [ -n "${import_files}" ] ; then
+ log "importing ${import_files} into mfs"
+ # We do it in a chroot environment on the target so
+ # symlinks are followed correctly.
+ # Make sure we have a statically linked tar there.
+ mkdir -p ${dst}/rescue
+ cp /rescue/tar ${dst}/rescue
+ (cd ${l_usrtree}/.. ; tar cf - ${import_files} ) | \
+ (chroot ${dst} /rescue/tar xPf - )
+ rm -rf ${dst}/rescue
+ fi
+
+ # final step -- build the mfs image
+ (cd ${BUILDDIR}
+ # override the owner
+ echo "/set uid=0 gid=0" > mtree.out
+ mtree -ic -p ${dst} -k "" >> mtree.out
+ log "mtree.out at ${BUILDDIR}/mtree.out size ${MFS_SIZE}k"
+ makefs -t ffs -o bsize=4096 -o fsize=512 \
+ -s ${MFS_SIZE}k -f 1000 -F mtree.out ${c_fs} ${dst}
+ ls -l ${c_fs} )
+ log "done mfs image"
+}
+
+final_cleanup() {
+ log "final_cleanup()"
+ rm -rf ${c_mnt} ${c_reply} 2> /dev/null || true
+}
+
+# fail errno errcode
+# This function is used to trap errors and print msgs
+#
+fail() {
+ local errno errocode where
+
+ errno=$1
+ errcode=$2
+ where=$3
+ echo "---> fail: Error <${errno}> error code <${errcode}> in <${where}>"
+ case ${errcode} in
+ mtree)
+ echo "Error while making hierarchy in ${c_mnt}"
+ ;;
+ crunch)
+ echo "Error while building ${name}."
+ ;;
+ missing_kernel)
+ echo "Error: you must build PICOBSD${suffix} kernel first"
+ ;;
+ includes)
+ echo "Error: failed while making includes"
+ ;;
+ libraries)
+ echo "Error: failed while making libraries"
+ ;;
+ bad_type)
+ echo "Error: unknown floppy type ${name}"
+ ;;
+ no_space)
+ echo "Error: no space left on device (${where})"
+ ;;
+ no_mfs)
+ echo "Error: while writing MFS into the kernel."
+ ;;
+ "")
+ echo "User break"
+ errcode="userbreak"
+ ;;
+ *)
+ echo "unknown error, maybe user break: $errno $errcode"
+ ;;
+ esac
+ echo "---> Aborting $0"
+ # try to cleanup the vnode.
+ final_cleanup
+ exit 2
+}
+
+fill_floppy_image() {
+ local blocks dst mfs_start mfs_end mfs_size img_size
+
+ log "fill_floppy_image()"
+ dst=${c_mnt} # where to create the image
+
+ log "Preparing ${fd_size}kB floppy filesystem..."
+
+ # correct blocks according to size.
+ blocks=${fd_size};
+ if [ "${blocks}" = "1720" ]; then
+ blocks=1722
+ elif [ "${blocks}" = "1480" ]; then
+ blocks=1476
+ fi
+
+ log "Labeling floppy image"
+
+ dst=${BUILDDIR}/image.tree
+ rm -rf ${dst}
+ mkdir -p ${dst}
+ (
+ cd ${BUILDDIR}
+ set 0 0 # reset variables
+ # $1 takes the offset of the MFS filesystem
+ set `strings -at d kernel | grep "MFS Filesystem goes here"`
+ mfs_start=$1
+ set 0 0 # reset variables
+ set `strings -at d kernel | grep "MFS Filesystem had better"`
+ mfs_end=$1
+ mfs_size="$((${mfs_end} - ${mfs_start}))"
+ set -- `ls -l ${c_fs}`; imgsize="$5"
+ if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then
+ mfs_ofs=$((${mfs_start} + 8192))
+ log "Preload kernel with file ${c_fs} at ${mfs_ofs}"
+ log "`ls -l ${c_fs}` to fit in ${mfs_size}"
+ dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \
+ oseek=1 conv=notrunc # 2> /dev/null
+ else
+ log "not loading mfs, size ${mfs_size} img ${imgsize}"
+ fi
+ log "Compress with gzip and copy to floppy image"
+
+ mkdir -p ${dst}/boot/kernel
+ # XXX loader.conf does not work unless we also load the .4th files
+ # echo "hint.acpi.0.disabled=\"1\"" > ${dst}/boot/loader.conf
+ # echo "console=\"comconsole\"" >> ${dst}/boot/loader.conf
+ local blf="loader* *.4th" # loader.rc loader.4th support.4th"
+ (cd /boot; cp -p loader ${dst}/boot) || fail $? no_space "copying bootloader"
+ cp ${MY_TREE}/floppy.tree/boot/loader.conf ${dst}/boot || true
+ gzip -c kernel > ${dst}/boot/kernel/kernel.gz || fail $? no_space "copying kernel"
+
+ # now transfer the floppy tree. If it is already in mfs, dont bother.
+ if [ "${o_all_in_mfs}" != "yes" ] ; then
+ log "Now transfer floppy tree if not already in MFS image"
+ cp -Rp floppy.tree/* ${dst} || \
+ fail $? no_space "copying floppy tree"
+ fi
+ )
+
+ # add local manipulation to the image
+ if [ -f ${MY_TREE}/buildtree.mk ] ; then
+ ${BINMAKE} -C ${dst} -f ${MY_TREE}/buildtree.mk image.tree
+ fi
+
+ log "image used `du -s ${dst}` of ${blocks}k"
+ if [ "${generate_iso}" = "YES" ]; then
+ logverbose "generate_iso ${generate_iso}"
+ # build_iso_image # XXX not implemented yet
+ (cd ${BUILDDIR}
+ cp -p /boot/cdboot ${dst}/boot || fail $? no_space "copying cdboot"
+ mkisofs -b boot/cdboot -no-emul-boot -J -r -ldots -l -L \
+ -o ${c_iso} ${dst}
+ )
+ fi
+
+ (cd ${BUILDDIR}
+ makefs -t ffs -o bsize=4096 -o fsize=512 \
+ -s ${blocks}k -f 50 ${c_img} ${dst}
+
+ ${c_label} -w -f `pwd`/${c_img} auto # write in a label
+ # copy partition c: into a: with some sed magic
+ ${c_label} -f `pwd`/${c_img} | sed -e '/ c:/{p;s/c:/a:/;}' | \
+ ${c_label} -R -f `pwd`/${c_img} /dev/stdin
+ ${c_label} -f `pwd`/${c_img}
+
+ ls -l ${c_img}
+ ${c_label} -f `pwd`/${c_img}
+ log "after disklabel"
+ )
+
+ echo "BUILDDIR ${BUILDDIR}"
+
+ # dump the primary and secondary boot
+ # XXX primary is 512 bytes
+ dd if=${c_boot1} of=${BUILDDIR}/${c_img} conv=notrunc 2>/dev/null
+ # XXX secondary starts after the 0x114 = dec 276 bytes of the label
+ # so we skip 276 from the source, and 276+512=788 from dst
+ # the old style blocks used 512 and 1024 respectively
+
+ dd if=${c_boot2} iseek=1 ibs=276 2> /dev/null | \
+ dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null
+ log "done disk image"
+ # XXX (log "Fixing permissions"; cd ${dst}; chown -R root *)
+ df -ik ${dst} | colrm 70 > .build.reply
+ # leave build stuff if verbose
+ [ ${o_verbose} -gt 0 ] && return
+
+ rm -rf ${BUILDDIR}/floppy.tree || true # cleanup
+ rm -rf ${dst}
+ rm ${BUILDDIR}/${c_fs}
+ # rm ${BUILDDIR}/kernel.gz
+}
+
+# This function creates variables which depend on the source tree in use:
+# SRC, l_usrtree, l_objtree
+# Optionally creates libraries, includes and the like (for cross compiles,
+# needs to be done once).
+
+set_build_parameters() {
+ if [ "${SRC}" = "/usr/src" ] ; then
+ l_usrtree=${USR:-/usr}
+ else
+ l_usrtree=${USR:-${SRC}/../usr}
+ fi
+ l_objtree=${l_usrtree}/obj-pico-${o_arch}
+
+ PICO_TREE=${PICO_TREE:-${SRC}/release/picobsd}
+ set `grep "#define[\t ]__FreeBSD_version" ${SRC}/sys/sys/param.h`
+ OSVERSION=$3
+ log "OSVERSION is ${OSVERSION}"
+
+ export MAKEOBJDIRPREFIX=${l_objtree}
+ export TARGET_ARCH=${o_arch} TARGET=${o_arch}
+ # XXX 20131001 see if CLANG fixes the build
+ export WITHOUT_CLANG_IS_CC=yes
+ export WITHOUT_CLANG_BOOTSTRAP=yes
+ export WITH_GCC=yes
+ export WITH_GCC_BOOTSTRAP=yes
+ export WITH_GNUCXX=yes
+ export WITHOUT_CLANG=yes
+ export WITHOUT_ICONV=yes
+ export WITHOUT_TESTS=yes
+
+ # XXX why change machine_arch ?
+ #-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m`
+ # export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers"
+ # XXX BINMAKE does not really exist anymore
+ eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\""
+ [ "$BINMAKE" = "" ] && \
+ eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V SUB_MAKE`\""
+
+ if [ "${o_init_src}" != "" ] ; then
+ create_includes_and_libraries2
+ else
+ eval export `cd ${SRC}; ${BINMAKE} -f Makefile.inc1 -V WMAKEENV`
+ fi
+
+ # if we have o_objdir, find where bin/ is
+ if [ ! -z "${o_objdir}" ] ; then
+ if [ -d ${o_objdir}/bin ] ; then
+ # fine
+ elif [ -d "${o_objdir}${SRC}/bin" ] ; then
+ o_objdir="${o_objdir}${SRC}"
+ log "Changing objdir to ${o_objdir}"
+ else
+ log "Cannot find objdir in ${o_objdir}, sorry"
+ o_objdir=""
+ fi
+ fi
+}
+
+#-------------------------------------------------------------------
+# Main entry of the script. Initialize variables, parse command line
+# arguments.
+
+
+set_defaults
+while [ true ]; do
+ log "Parsing $1"
+ case $1 in
+ -j)
+ o_par="-j $2"
+ shift
+ ;;
+
+ --par)
+ o_par="-j 8" # watch out, this might be too large
+ ;;
+
+ --src) # set the source path instead of /usr/src
+ SRC=`realpath $2`
+ shift
+ ;;
+
+ --init) # run a partial buildworld on the source tree
+ o_init_src="YES"
+ ;;
+
+ --arch) # override the target architecture
+ o_arch=$2
+ shift
+ ;;
+
+ --floppy_size) # image size
+ fd_size=$2
+ shift
+ ;;
+
+ --all_in_mfs)
+ o_all_in_mfs="yes"
+ ;;
+
+ --no_all_in_mfs)
+ o_all_in_mfs="no"
+ ;;
+
+ --modules) # also build kernel modules
+ o_do_modules="yes"
+ ;;
+
+ -n)
+ o_interactive="NO"
+ ;;
+
+ -clear|-clean|-c) # clean
+ o_clean="YES"
+ o_interactive="NO"
+ ;;
+
+ -v) # need -v -v to wait for user input
+ o_verbose=$((${o_verbose}+1)) # verbose level
+ o_tarv="v" # tar verbose flag
+ o_makeopts="-d l" # be verbose
+ ;;
+
+ --iso) # generate iso image
+ generate_iso="YES"
+ ;;
+
+ --cfg) # read additional config from this file
+ o_additional_config=`realpath $2`
+ shift
+ ;;
+
+ --objdir) # Place with results of a previous buildworld
+ # useful if you want to copy shared binaries and libs
+ o_objdir=`realpath $2`
+ shift
+ ;;
+
+ *)
+ break
+ ;;
+
+ esac
+ shift
+done
+
+set_build_parameters # things that depend on ${SRC}
+set_type $1 $2 # type and site, respectively
+
+[ "${o_interactive}" != "NO" ] && main_dialog
+
+if [ "${o_clean}" = "YES" ] ; then
+ clean_tree
+else
+ build_image
+ do_install
+fi
+final_cleanup
+exit 0
diff --git a/release/picobsd/floppy.tree/etc/fstab b/release/picobsd/floppy.tree/etc/fstab
new file mode 100644
index 0000000..cf9673a
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/fstab
@@ -0,0 +1,6 @@
+# $FreeBSD$
+proc /proc procfs rw 0 0
+/dev/fd0c /fd ufs rw,noauto 0 0
+/dev/ad0s1 /dos msdosfs rw,noauto 0 0
+/dev/ad0s1a /wd ufs rw,noauto 0 0
+/dev/acd0c /cdrom cd9660 ro,noauto 0 0
diff --git a/release/picobsd/floppy.tree/etc/hosts b/release/picobsd/floppy.tree/etc/hosts
new file mode 100644
index 0000000..d4f9c54
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/hosts
@@ -0,0 +1,17 @@
+# $FreeBSD$
+# This file contains ip <-> hostname mapping.
+# It is also used for autoconfiguration based on Ethernet address
+# and other things. The initial part is just a standard /etc/hosts
+# for local hosts that share this file.
+127.0.0.1 localhost localhost.mydomain.edu
+127.0.0.1 pico.mydomain.edu
+10.0.0.1 default
+192.168.254.1 vmrouter
+192.168.254.2 vm
+
+#ethertable This line starts the ethernet->hostname mapping
+# main_ether hostname
+# 00:12:34:56:78:9a myaddress
+# 00:bd:* vm
+# default default
+
diff --git a/release/picobsd/floppy.tree/etc/inetd.conf b/release/picobsd/floppy.tree/etc/inetd.conf
new file mode 100644
index 0000000..c7c50de
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/inetd.conf
@@ -0,0 +1,21 @@
+#
+# Internet server configuration database
+#
+# @(#)inetd.conf 5.4 (Berkeley) 6/30/90
+#
+telnet stream tcp nowait root /usr/libexec/telnetd telnetd
+#
+# "Small servers" -- used to be standard on, but we're more conservative
+# about things due to Internet security concerns. Only turn on what you
+# need.
+#
+#daytime stream tcp nowait root internal
+#daytime dgram udp wait root internal
+#time stream tcp nowait root internal
+#time dgram udp wait root internal
+#echo stream tcp nowait root internal
+#echo dgram udp wait root internal
+#discard stream tcp nowait root internal
+#discard dgram udp wait root internal
+#chargen stream tcp nowait root internal
+#chargen dgram udp wait root internal
diff --git a/release/picobsd/floppy.tree/etc/master.passwd b/release/picobsd/floppy.tree/etc/master.passwd
new file mode 100644
index 0000000..ce14381
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/master.passwd
@@ -0,0 +1,11 @@
+# $FreeBSD$
+root:$1$xOOaGnKU$U9QdsCI40XXcCUMBN.7Az.:0:0::0:0:Charlie &:/root:/bin/sh
+toor:*:0:0::0:0:Bourne-again Superuser:/root:
+daemon:*:1:1::0:0:Owner of many system processes:/root:/nonexistent
+operator:*:2:20::0:0:System &:/usr/guest/operator:/bin/csh
+bin:*:3:7::0:0:Binaries Commands and Source,,,:/:/nonexistent
+tty:*:4:65533::0:0:Tty Sandbox:/:/nonexistent
+sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/usr/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/nonexistent
+_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
+user:*:1002:1002:Sample User:0:0:user:/home/user:/bin/sh
diff --git a/release/picobsd/floppy.tree/etc/networks b/release/picobsd/floppy.tree/etc/networks
new file mode 100644
index 0000000..c32b68b
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/networks
@@ -0,0 +1,5 @@
+# Sample networks file. Picobsd scripts will look for entries of the form
+# hostname-netmask 255.255.255.0
+# when searching for masks
+vm-netmask 255.255.255.0
+
diff --git a/release/picobsd/floppy.tree/etc/ppp/ppp.conf b/release/picobsd/floppy.tree/etc/ppp/ppp.conf
new file mode 100644
index 0000000..e9ddabf
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/ppp/ppp.conf
@@ -0,0 +1,9 @@
+# $FreeBSD$
+# PPP Sample Configuration File
+# Written by Toshiharu OHNO
+default:
+ set device /dev/cuau1
+ set speed 38400
+ disable lqr
+ deny lqr
+ set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \"\" ATE1Q0 OK-AT-OK \\dATDT\\T TIMEOUT 40 CONNECT"
diff --git a/release/picobsd/floppy.tree/etc/ppp/ppp.deny b/release/picobsd/floppy.tree/etc/ppp/ppp.deny
new file mode 100644
index 0000000..51e1e9b
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/ppp/ppp.deny
@@ -0,0 +1,15 @@
+# list of users disallowed any pppd access via 'system
+# password login'.
+# read by pppd(8).
+root
+toor
+daemon
+operator
+bin
+games
+news
+man
+ftp
+uucp
+xten
+ingres
diff --git a/release/picobsd/floppy.tree/etc/ppp/ppp.linkup b/release/picobsd/floppy.tree/etc/ppp/ppp.linkup
new file mode 100644
index 0000000..05107c6
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/ppp/ppp.linkup
@@ -0,0 +1,10 @@
+# Example of ppp.linkup file
+#
+iij-demand:
+ delete ALL
+ add 0 0 HISADDR
+#
+# Otherwise, simply add peer as default gateway.
+#
+MYADDR:
+ add 0 0 HISADDR
diff --git a/release/picobsd/floppy.tree/etc/ppp/ppp.secret.sample b/release/picobsd/floppy.tree/etc/ppp/ppp.secret.sample
new file mode 100644
index 0000000..bfaab76
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/ppp/ppp.secret.sample
@@ -0,0 +1,23 @@
+##################################################
+#
+# Example of ppp.secret file
+#
+# This file is used to authenticate incoming connections.
+# You must ``enable'' either PAP or CHAP in your ppp.conf file.
+# The peer may then use any of the Authname/Authkey pairs listed.
+# If an IP address is given, it will be assigned to the peer.
+#
+# If an entry exists for your local machine (as given by the
+# ``hostname -s'' command), the password specified will be
+# required for all server socket connections. Refer to the ppp(8)
+# and pppctl(8) man pages for further details.
+#
+# $FreeBSD$
+#
+##################################################
+
+# Authname Authkey Peer's IP address
+
+oscar OurSecretKey 192.244.184.34/24
+BigBird X4dWg9327 192.244.184.33/32
+tama localPasswdForControl
diff --git a/release/picobsd/floppy.tree/etc/profile b/release/picobsd/floppy.tree/etc/profile
new file mode 100644
index 0000000..c0c9de4
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/profile
@@ -0,0 +1,5 @@
+# System-wide .profile file for sh(1).
+BLOCKSIZE=K; export BLOCKSIZE
+PATH=/stand:.; export PATH
+EDITOR=ee; export EDITOR
+set -E
diff --git a/release/picobsd/floppy.tree/etc/rc.conf b/release/picobsd/floppy.tree/etc/rc.conf
new file mode 100644
index 0000000..d9d4bbf
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/rc.conf
@@ -0,0 +1,10 @@
+# Sample rc.conf file for PicoBSD
+# you should mostly set variables here, see rc.conf.defaults.
+
+tcp_extensions=YES # enable rfc1323 and rfc1644
+
+case ${hostname} in
+*)
+ echo "processing rc.conf for ${hostname}"
+ ;;
+esac
diff --git a/release/picobsd/floppy.tree/etc/rc.conf.defaults b/release/picobsd/floppy.tree/etc/rc.conf.defaults
new file mode 100644
index 0000000..8b8bdf3
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/rc.conf.defaults
@@ -0,0 +1,184 @@
+#!/bin/sh
+# $FreeBSD$
+#
+# rc.conf for picobsd. This is sourced from /etc/rc1, and is supposed to
+# contain only shell functions that are used later in /etc/rc1.
+
+# set default values for variables. Boolean values should be either
+# NO or YES -- other values are not guaranteed to work.
+
+rc_conf_set_defaults() {
+hostname="" # Should not need to set it
+syslogd_enable="NO"
+pccard_enable="NO"
+swapfile="" # name of swapfile if aux swapfile desired.
+
+# Network interface configurations: ifconfig_${interface}[_aliasNN]
+ifconfig_lo0="inet 127.0.0.1" # default loopback device configuration.
+#ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry.
+
+### Network daemons options: they are only run if present.
+sshd_enable="YES" # if present...
+inetd_enable="YES" # Run the network daemon dispatcher (or NO)
+inetd_flags="" # Optional flags to inetd
+snmpd_enable="NO" # Run the SNMP daemon (or NO)
+snmpd_flags="-C -c /etc/snmpd.conf" # Optional flags to snmpd
+
+### Network routing options: ###
+defaultrouter="NO" # Set to default gateway (or NO).
+static_routes="" # Set to static route list (or leave empty).
+gateway_enable="NO" # Set to YES if this host will be a gateway.
+arpproxy_all="" # replaces obsolete kernel option ARP_PROXYALL.
+default_mask="0xffffff00"
+
+### Other network features
+firewall_enable="NO"
+firewall_quiet="NO" # be quiet if set.
+firewall_type="" # Standard types or absolute pathname.
+tcp_extensions="NO" # Allow RFC1323 & RFC1644 extensions (or NO).
+
+### Overrides for some files in /etc. Leave empty if no override,
+### set variable (remember to use multiple lines) to override content.
+
+host_conf="hosts
+bind"
+resolv_conf=""
+}
+
+# Try to identify the system by using the MAC address and name of the
+# first ethernet interface, made available as $main_eth $main_if
+find_system_id() {
+ main_ether=""
+ for main_if in `ifconfig -l` ; do
+ set `ifconfig $main_if`
+ while [ "$1" != "" ] ; do
+ if [ $1 = "ether" ] ; then
+ main_ether=$2
+ break 2
+ else
+ shift
+ fi
+ done
+ done
+}
+
+# the following lets the user specify a name and ip for his system
+read_address() {
+ echo "Please enter a hostname and IP address for your system $main_ether"
+ read hostname the_ip
+ if [ "${hostname}" != "" ] ; then
+ echo "# $main_ether $hostname" >> /etc/hosts
+ echo "$the_ip $hostname" >> /etc/hosts
+ else
+ hostname=default
+ fi
+}
+
+# set "ether" using $1 (interface name) as search key
+get_ether() {
+ local key
+ key=$1
+ ether=""
+ set `ifconfig ${key}`
+ while [ "$1" != "" ] ; do
+ if [ "$1" = "ether" ] ; then
+ ether=$2
+ break
+ else
+ shift
+ fi
+ done
+}
+
+# read content from /etc/hosts into a couple of arrays
+# (needed later in fetch_hostname)
+read_hosts() {
+ local i a b c key junk
+ i=""
+ while read a b c junk ; do
+ if [ "$a" = "#ethertable" ] ; then
+ i=0
+ elif [ "$i" != "" -a "$a" = "#" -a "$b" != "" ] ; then
+ eval eth_${i}=$b
+ eval eth_host_${i}=$c
+ i=$(($i+1))
+ fi
+ done < /etc/hosts
+}
+
+# set ${hostname} using $1 (MAC address) as search key in /etc/hosts
+# Returns empty value if $1 is empty
+fetch_hostname() {
+ local i b key
+ hostname=""
+ [ "$1" = "" ] && return
+ key=$1
+ i=0
+ b="x"
+ [ "${eth_0}" = "" ] && read_hosts # fill cache.
+ while [ "$b" != "" -a "${hostname}" = "" ] ; do
+ eval b=\${eth_${i}}
+ case X${key} in
+ X${b} ) # so we can use wildcards
+ eval hostname=\${eth_host_${i}}
+ break
+ ;;
+ esac
+ i=$(($i+1))
+ done
+ echo "fetch_hostname for <${key}> returns <${hostname}>"
+}
+
+# sets "mask" using $1 (netmask name) as the search key in /etc/networks
+fetch_mask() {
+ local a b key junk
+ key=$1 # search key, typically hostname-netmask
+ mask=""
+ while read a b junk; do # key mask otherstuff
+ case X${key} in
+ X${a} ) # The X is so we can use wildcards in ${a}
+ mask=$b
+ break
+ ;;
+ esac
+ done < /etc/networks
+ if [ "${mask}" = "" ] ; then
+ mask=${default_mask}
+ fi
+ echo "fetch_mask for <${key}> returns <${mask}>"
+}
+
+# set hostname, and ifconfig_${main_if} (whose MAC is ${main_ether})
+# if not found, read from console
+set_main_interface() {
+ if [ -z "${hostname}" ] ; then
+ if [ -z "${main_ether}" ] ; then
+ echo "No ethernets found, using localhost"
+ hostname=localhost
+ return
+ fi
+ fetch_hostname ${main_ether}
+ fi
+
+ [ -z "${hostname}" -o "${hostname}" = "." ] && read_address
+
+ fetch_mask ${hostname}-netmask
+
+ eval ifconfig_${main_if}=\" \${hostname} netmask \${mask}\"
+ network_interfaces=`ifconfig -l`
+}
+
+# set ifconfig_${interface} for all other interfaces
+set_all_interfaces() {
+ local i ether hostname mask
+
+ for i in `ifconfig -l` ; do
+ if [ "$i" != "${main_if}" ] ; then
+ get_ether $i
+ fetch_hostname ${ether}
+ fetch_mask ${hostname}-netmask
+ [ -n "${ether}" -a -n "${hostname}" ] && \
+ eval ifconfig_${i}=\" \${hostname} netmask \${mask}\"
+ fi
+ done
+}
diff --git a/release/picobsd/floppy.tree/etc/rc.firewall b/release/picobsd/floppy.tree/etc/rc.firewall
new file mode 100644
index 0000000..408fe60
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/rc.firewall
@@ -0,0 +1,142 @@
+# $FreeBSD$
+
+# Setup system for firewall service, with some sample configurations.
+# Select one using ${firewall_type} which you can set in /etc/rc.conf.local.
+#
+# If you override this file with your own copy, you can use ${hostname}
+# as the key for the case statement. On entry, the firewall will be flushed
+# and $fwcmd will point to the appropriate command (usually /sbin/ipfw)
+#
+# Sample configurations are:
+# open - will allow anyone in
+# client - will try to protect just this machine (should be customized).
+# simple - will try to protect a whole network (should be customized).
+# closed - totally disables IP services except via lo0 interface
+# UNKNOWN - disables the loading of firewall rules.
+# filename - will load the rules in the given filename (full path required)
+#
+
+############
+# Only in rare cases do you want to change these rules
+$fwcmd add 1000 pass all from any to any via lo0
+$fwcmd add 1010 deny all from 127.0.0.0/8 to 127.0.0.0/8
+
+
+# Prototype setups.
+case "${firewall_type}" in
+open|OPEN)
+ $fwcmd add 65000 pass all from any to any
+ ;;
+
+client)
+
+ ############
+ # This is a prototype setup that will protect your system somewhat against
+ # people from outside your own network.
+ ############
+
+ # set these to your network and netmask and ip
+ net="192.168.4.0"
+ mask="255.255.255.0"
+ ip="192.168.4.17"
+
+ # Allow any traffic to or from my own net.
+ $fwcmd add pass all from ${ip} to ${net}:${mask}
+ $fwcmd add pass all from ${net}:${mask} to ${ip}
+
+ # Allow TCP through if setup succeeded
+ $fwcmd add pass tcp from any to any established
+
+ # Allow setup of incoming email
+ $fwcmd add pass tcp from any to ${ip} 25 setup
+
+ # Allow setup of outgoing TCP connections only
+ $fwcmd add pass tcp from ${ip} to any setup
+
+ # Disallow setup of all other TCP connections
+ $fwcmd add deny tcp from any to any setup
+
+ # Allow DNS queries out in the world
+ $fwcmd add pass udp from any 53 to ${ip}
+ $fwcmd add pass udp from ${ip} to any 53
+
+ # Allow NTP queries out in the world
+ $fwcmd add pass udp from any 123 to ${ip}
+ $fwcmd add pass udp from ${ip} to any 123
+
+ # Everything else is denied as default.
+ $fwcmd add 65000 deny all from any to any
+ ;;
+
+simple)
+
+ ############
+ # This is a prototype setup for a simple firewall. Configure this machine
+ # as a named server and ntp server, and point all the machines on the inside
+ # at this machine for those services.
+ ############
+
+ # set these to your outside interface network and netmask and ip
+ oif="ed0"
+ onet="192.168.4.0"
+ omask="255.255.255.0"
+ oip="192.168.4.17"
+
+ # set these to your inside interface network and netmask and ip
+ iif="ed1"
+ inet="192.168.3.0"
+ imask="255.255.255.0"
+ iip="192.168.3.17"
+
+ # Stop spoofing
+ $fwcmd add deny all from ${inet}:${imask} to any in via ${oif}
+ $fwcmd add deny all from ${onet}:${omask} to any in via ${iif}
+
+ # Stop RFC1918 nets on the outside interface
+ $fwcmd add deny all from 192.168.0.0:255.255.0.0 to any via ${oif}
+ $fwcmd add deny all from 172.16.0.0:255.240.0.0 to any via ${oif}
+ $fwcmd add deny all from 10.0.0.0:255.0.0.0 to any via ${oif}
+
+ # Allow TCP through if setup succeeded
+ $fwcmd add pass tcp from any to any established
+
+ # Allow setup of incoming email
+ $fwcmd add pass tcp from any to ${oip} 25 setup
+
+ # Allow access to our DNS
+ $fwcmd add pass tcp from any to ${oip} 53 setup
+
+ # Allow access to our WWW
+ $fwcmd add pass tcp from any to ${oip} 80 setup
+
+ # Reject&Log all setup of incoming connections from the outside
+ $fwcmd add deny log tcp from any to any in via ${oif} setup
+
+ # Allow setup of any other TCP connection
+ $fwcmd add pass tcp from any to any setup
+
+ # Allow DNS queries out in the world
+ $fwcmd add pass udp from any 53 to ${oip}
+ $fwcmd add pass udp from ${oip} to any 53
+
+ # Allow NTP queries out in the world
+ $fwcmd add pass udp from any 123 to ${oip}
+ $fwcmd add pass udp from ${oip} to any 123
+
+ # Everything else is denied as default.
+ $fwcmd add 65000 deny all from any to any
+ ;;
+
+UNKNOWN|"")
+ echo "WARNING: firewall rules not loaded."
+ ;;
+
+*) # an absolute pathname ?
+ if [ -f "${firewall_type}" ] ; then
+ $fwcmd ${firewall_type}
+ else
+ echo "WARNING: firewall config script (${firewall_type}) not found,"
+ echo " firewall rules not loaded."
+ fi
+ ;;
+esac
diff --git a/release/picobsd/floppy.tree/etc/rc1 b/release/picobsd/floppy.tree/etc/rc1
new file mode 100644
index 0000000..a4a0798
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/rc1
@@ -0,0 +1,63 @@
+#!/bin/sh
+# $FreeBSD$
+### rc1, next stage 'rc' for PicoBSD -- THIS IS NOT THE NORMAL /etc/rc
+
+. /etc/rc.conf.defaults # Load default procedures
+rc_conf_set_defaults # Assign default values to variables.
+find_system_id # Set $main_eth $main_if
+set_main_interface # Set ${hostname} and ${ifconfig_${main_if}}
+set_all_interfaces # Set ${ifconfig_${if}} for other interfaces.
+
+# Now process local configurations if present. ${hostname} should be set now,
+# so rc.conf[.local] can make use of a case statement to set per-host things.
+
+[ -f /etc/rc.conf ] && . /etc/rc.conf
+[ -f /etc/rc.conf.local ] && . /etc/rc.conf.local
+
+### Now use some variables to override files in /etc ###
+( IFS=''
+[ -n "${host_conf}" ] && echo ${host_conf} > /etc/host.conf
+[ -n "${resolv_conf}" ] && echo ${resolv_conf} > /etc/resolv.conf
+[ -n "${rc_local}" ] && echo ${rc_local} > /etc/rc.local
+unset IFS
+)
+
+rm -f /var/run/*
+if [ "x$swapfile" != "xNO" -a -w "$swapfile" -a -b /dev/vn0b ]; then
+ echo "Adding $swapfile as additional swap."
+ vnconfig /dev/vn0b $swapfile && swapon /dev/vn0b
+else
+ echo "No swap partition available!"
+fi
+# configure serial devices
+[ -f /etc/rc.serial ] && . /etc/rc.serial
+
+# start up the initial network configuration.
+if [ -f /etc/rc.network ]; then
+ . /etc/rc.network
+ network_pass1
+fi
+mount -a -t nfs
+# clean up left-over files
+(cd /var/run && { cp /dev/null utmp; chmod 644 utmp; })
+
+[ -n "$network_pass1_done" ] && network_pass2
+[ -n "$network_pass2_done" ] && network_pass3
+
+pwd_mkdb -p ./master.passwd
+
+[ -f /etc/syslog.conf -a -f /stand/syslogd ] && \
+ { echo "Starting syslogd."; syslogd ${syslogd_flags} ; }
+
+[ "${inetd_enable}" = "YES" -a -f /stand/inetd ] && \
+ { echo "Starting inetd."; inetd ${inetd_flags} ; }
+
+if [ "${sshd_enable}" = "YES" -a -f /usr/sbin/sshd ] ; then
+ echo "Starting sshd..."
+ chmod 600 /etc/ssh_host*key
+ /usr/sbin/sshd -f /etc/sshd_config
+fi
+
+echo ''
+cat /etc/motd
+exit 0
diff --git a/release/picobsd/floppy.tree/etc/snmpd.conf b/release/picobsd/floppy.tree/etc/snmpd.conf
new file mode 100644
index 0000000..29400df
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/snmpd.conf
@@ -0,0 +1,58 @@
+# load average checks
+
+# load [1MAX=DEFMAXLOADAVE] [5MAX=DEFMAXLOADAVE] [15MAX=DEFMAXLOADAVE]
+#
+# 1MAX: If the 1 minute load average is above this limit at query
+# time, the errorFlag will be set.
+# 5MAX: Similar, but for 5 min average.
+# 15MAX: Similar, but for 15 min average.
+
+# Check for loads:
+load 12 14 14
+
+# % snmpwalk -v 1 localhost public .1.3.6.1.4.1.2021.10
+
+# snmp agent errors
+
+# % snmpwalk -v 1 localhost public .1.3.6.1.4.1.2021.101
+
+# snmp version mib
+
+# % snmpwalk -v 1 localhost public .1.3.6.1.4.1.2021.100
+
+# System contact information
+
+syslocation PicoBSD
+syscontact root <root@pico>
+
+# Setting up the access control lists to the agent
+
+# sec.name source community
+com2sec local localhost private
+com2sec public default public
+
+# sec.model sec.name
+group local any local
+group public any public
+
+# incl/excl subtree mask
+view all included .1 80
+view system included system fe
+view mib2 included .iso.org.dod.internet.mgmt.mib-2 fc
+
+# context sec.model sec.level prefix read write not
+access public "" any noauth 0 system none none
+access local "" any noauth 0 all all all
+
+# If you want to get back to the functionality of previous versions,
+# where the public community could read anything from anywhere and the
+# private community could write anything from anywhere, use these
+# lines instead:
+#
+# com2sec public default public
+# com2sec private default private
+# group public any public
+# group private any private
+# view all included .1 80
+# access public "" any noauth 0 all none none
+# access private "" any noauth 0 all all none
diff --git a/release/picobsd/floppy.tree/etc/ssh/sshd_config b/release/picobsd/floppy.tree/etc/ssh/sshd_config
new file mode 100644
index 0000000..4529c41
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/ssh/sshd_config
@@ -0,0 +1,28 @@
+# $FreeBSD$
+# minimal config for sshd on picobsd
+Port 22
+ListenAddress 0.0.0.0
+HostKey /etc/ssh_host_key
+#RandomSeed /etc/ssh_random_seed
+ServerKeyBits 768
+LoginGraceTime 600
+KeyRegenerationInterval 3600
+PermitRootLogin yes
+IgnoreRhosts no
+StrictModes yes
+X11Forwarding no
+X11DisplayOffset 10
+PrintMotd yes
+KeepAlive yes
+SyslogFacility AUTH
+RhostsRSAAuthentication yes
+RSAAuthentication yes
+PasswordAuthentication yes
+PermitEmptyPasswords no
+UseLogin no
+# CheckMail no
+# PidFile /u/zappa/.ssh/pid
+# AllowHosts *.our.com friend.other.com
+# DenyHosts lowsecurity.theirs.com *.evil.org evil.org
+# Umask 022
+# SilentDeny yes
diff --git a/release/picobsd/floppy.tree/etc/ttys b/release/picobsd/floppy.tree/etc/ttys
new file mode 100644
index 0000000..e0ff480
--- /dev/null
+++ b/release/picobsd/floppy.tree/etc/ttys
@@ -0,0 +1,36 @@
+#
+# @(#)ttys 5.1 (Berkeley) 4/17/89
+#
+# $FreeBSD$
+#
+# name getty type status comments
+#
+# This entry needed for asking password when init goes to single-user mode
+# If you want to be asked for password, change "secure" to "insecure" here
+#console none unknown off secure
+vga none xterm off secure
+#
+ttyv0 "/usr/libexec/getty Pc" xterm on secure
+# Virtual terminals
+ttyv1 "/usr/libexec/getty Pc" xterm on secure
+ttyv2 "/usr/libexec/getty Pc" xterm on secure
+ttyv3 "/usr/libexec/getty Pc" xterm on secure
+ttyv4 "/usr/libexec/getty Pc" xterm on secure
+ttyv5 "/usr/libexec/getty Pc" xterm on secure
+ttyv6 "/usr/libexec/getty Pc" xterm on secure
+ttyv7 "/usr/libexec/getty Pc" xterm on secure
+#ttyv8 "/usr/libexec/getty Pc" xterm on secure
+#ttyv9 "/usr/libexec/getty Pc" xterm on secure
+# Pseudo terminals
+ttyp0 none network secure
+ttyp1 none network secure
+ttyp2 none network secure
+ttyp3 none network secure
+ttyp4 none network secure
+ttyp5 none network secure
+ttyp6 none network secure
+ttyp7 none network secure
+ttyp8 none network secure
+ttyp9 none network secure
+ttyu0 "/usr/libexec/getty 3wire" dialup on secure
+ttyu1 "/usr/libexec/getty 3wire" dialup on secure
diff --git a/release/picobsd/floppy.tree/sbin/dhclient-script b/release/picobsd/floppy.tree/sbin/dhclient-script
new file mode 100755
index 0000000..c457bf4
--- /dev/null
+++ b/release/picobsd/floppy.tree/sbin/dhclient-script
@@ -0,0 +1,384 @@
+#!/bin/sh
+#
+# $OpenBSD: dhclient-script,v 1.6 2004/05/06 18:22:41 claudio Exp $
+# $FreeBSD$
+#
+# Copyright (c) 2003 Kenneth R Westerback <krw@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+
+ARP=/usr/sbin/arp
+HOSTNAME=/bin/hostname
+IFCONFIG='/sbin/ifconfig -n'
+
+LOCALHOST=127.0.0.1
+
+if [ -x /usr/bin/logger ]; then
+ LOGGER="/usr/bin/logger -s -p user.notice -t dhclient"
+else
+ LOGGER=echo
+fi
+
+#
+# Helper functions that implement common actions.
+#
+
+check_hostname() {
+ current_hostname=`$HOSTNAME`
+ if [ -z "$current_hostname" ]; then
+ $LOGGER "New Hostname ($interface): $new_host_name"
+ $HOSTNAME $new_host_name
+ elif [ "$current_hostname" = "$old_host_name" -a \
+ "$new_host_name" != "$old_host_name" ]; then
+ $LOGGER "New Hostname ($interface): $new_host_name"
+ $HOSTNAME $new_host_name
+ fi
+}
+
+arp_flush() {
+ arp -an -i $interface | \
+ sed -n -e 's/^.*(\(.*\)) at .*$/arp -d \1/p' | \
+ sh >/dev/null 2>&1
+}
+
+delete_old_address() {
+ eval "$IFCONFIG $interface inet -alias $old_ip_address $medium"
+}
+
+add_new_address() {
+ eval "$IFCONFIG $interface \
+ inet $new_ip_address \
+ netmask $new_subnet_mask \
+ broadcast $new_broadcast_address \
+ $medium"
+
+ $LOGGER "New IP Address ($interface): $new_ip_address"
+ $LOGGER "New Subnet Mask ($interface): $new_subnet_mask"
+ $LOGGER "New Broadcast Address ($interface): $new_broadcast_address"
+ $LOGGER "New Routers ($interface): $new_routers"
+}
+
+delete_old_alias() {
+ if [ -n "$alias_ip_address" ]; then
+ $IFCONFIG $interface inet -alias $alias_ip_address > /dev/null 2>&1
+ #route delete $alias_ip_address $LOCALHOST > /dev/null 2>&1
+ fi
+}
+
+add_new_alias() {
+ if [ -n "$alias_ip_address" ]; then
+ $IFCONFIG $interface inet alias $alias_ip_address netmask \
+ $alias_subnet_mask
+ #route add $alias_ip_address $LOCALHOST
+ fi
+}
+
+fill_classless_routes() {
+ set $1
+ while [ $# -ge 5 ]; do
+ if [ $1 -eq 0 ]; then
+ route="default"
+ elif [ $1 -le 8 ]; then
+ route="$2.0.0.0/$1"
+ shift
+ elif [ $1 -le 16 ]; then
+ route="$2.$3.0.0/$1"
+ shift; shift
+ elif [ $1 -le 24 ]; then
+ route="$2.$3.$4.0/$1"
+ shift; shift; shift
+ else
+ route="$2.$3.$4.$5/$1"
+ shift; shift; shift; shift
+ fi
+ shift
+ router="$1.$2.$3.$4"
+ classless_routes="$classless_routes $route $router"
+ shift; shift; shift; shift
+ done
+}
+
+delete_old_routes() {
+ #route delete "$old_ip_address" $LOCALHOST >/dev/null 2>&1
+ if [ -n "$old_classless_routes" ]; then
+ fill_classless_routes "$old_classless_routes"
+ set $classless_routes
+ while [ $# -gt 1 ]; do
+ route delete "$1" "$2"
+ shift; shift
+ done
+ return 0;
+ fi
+
+ # If we supported multiple default routes, we'd be removing each
+ # one here. We don't so just delete the default route if it's
+ # through our interface.
+ if is_default_interface; then
+ route delete default >/dev/null 2>&1
+ fi
+
+ if [ -n "$old_static_routes" ]; then
+ set $old_static_routes
+ while [ $# -gt 1 ]; do
+ route delete "$1" "$2"
+ shift; shift
+ done
+ fi
+
+ arp_flush
+}
+
+add_new_routes() {
+ #route add $new_ip_address $LOCALHOST >/dev/null 2>&1
+
+ # RFC 3442: If the DHCP server returns both a Classless Static
+ # Routes option and a Router option, the DHCP client MUST ignore
+ # the Router option.
+ #
+ # DHCP clients that support this option (Classless Static Routes)
+ # MUST NOT install the routes specified in the Static Routes
+ # option (option code 33) if both a Static Routes option and the
+ # Classless Static Routes option are provided.
+
+ if [ -n "$new_classless_routes" ]; then
+ fill_classless_routes "$new_classless_routes"
+ $LOGGER "New Classless Static Routes ($interface): $classless_routes"
+ set $classless_routes
+ while [ $# -gt 1 ]; do
+ if [ "0.0.0.0" = "$2" ]; then
+ route add "$1" -iface "$interface"
+ else
+ route add "$1" "$2"
+ fi
+ shift; shift
+ done
+ return
+ fi
+
+ for router in $new_routers; do
+ if is_default_interface; then
+
+ if [ "$new_ip_address" = "$router" ]; then
+ route add default -iface $router >/dev/null 2>&1
+ else
+ route add default $router >/dev/null 2>&1
+ fi
+ fi
+ # 2nd and subsequent default routers error out, so explicitly
+ # stop processing the list after the first one.
+ break
+ done
+
+ if [ -n "$new_static_routes" ]; then
+ $LOGGER "New Static Routes ($interface): $new_static_routes"
+ set $new_static_routes
+ while [ $# -gt 1 ]; do
+ route add $1 $2
+ shift; shift
+ done
+ fi
+}
+
+add_new_resolv_conf() {
+ # XXX Old code did not create/update resolv.conf unless both
+ # $new_domain_name and $new_domain_name_servers were provided. PR
+ # #3135 reported some ISP's only provide $new_domain_name_servers and
+ # thus broke the script. This code creates the resolv.conf if either
+ # are provided.
+
+ local tmpres=/var/run/resolv.conf.${interface}
+ rm -f $tmpres
+
+ if [ -n "$new_domain_name" ]; then
+ echo "search $new_domain_name" >>$tmpres
+ fi
+
+ if [ -n "$new_domain_name_servers" ]; then
+ for nameserver in $new_domain_name_servers; do
+ echo "nameserver $nameserver" >>$tmpres
+ done
+ fi
+
+ if [ -f $tmpres ]; then
+ if [ -f /etc/resolv.conf.tail ]; then
+ cat /etc/resolv.conf.tail >>$tmpres
+ fi
+
+ # When resolv.conf is not changed actually, we don't
+ # need to update it.
+ # If /usr is not mounted yet, we cannot use cmp, then
+ # the following test fails. In such case, we simply
+ # ignore an error and do update resolv.conf.
+ if cmp -s $tmpres /etc/resolv.conf; then
+ rm -f $tmpres
+ return 0
+ fi 2>/dev/null
+
+ # In case (e.g. during OpenBSD installs) /etc/resolv.conf
+ # is a symbolic link, take care to preserve the link and write
+ # the new data in the correct location.
+
+ if [ -f /etc/resolv.conf ]; then
+ cat /etc/resolv.conf > /etc/resolv.conf.save
+ fi
+ cat $tmpres > /etc/resolv.conf
+ rm -f $tmpres
+
+ # Try to ensure correct ownership and permissions.
+ chown -RL root:wheel /etc/resolv.conf
+ chmod -RL 644 /etc/resolv.conf
+
+ return 0
+ fi
+
+ return 1
+}
+
+# Must be used on exit. Invokes the local dhcp client exit hooks, if any.
+exit_with_hooks() {
+ exit_status=$1
+ if [ -f /etc/dhclient-exit-hooks ]; then
+ . /etc/dhclient-exit-hooks
+ fi
+ # probably should do something with exit status of the local script
+ exit $exit_status
+}
+
+# Get the interface with the current ipv4 default route on it using only
+# commands that are available prior to /usr being mounted.
+is_default_interface()
+{
+ routeget="`route -n get -inet default`"
+ oldifs="$IFS"
+ IFS="
+"
+ defif=
+ for line in $routeget ; do
+ case $line in
+ *interface:*)
+ defif=${line##*: }
+ ;;
+ esac
+ done
+ IFS=${oldifs}
+
+ if [ -z "$defif" -o "$defif" = "$interface" ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+#
+# Start of active code.
+#
+
+# Invoke the local dhcp client enter hooks, if they exist.
+if [ -f /etc/dhclient-enter-hooks ]; then
+ exit_status=0
+ . /etc/dhclient-enter-hooks
+ # allow the local script to abort processing of this state
+ # local script must set exit_status variable to nonzero.
+ if [ $exit_status -ne 0 ]; then
+ exit $exit_status
+ fi
+fi
+
+case $reason in
+MEDIUM)
+ eval "$IFCONFIG $interface $medium"
+ eval "$IFCONFIG $interface inet -alias 0.0.0.0 $medium" >/dev/null 2>&1
+ sleep 1
+ ;;
+
+PREINIT)
+ delete_old_alias
+ $IFCONFIG $interface inet alias 0.0.0.0 netmask 0.0.0.0 broadcast 255.255.255.255 up
+ ;;
+
+ARPCHECK|ARPSEND)
+ ;;
+
+BOUND|RENEW|REBIND|REBOOT)
+ check_hostname
+ if [ -n "$old_ip_address" ]; then
+ if [ "$old_ip_address" != "$alias_ip_address" ]; then
+ delete_old_alias
+ fi
+ if [ "$old_ip_address" != "$new_ip_address" ]; then
+ delete_old_address
+ delete_old_routes
+ fi
+ fi
+ if [ "$reason" = BOUND ] || \
+ [ "$reason" = REBOOT ] || \
+ [ -z "$old_ip_address" ] || \
+ [ "$old_ip_address" != "$new_ip_address" ]; then
+ add_new_address
+ add_new_routes
+ fi
+ if [ "$new_ip_address" != "$alias_ip_address" ]; then
+ add_new_alias
+ fi
+ if is_default_interface; then
+ add_new_resolv_conf
+ fi
+ ;;
+
+EXPIRE|FAIL)
+ delete_old_alias
+ if [ -n "$old_ip_address" ]; then
+ delete_old_address
+ delete_old_routes
+ fi
+ if [ -x $ARP ]; then
+ $ARP -d -a -i $interface
+ fi
+ # XXX Why add alias we just deleted above?
+ add_new_alias
+ if is_default_interface; then
+ if [ -f /etc/resolv.conf.save ]; then
+ cat /etc/resolv.conf.save > /etc/resolv.conf
+ fi
+ fi
+ ;;
+
+TIMEOUT)
+ delete_old_alias
+ add_new_address
+ sleep 1
+ if [ -n "$new_routers" ]; then
+ $LOGGER "New Routers ($interface): $new_routers"
+ set "$new_routers"
+ if ping -q -c 1 -t 1 "$1"; then
+ if [ "$new_ip_address" != "$alias_ip_address" ]; then
+ add_new_alias
+ fi
+ add_new_routes
+ if ! is_default_interface; then
+ exit_with_hooks 0
+ fi
+ if add_new_resolv_conf; then
+ exit_with_hooks 0
+ fi
+ fi
+ fi
+ eval "$IFCONFIG $interface inet -alias $new_ip_address $medium"
+ delete_old_routes
+ exit_with_hooks 1
+ ;;
+esac
+
+exit_with_hooks 0
diff --git a/release/picobsd/mfs_tree/etc/disktab b/release/picobsd/mfs_tree/etc/disktab
new file mode 100644
index 0000000..f5b0097
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/disktab
@@ -0,0 +1,85 @@
+# $FreeBSD$
+# Floppy formats:
+#
+# To make a filesystem on a floppy:
+# fdformat [-f <size>] fd<drive>[.<size>]
+# disklabel -B -r -w fd<drive>[.<size>] fd<size>
+# newfs <opts> fd<drive>[.<size>]
+#
+# with <opts>:
+# -t 2 - two heads
+# -u 9|15|18 - sectors per track
+# (using the default value of 1/4096 is not much useful for floppies)
+# -l 1 - interleave 1 (for most floppies)
+# -i 65536 - bytes of data per i-node
+# (the default -i value will render you with a floppy wasting way
+# too much space in i-node areas)
+
+fd360:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#40:\
+ :pa#720:oa#0:ba#4096:fa#512:\
+ :pb#720:ob#0:bb#4096:fb#512:\
+ :pc#720:oc#0:bc#4096:fc#512:
+
+fd720:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#80:\
+ :pa#1440:oa#0:ba#4096:fa#512:\
+ :pb#1440:ob#0:bb#4096:fb#512:\
+ :pc#1440:oc#0:bc#4096:fc#512:
+
+fd1200|floppy5|5in|5.25in High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#360:ns#15:nc#80:\
+ :pa#2400:oa#0:ba#4096:fa#512:\
+ :pb#2400:ob#0:bb#4096:fb#512:\
+ :pc#2400:oc#0:bc#4096:fc#512:
+
+fd1440|floppy|floppy3|3in|3.5in High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#18:nc#80:\
+ :pa#2880:oa#0:ba#4096:fa#512:\
+ :pb#2880:ob#0:bb#4096:fb#512:\
+ :pc#2880:oc#0:bc#4096:fc#512:
+
+fd1024|floppy0|3.5in Special Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#16:nc#64:\
+ :pa#2048:oa#0:ba#4096:fa#512:\
+ :pb#2048:ob#0:bb#4096:fb#512:\
+ :pc#2048:oc#0:bc#4096:fc#512:
+
+# a == root
+# b == swap
+# c == d == whole disk
+# e == /var
+# f == scratch
+# h == /usr
+
+cp3100new|Connor Peripherals 100MB IDE, with a different configuration:\
+ :dt=ST506:ty=winchester:se#512:nt#8:ns#33:nc#766: \
+ :pa#15840:oa#0:ta=4.2BSD:ba#4096:fa#512: \
+ :pb#24288:ob#15840:tb=swap: \
+ :pc#202224:oc#0: \
+ :pd#202224:od#0: \
+ :pe#15840:oe#40128:te=4.2BSD:be#4096:fe#512: \
+ :pg#15840:og#55968:tg=4.2BSD:bg#4096:fg#512: \
+ :ph#130416:oh#71808:th=4.2BSD:bh#4096:fh#512:
+
+sony650|Sony 650 MB MOD|\
+ :ty=removable:dt=SCSI:se#512:nt#1:ns#31:nc#18600:ts#1:rm#4800:\
+ :pc#576600:oc#0:\
+ :pa#576600:oa#0:ta=4.2BSD:ba#8192:fa#1024:
+
+mta3230|mo230|IBM MTA-3230 230 Meg 3.5inch Magneto-Optical:\
+ :ty=removeable:dt=SCSI:rm#3600:\
+ :se#512:nt#64:ns#32:nc#216:sc#2048:su#444384:\
+ :pa#444384:oa#0:ba#4096:fa#0:ta=4.2BSD:\
+ :pc#444384:oc#0:
+
+minimum:ty=mfs:se#512:nt#1:rm#300:\
+ :ns#2880:nc#1:\
+ :pa#2880:oa#0:ba#4096:fa#512:\
+ :pc#2880:oc#0:bc#4096:fc#512:
+
+zip100|zip 100:\
+ :ty=removable:se#512:nc#96:nt#64:ns#32:\
+ :pa#196608:oa#0:ba#4096:fa#512:\
+ :pb#196608:ob#0:bb#4096:fb#512:\
+ :pc#196608:oc#0:bc#4096:fc#512:
diff --git a/release/picobsd/mfs_tree/etc/gettytab b/release/picobsd/mfs_tree/etc/gettytab
new file mode 100644
index 0000000..c444276
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/gettytab
@@ -0,0 +1,42 @@
+# $FreeBSD$
+# from: @(#)gettytab 5.14 (Berkeley) 3/27/91
+#
+default:\
+ :cb:ce:ck:lc:fd#1000:cl:im=\r\nPicoBSD (%h) (%t)\r\n\r\n:sp#1200:
+
+# 20140527 add nc (no carrier) to the pc console entry to fix
+# devices with no handshake after svn 264175 (this also affects bhyve)
+P|Pc|Pc console|3wire:\
+ :nc:\
+ :ht:np:sp#115200:
+
+# Fixed speed entries
+2|std.9600|9600-baud:\
+ :nc:np:sp#9600:
+g|std.19200|19200-baud:\
+ :np:sp#19200:
+std.38400|38400-baud:\
+ :np:sp#38400:
+std.57600|57600-baud:\
+ :np:sp#57600:
+std.115200|115200-baud:\
+ :np:sp#115200:
+
+# Entry specifying explicit device settings. See termios(4) and
+# /usr/include/termios.h, too. The entry forces the tty into
+# CLOCAL mode (so no DCD is required), and uses Xon/Xoff flow control.
+#
+# cflags: CLOCAL | HUPCL | CREAD | CS8
+# oflags: OPOST | ONLCR | OXTABS
+# iflags: IXOFF | IXON | ICRNL | IGNPAR
+# lflags: IEXTEN | ICANON | ISIG | ECHOCTL | ECHO | ECHOK | ECHOE | ECHOKE
+#
+# The `0' flags don't have input enabled. The `1' flags don't echo.
+# (Echoing is done inside getty itself.)
+#
+local.9600|CLOCAL tty @ 9600 Bd:\
+ :c0#0x0000c300:c1#0x0000cb00:c2#0x0000cb00:\
+ :o0#0x00000007:o1#0x00000002:o2#0x00000007:\
+ :i0#0x00000704:i1#0x00000000:i2#0x00000704:\
+ :l0#0x000005cf:l1#0x00000000:l2#0x000005cf:\
+ :sp#9600:
diff --git a/release/picobsd/mfs_tree/etc/group b/release/picobsd/mfs_tree/etc/group
new file mode 100644
index 0000000..abbd733
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/group
@@ -0,0 +1,19 @@
+wheel:*:0:root,user
+daemon:*:1:daemon
+kmem:*:2:root
+sys:*:3:root
+tty:*:4:root
+operator:*:5:root
+mail:*:6:
+bin:*:7:
+news:*:8:
+man:*:9:
+games:*:13:
+staff:*:20:root,user
+guest:*:31:root
+uucp:*:66:
+xten:*:67:xten
+dialer:*:68:
+network:*:69:
+nogroup:*:65533:
+nobody:*:65534:
diff --git a/release/picobsd/mfs_tree/etc/login.conf b/release/picobsd/mfs_tree/etc/login.conf
new file mode 100644
index 0000000..4337b1f
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/login.conf
@@ -0,0 +1,118 @@
+# This file controls resource limits, accounting limits and
+# default user environment settings.
+#
+# $FreeBSD$
+#
+
+
+# Authentication methods
+
+auth-defaults:\
+ :auth=passwd:
+
+auth-root-defaults:\
+ :auth-login=passwd:\
+ :auth-rlogin=passwd:\
+
+auth-ftp-defaults:\
+ :auth=passwd:
+
+# Example defaults
+# These settings are used by login(1) by default for classless users
+# Note that entries like "cputime" set both "cputime-cur" and "cputime-max"
+
+default:\
+ :cputime=infinity:\
+ :datasize-cur=22M:\
+ :stacksize-cur=8M:\
+ :memorylocked-cur=10M:\
+ :memoryuse-cur=30M:\
+ :filesize=infinity:\
+ :coredumpsize=0:\
+ :maxproc-cur=64:\
+ :openfiles-cur=64:\
+ :priority=0:\
+ :requirehome@:\
+ :umask=022:\
+ :tc=auth-defaults:
+
+# standard - standard user defaults
+#
+standard:\
+ :copyright=/etc/COPYRIGHT:\
+ :welcome=/etc/motd:\
+ :setenv=MAIL=/var/mail/$,BLOCKSIZE=K,EDITOR=/usr/bin/ee:\
+ :path=~/bin /bin /usr/bin:\
+ :nologin=/var/run/nologin:\
+ :cputime=1h30m:\
+ :datasize=8M:\
+ :stacksize=2M:\
+ :memorylocked=4M:\
+ :memoryuse=8M:\
+ :filesize=8M:\
+ :coredumpsize=0:\
+ :openfiles=24:\
+ :maxproc=32:\
+ :priority=0:\
+ :requirehome:\
+ :passwordtime=90d:\
+ :umask=002:\
+ :ignoretime@:\
+ :tc=default:
+#
+# Staff users - few restrictions and allow login anytime
+#
+staff:\
+ :ignorenologin:\
+ :ignoretime:\
+ :requirehome@:\
+ :accounted@:\
+ :path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
+ :umask=022:\
+ :tc=standard:
+
+
+#
+# root - fallback for root logins
+#
+root:\
+ :path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
+ :cputime=infinity:\
+ :datasize=infinity:\
+ :stacksize=infinity:\
+ :memorylocked=infinity:\
+ :memoryuse=infinity:\
+ :filesize=infinity:\
+ :coredumpsize=0:\
+ :openfiles=infinity:\
+ :maxproc=infinity:\
+ :memoryuse-cur=32M:\
+ :maxproc-cur=64:\
+ :openfiles-cur=1024:\
+ :priority=0:\
+ :requirehome@:\
+ :umask=022:\
+ :tc=auth-root-defaults:\
+#
+# Settings used by /etc/rc
+#
+daemon:\
+ :coredumpsize@:\
+ :coredumpsize-cur=0:\
+ :datasize=infinity:\
+ :datasize-cur@:\
+ :maxproc=512:\
+ :maxproc-cur@:\
+ :memoryuse-cur=64M:\
+ :memorylocked-cur=64M:\
+ :openfiles=1024:\
+ :openfiles-cur@:\
+ :stacksize=16M:\
+ :stacksize-cur@:\
+ :tc=default:
+#
+# Polish Users Accounts. Setup proper environment variables.
+#
+polish:Polish Users Accounts:\
+ :lang=pl_pl.ISO-8859-2:\
+ :tc=default:
diff --git a/release/picobsd/mfs_tree/etc/motd b/release/picobsd/mfs_tree/etc/motd
new file mode 100644
index 0000000..299ac17
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/motd
@@ -0,0 +1,9 @@
+==============================================================
+
+ )\_)\ Welcome to PicoBSD
+ (o,o)
+ __ \~/
+ -->====\
+ ~~ d d
+
+==============================================================
diff --git a/release/picobsd/mfs_tree/etc/protocols b/release/picobsd/mfs_tree/etc/protocols
new file mode 100644
index 0000000..0ef23af
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/protocols
@@ -0,0 +1,14 @@
+# $FreeBSD$
+# Internet (IP) protocols
+ip 0 IP # internet protocol, pseudo protocol number
+icmp 1 ICMP # internet control message protocol
+igmp 2 IGMP # Internet Group Management
+tcp 6 TCP # transmission control protocol
+udp 17 UDP # user datagram protocol
+ipv6 41 IPV6 # ipv6
+gre 47 GRE # Generic Routing Encapsulation
+ah 51 AH # authentication header
+ospf 89 OSPFIGP # Open Shortest Path First IGP
+pim 103 PIM # Protocol Independent Multicast
+vrrp 112 VRRP # Virtual Router Redundancy Protocol
+pgm 113 PGM # PGM
diff --git a/release/picobsd/mfs_tree/etc/rc b/release/picobsd/mfs_tree/etc/rc
new file mode 100644
index 0000000..217224e
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/rc
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD$
+
+stty status '^T'
+trap : 2
+trap : 3
+
+HOME=/; export HOME
+PATH=/bin; export PATH
+dev=`sysctl -n machdep.guessed_bootdev`
+[ -c "${dev}" ] || dev="/dev/fd0"
+
+trap "echo 'Reboot interrupted'; exit 1" 3
+set `df /`; mount -u $8 / # upgrade mount to rw
+echo "Loading /etc from MFS:/fd ..."
+cp -Rp /fd/* /
+echo "Updating /etc from ${dev}..."
+mount -o rdonly ${dev} /fd && \
+{ cd /fd; cp -Rp etc root / ; cd / ; umount /fd ; }
+cd /etc
+#rm files to stop overwrite warning
+for i in *; do
+ [ -f $i.gz ] && rm $i
+done
+gzip -d *.gz
+. /etc/rc1
+exit 0
diff --git a/release/picobsd/mfs_tree/etc/rc.network b/release/picobsd/mfs_tree/etc/rc.network
new file mode 100644
index 0000000..3cd6d5d
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/rc.network
@@ -0,0 +1,83 @@
+#!/bin/sh -
+# $FreeBSD$
+
+network_pass1() {
+ echo -n 'Doing initial network setup:'
+ # Set the host name if it is not already set
+ if [ -z "`hostname -s`" ] ; then
+ hostname $hostname
+ echo ' hostname'
+ fi
+ # Set up all the network interfaces, calling startup scripts if needed
+ for ifn in ${network_interfaces}; do
+ [ -e /etc/start_if.${ifn} ] && . /etc/start_if.${ifn}
+ # Do the primary ifconfig if specified
+ eval ifconfig_args=\$ifconfig_${ifn}
+ [ -n "${ifconfig_args}" ] && ifconfig ${ifn} ${ifconfig_args}
+ # Check to see if aliases need to be added
+ alias=0
+ while :
+ do
+ eval ifconfig_args=\$ifconfig_${ifn}_alias${alias}
+ if [ -n "${ifconfig_args}" ]; then
+ ifconfig ${ifn} ${ifconfig_args} alias
+ alias=$((${alias} + 1))
+ else
+ break;
+ fi
+ done
+ ifconfig ${ifn}
+ done
+ # Load the filters if required
+ if [ -f /etc/rc.firewall -a "${firewall_enable}" = "YES" ] ; then
+ # Set quiet mode if requested
+ if [ "${firewall_quiet}" = "YES" ]; then
+ fwcmd="/sbin/ipfw -q"
+ else
+ fwcmd="/sbin/ipfw"
+ fi
+ $fwcmd -f flush # Flush out the list before we begin.
+
+ . /etc/rc.firewall
+ echo "Firewall rules loaded."
+ else
+ echo "Warning: kernel has firewall functionality, but firewall rules weren't loaded."
+ echo " All ip services are ENABLED by default."
+ fi
+ # Configure routing
+ if [ "x$defaultrouter" != "xNO" ] ; then
+ static_routes="default ${static_routes}"
+ route_default="default ${defaultrouter}"
+ fi
+ # Set up any static routes. This should be done before router discovery.
+ if [ "x${static_routes}" != "x" ]; then
+ for i in ${static_routes}; do
+ eval route_args=\$route_${i}
+ route add ${route_args}
+ done
+ fi
+ echo -n 'Additional routing options:'
+ if [ -n "$tcp_extensions" -a "x$tcp_extensions" != "xYES" ] ; then
+ echo -n ' tcp_extensions=NO'
+ sysctl net.inet.tcp.rfc1323=0 >/dev/null 2>&1
+ sysctl net.inet.tcp.rfc1644=0 >/dev/null 2>&1
+ fi
+ if [ "X$gateway_enable" = X"YES" ]; then
+ echo -n ' IP_gateway=YES'
+ sysctl net.inet.ip.forwarding=1 >/dev/null 2>&1
+ fi
+ if [ "X$arpproxy_all" = X"YES" ]; then
+ echo -n ' turning on ARP_PROXY_ALL: '
+ sysctl net.link.ether.inet.proxyall=1 2>&1
+ fi
+ echo '.'
+ network_pass1_done=YES # Let future generations know we made it.
+}
+
+network_pass2() {
+ network_pass2_done=YES
+}
+
+network_pass3() {
+ network_pass3_done=YES
+}
diff --git a/release/picobsd/mfs_tree/etc/rc.serial b/release/picobsd/mfs_tree/etc/rc.serial
new file mode 100644
index 0000000..40fbd8a
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/rc.serial
@@ -0,0 +1,127 @@
+#!/bin/sh
+# $FreeBSD$
+
+# Change some defaults for serial devices.
+# Standard defaults are:
+# dtrwait 300 drainwait 0
+# initial cflag from <sys/ttydefaults.h> = cread cs8 hupcl
+# initial iflag, lflag and oflag all 0
+# speed 9600
+# special chars from <sys/ttydefaults.h>
+# nothing locked
+# except for serial consoles the initial iflag, lflag and oflag are from
+# <sys/ttydefaults.h> and clocal is locked on.
+
+default() {
+ # Reset everything changed by the other functions to initial defaults.
+
+ ci=$1; shift # call in device identifier
+ co=$1; shift # call out device identifier
+
+ for i in $*
+ do
+ comcontrol /dev/tty$ci$i dtrwait 300 drainwait 0
+ stty </dev/ttyi$ci$i -clocal crtscts hupcl 9600 reprint ^R
+ stty </dev/ttyl$ci$i -clocal -crtscts -hupcl 0
+ stty </dev/cuai$co$i -clocal crtscts hupcl 9600 reprint ^R
+ stty </dev/cual$co$i -clocal -crtscts -hupcl 0
+ done
+}
+
+maybe() {
+ # Special settings.
+
+ ci=$1; shift
+ co=$1; shift
+
+ for i in $*
+ do
+ # Don't use ^R; it breaks bash's ^R when typed ahead.
+ stty </dev/ttyi$ci$i reprint undef
+ stty </dev/cuai$co$i reprint undef
+ # Lock clocal off on dialin device for security.
+ stty </dev/ttyl$ci$i clocal
+ # Lock the speeds to use old binaries that don't support them.
+ # Any legal speed works to lock the initial speed.
+ stty </dev/ttyl$ci$i 300
+ stty </dev/cual$co$i 300
+ done
+}
+
+modem() {
+ # Modem that supports CTS and perhaps RTS handshaking.
+
+ ci=$1; shift
+ co=$1; shift
+
+ for i in $*
+ do
+ # may depend on modem
+ comcontrol /dev/tty$ci$i dtrwait 100 drainwait 180
+ # Lock crtscts on.
+ # Speed reasonable for V42bis.
+ stty </dev/ttyi$ci$i crtscts 57600
+ stty </dev/ttyl$ci$i crtscts
+ stty </dev/cuai$co$i crtscts 57600
+ stty </dev/cual$co$i crtscts
+ done
+}
+
+mouse() {
+ # Mouse on either callin or callout port.
+
+ ci=$1; shift
+ co=$1; shift
+
+ for i in $*
+ do
+ # Lock clocal on, hupcl off.
+ # Standard speed for Microsoft mouse.
+ stty </dev/ttyi$ci$i clocal -hupcl 1200
+ stty </dev/ttyl$ci$i clocal hupcl
+ stty </dev/cuai$co$i clocal -hupcl 1200
+ stty </dev/cual$co$i clocal hupcl
+ done
+}
+
+terminal() {
+ # Terminal that supports CTS and perhaps RTS handshaking
+ # with the cable or terminal arranged so that DCD is on
+ # at least while the terminal is on.
+ # Also works for bidirectional communications to another pc
+ # provided at most one side runs getty.
+ # Same as modem() except we want a faster speed and no dtrwait.
+
+ ci=$1; shift
+ co=$1; shift
+
+ modem $ci $co $*
+ for i in $*
+ do
+ comcontrol /dev/tty$ci$i dtrwait 0
+ stty </dev/ttyi$ci$i 115200
+ stty </dev/cuai$co$i 115200
+ done
+}
+
+# Don't use anything from this file unless you have some buggy programs
+# that require it.
+
+# Edit the functions and the examples to suit your system.
+# $1 is the call in device identifier, $2 is the call out device identifier
+# and the remainder of the line lists the device numbers.
+
+# Initialize assorted 8250-16550 (sio) ports.
+# maybe d a 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v
+# mouse d a 2
+# modem d a 1
+# terminal d a 0
+
+# Initialize all ports on a Cyclades-8yo.
+# modem c c 00 01 02 03 04 05 06 07
+
+# Initialize all ports on a Cyclades-16ye.
+# modem c c 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
+
+# Initialize all ports on a Digiboard 8.
+# modem D D 00 01 02 03 04 05 06 07
diff --git a/release/picobsd/mfs_tree/etc/remote b/release/picobsd/mfs_tree/etc/remote
new file mode 100644
index 0000000..523a4c2
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/remote
@@ -0,0 +1,50 @@
+# @(#)remote 5.2 (Berkeley) 6/30/90
+# $FreeBSD$
+# remote -- remote host description file
+# see tip(1), remote(5)
+#
+# dv device to use for the tty
+# el EOL marks (default is NULL)
+# du make a call flag (dial up)
+# pn phone numbers (@ =>'s search phones file; possibly taken from
+# PHONES environment variable)
+# at ACU type
+# ie input EOF marks (default is NULL)
+# oe output EOF string (default is NULL)
+# cu call unit (default is dv)
+# br baud rate (defaults to 300)
+# fs frame size (default is BUFSIZ) -- used in buffering writes on
+# receive operations
+# tc to continue a capability
+
+# Systems definitions
+netcom|Netcom Unix Access:\
+ :pn=\@:tc=unix1200:
+omen|Omen BBS:\
+ :pn=\@:tc=dos1200:
+
+# UNIX system definitions
+unix1200|1200 Baud dial-out to a UNIX system:\
+ :el=^U^C^R^O^D^S^Q:ie=%$:oe=^D:tc=dial1200:
+unix300|300 Baud dial-out to a UNIX system:\
+ :el=^U^C^R^O^D^S^Q:ie=%$:oe=^D:tc=dial300:
+
+# DOS system definitions
+dos1200|1200 Baud dial-out to a DOS system:\
+ :el=^U^C^R^O^D^S^Q:ie=%$:oe=^Z:pa=none:tc=dial1200:
+
+# General dialer definitions used below
+#
+# COURIER switch settings:
+# switch: 1 2 3 4 5 6 7 8 9 10
+# setting: D U D U D D U D U U
+# Rackmount: U U D U D U D D U D
+#
+dial2400|2400 Baud Hayes attributes:\
+ :dv=/dev/cuau0:br#2400:cu=/dev/cuau0:at=hayes:du:
+dial1200|1200 Baud Hayes attributes:\
+ :dv=/dev/cuau0:br#1200:cu=/dev/cuau0:at=hayes:du:
+
+# Hardwired line
+cuau0b|cua0b:dv=/dev/cuau0:br#2400
+cuau0c|cua0c:dv=/dev/cuau0:br#9600
diff --git a/release/picobsd/mfs_tree/etc/services b/release/picobsd/mfs_tree/etc/services
new file mode 100644
index 0000000..eec499f
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/services
@@ -0,0 +1,94 @@
+echo 4/ddp
+echo 7/tcp
+echo 7/udp
+discard 9/tcp
+discard 9/udp
+systat 11/tcp
+systat 11/udp
+daytime 13/tcp
+daytime 13/udp
+qotd 17/tcp
+qotd 17/udp
+chargen 19/tcp
+chargen 19/udp
+ftp-data 20/tcp
+ftp-data 20/udp
+ftp 21/tcp
+ftp 21/udp
+ssh 22/tcp
+ssh 22/udp
+telnet 23/tcp
+telnet 23/udp
+smtp 25/tcp
+smtp 25/udp
+time 37/tcp
+time 37/udp
+domain 53/tcp
+domain 53/udp
+tacacs-ds 65/tcp
+tacacs-ds 65/udp
+bootps 67/tcp
+bootps 67/udp
+bootpc 68/tcp
+bootpc 68/udp
+tftp 69/tcp
+tftp 69/udp
+gopher 70/tcp
+gopher 70/udp
+finger 79/tcp
+finger 79/udp
+http 80/tcp
+http 80/udp
+pop2 109/tcp
+pop2 109/udp
+pop3 110/tcp
+pop3 110/udp
+uucp-path 117/tcp
+uucp-path 117/udp
+nntp 119/tcp
+nntp 119/udp
+netbios-ns 137/tcp
+netbios-ns 137/udp
+netbios-dgm 138/tcp
+netbios-dgm 138/udp
+netbios-ssn 139/tcp
+netbios-ssn 139/udp
+imap 143/tcp
+imap 143/udp
+snmp 161/tcp
+snmp 161/udp
+snmptrap 162/tcp
+snmptrap 162/udp
+bgp 179/tcp
+bgp 179/udp
+irc 194/tcp
+irc 194/udp
+ipx 213/tcp
+ipx 213/udp
+imap3 220/tcp
+imap3 220/udp
+ldap 389/tcp
+ldap 389/udp
+netware-ip 396/tcp
+netware-ip 396/udp
+https 443/tcp
+https 443/udp
+exec 512/tcp
+biff 512/udp
+login 513/tcp
+who 513/udp
+cmd 514/tcp
+syslog 514/udp
+printer 515/tcp
+printer 515/udp
+talk 517/tcp
+talk 517/udp
+ntalk 518/tcp
+ntalk 518/udp
+timed 525/tcp
+timed 525/udp
+uucp 540/tcp
+uucp 540/udp
+uucp-rlogin 541/tcp
+uucp-rlogin 541/udp
+natd 8668/divert # Network Address Translation
diff --git a/release/picobsd/mfs_tree/etc/shells b/release/picobsd/mfs_tree/etc/shells
new file mode 100644
index 0000000..cd386f6
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/shells
@@ -0,0 +1,7 @@
+# $FreeBSD$
+# List of acceptable shells for chpass(1).
+# Ftpd will not allow users to connect who are not using
+# one of these shells.
+
+/bin/sh
+/bin/csh
diff --git a/release/picobsd/mfs_tree/etc/termcap b/release/picobsd/mfs_tree/etc/termcap
new file mode 100644
index 0000000..5b8f949
--- /dev/null
+++ b/release/picobsd/mfs_tree/etc/termcap
@@ -0,0 +1,187 @@
+# Copyright (c) 1980, 1985, 1989 The Regents of the University of California.
+# All rights reserved.
+# @(#)termcap.src 5.88 (Berkeley) 4/30/91
+#
+# $FreeBSD$
+#
+# for syscons
+# common entry without semigraphics
+cons25w|ansiw|ansi80x25-raw:\
+ :al=\E[L:am:bs:NP:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:co#80:\
+ :dc=\E[P:dl=\E[M:do=\E[B:bt=\E[Z:ho=\E[H:ic=\E[@:li#25:cb=\E[1K:\
+ :ms:nd=\E[C:pt:rs=\E[x\E[m\Ec:so=\E[7m:se=\E[m:up=\E[A:\
+ :pa#64:Co#8:Sf=\E[3%dm:Sb=\E[4%dm:op=\E[37;40m:\
+ :k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:k5=\E[Q:k6=\E[R:k7=\E[S:k8=\E[T:\
+ :k9=\E[U:k;=\E[V:F1=\E[W:F2=\E[X:K2=\E[E:nw=\E[E:ec=\E[%dX:\
+ :kb=^H:kh=\E[H:ku=\E[A:kd=\E[B:kl=\E[D:kr=\E[C:le=^H:eo:sf=\E[S:sr=\E[T:\
+ :kN=\E[G:kP=\E[I:@7=\E[F:kI=\E[L:kD=\E[K:kB=\E[Z:\
+ :IC=\E[%d@:DC=\E[%dP:SF=\E[%dS:SR=\E[%dT:AL=\E[%dL:DL=\E[%dM:\
+ :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:cv=\E[%i%dd:ch=\E[%i%d`:bw:\
+ :mb=\E[5m:md=\E[1m:mh=\E[30;1m:mr=\E[7m:me=\E[m:bl=^G:ut:it#8:
+cons25|ansis|ansi80x25:\
+ :ac=l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\305`^Da\260f\370g\361~\371.^Y-^Xh\261I^U0\333y\363z\362:\
+ :tc=cons25w:
+cons25-m|ansis-mono|ansi80x25-mono:\
+ :pa@:Co@:Sf@:Sb@:op@:us=\E[4m:ue=\E[m:md@:mh@:tc=cons25:
+cons50|ansil|ansi80x50:\
+ :li#50:tc=cons25:
+cons50-m|ansil-mono|ansi80x50-mono:\
+ :li#50:tc=cons25-m:
+# 80x25 ISO 8859-1 FreeBSD console
+cons25l1|cons25-iso8859-1:\
+ :ac=l\215m\216k\214j\213u\226t\225v\227w\230q\222x\231n\217o\220s\224p\221r\223`\201a\202f\207g\210~\237.^Y-^X+\253,\273I\247y\232z\233:\
+ :tc=cons25w:
+cons25l1-m|cons25-iso8859-1-mono:\
+ :pa@:Co@:Sf@:Sb@:op@:us=\E[4m:ue=\E[m:md@:mh@:tc=cons25l1:
+# 80x50 ISO 8859-1 FreeBSD console
+cons50l1|cons50-iso8859-1:\
+ :li#50:tc=cons25l1:
+cons50l1-m|cons50-iso8859-1-mono:\
+ :li#50:tc=cons25l1-m:
+dosansi|ANSI.SYS standard crt|ansi:\
+ :am:bs:ce=\E[K:cl=\E[2J:cm=\E[%i%d;%dH:co#80:\
+ :do=\E[B:li#25:mi:nd=\E[C:\
+ :se=\E[m:so=\E[7m:up=\E[A:us=\E[4m:ue=\E[m:\
+ :md=\E[1m:mh=\E[m:mb=\E[5m:me=\E[m:\
+ :kh=\EG:kb=^h:ku=\EH:kd=\EP:kl=\EK:kr=\EM:\
+ :k1=\E;:k2=\E<:k3=\E=:k4=\E>:k5=\E?:\
+ :k6=\E@:k7=\EA:k8=\EB:k9=\EC:k0=\ED:
+vt200|vt220|vt220am|vt200am|dec-vt220|dec-vt200|dec vt200 series with jump scroll:\
+ :@7=\E[4~:kD=\E[3~:kI=\E[2~:kN=\E[6~:kP=\E[5~:kh=\E[1~:\
+ :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:\
+ :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\
+ :ve=\E[?25h:vi=\E[?25l:k0@:im@:ei@:\
+ :F1=\E[23~:F2=\E[24~:ic=\E[@:IC=\E[%d@:ec=\E[%dX:tc=vt102:
+vt100|dec-vt100|vt100-am|vt100am|dec vt100:\
+ :do=2\E[B:co#80:li#24:cl=50\E[H\E[J:sf=2*\ED:\
+ :le=^H:bs:am:cm=5\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
+ :ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
+ :md=2\E[1m:mr=2\E[7m:mb=2\E[5m:me=2\E[m:\
+ :is=\E>\E[?1;3;4;5l\E[?7;8h\E[1;24r\E[24;1H:\
+ :if=/usr/share/tabset/vt100:nw=2\EE:ho=\E[H:\
+ :as=2\E(0:ae=2\E(B:ac=llmmkkjjuuttvvwwqqxxnnpprr``aa:\
+ :rs=\E>\E[?1;3;4;5l\E[?7;8h:ks=\E[?1h\E=:ke=\E[?1l\E>:\
+ :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=\177:\
+ :k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOt:\
+ :k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:@8=\EOM:\
+ :K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:pt:sr=2*\EM:vt#3:xn:\
+ :sc=2\E7:rc=2\E8:cs=5\E[%i%d;%dr:UP=2\E[%dA:DO=2\E[%dB:RI=2\E[%dC:\
+ :LE=2\E[%dD:ct=2\E[3g:st=2\EH:ta=^I:ms:bl=^G:cr=^M:eo:it#8:ut:\
+ :RA=\E[?7l:SA=\E[?7h:
+xterm|vs100|xterm terminal emulator (X window system):\
+ :li#25:\
+ :kh=\EOH:@7=\EOF:kb=^H:kD=^?:\
+ :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:km:\
+ :is=\E>\E[?1;3;4;5l\E[?7;8h\E[1;65r\E[65;1H:\
+ :rs=\E>\E[?1;3;4;5l\E[?7;8h:\
+ :tc=vt220:
+xterm-color|xterm-co|xterm with ANSI colors:\
+ :pa#64:Co#8:AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:tc=xterm:
+
+
+vt100-nam|dec-vt100-nam|vt100nam|vt100 w/no am:\
+ :am@:xn@:\
+ :is=\E>\E[?1;3;4;5;7l\E[?8h\E[1;24r\E[24;1H:\
+ :rs=\E>\E[?1;3;4;5;7l\E[?8h:\
+ :tc=vt100-am:
+vt100-np|dec-vt100-np|vt100 with no padding (for psl games):\
+ :do=\E[B:cl=\E[H\E[J:sf=\ED:as=\E(0:ae=\E(B:\
+ :cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:nw=\EE:\
+ :ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\
+ :md=\E[1m:mr=\E[7m:mb=\E[5m:me=\E[m:sr=\EM:\
+ :sc=\E7:rc=\E8:cs=\E[%i%d;%dr:UP=\E[%dA:DO=\E[%dB:RI=\E[%dC:\
+ :LE=\E[%dD:ct=\E[3g:st=\EH:tc=vt100-am:
+vt100-nac|dec-vt100-nac|vt100 without pseudographics and padding:\
+ :as@:ae@:ac@:tc=vt100-np:
+vt102|dec-vt102-am|vt102am|vt100 w/adv. video:\
+ :al=\E[L:dl=\E[M:im=\E[4h:ei=\E[4l:mi:dc=\E[P:\
+ :AL=\E[%dL:DL=\E[%dM:DC=\E[%dP:tc=vt100-np:
+
+# Note: this entry describes the "native"
+# capabilities of the PC monochrome display, without ANY emulation; most
+# communications packages (but NOT PC/IX connect) do some kind of emulation.
+pc|ibmpc|ibm pc PC/IX:\
+ :li#24:co#80:am:bs:bw:eo:\
+ :cd=\E[J:ce=\E[K:cl=\Ec:cm=\E[%i%2;%2H:do=\E[B:ho=\E[;H:\
+ :nd=\E[C:up=\E[A:so=\E[7m:se=\E[0m:us=\E[4m:ue=\E[0m:
+pc3mono|IBM PC 386BSD Console with monochrome monitor:\
+ :so=\E[0;1r\E[m:tc=pc3:
+pc3|ibmpc3|IBM PC 386BSD Console:\
+ :Co#8:\
+ :DO=\E[%dB:\
+ :F1=\E[W:F2=\E[X:\
+ :K1=\E[H:K2=\E[I:K3=\E[E:K4=\E[F:K5=\E[G:\
+ :LE=\E[%dD:\
+ :RI=\E[%dC:\
+ :Sb=\E[1;%dx:\
+ :Sf=\E[2;%dx:\
+ :UP=\E[%dA:\
+ :ac=l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\305`^Da\260f\370g\361~\371.^Y-^Xh\261I^U0\333y\363z\362:\
+ :am:\
+ :bl=^G:\
+ :bs:\
+ :cb=\E[1K:\
+ :cd=\E[J:\
+ :ce=\E[K:\
+ :cl=\E[H\E[J:\
+ :cm=\E[%i%d;%dH:\
+ :co#80:\
+ :cr=^M:\
+ :do=\E[B:\
+ :ho=\E[H:\
+ :is=\E[m:\
+ :it#8:\
+ :k;=\E[V:k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:k5=\E[Q:k6=\E[R:k7=\E[S:k8=\E[T:k9=\E[U:\
+ :kD=\177:\
+ :@7=\E[F:\
+ :kN=\E[G:\
+ :kP=\E[I:\
+ :kb=\177:\
+ :kd=\E[B:\
+ :kh=\E[H:\
+ :kl=\E[D:\
+ :kr=\E[C:\
+ :ku=\E[A:\
+ :le=^H:\
+ :li#25:\
+ :ms:\
+ :nd=\E[C:\
+ :op=\E[x:\
+ :pa#64:\
+ :rs=\E[m:\
+ :se=\E[m:\
+ :sf=\E[S:\
+ :so=\E[7;1r\E[7m:\
+ :sr=\E[T:\
+ :ta=^I:\
+ :te=\E[m:\
+ :ti=\E[m:\
+ :up=\E[A:\
+ :ut:
+du|dialup:\
+ :tc=unknown:
+dumb|un|unknown:\
+ :am:co#80:do=^J:
+# SC,SW names needed for screen(1) ache
+SC|screen|VT 100/ANSI X3.64 virtual terminal:\
+ :am:xn:ms:mi:G0:km:\
+ :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bs:bt=\E[Z:\
+ :cb=\E[1K:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:ct=\E[3g:\
+ :do=^J:nd=\E[C:pt:rc=\E8:rs=\Ec:sc=\E7:st=\EH:up=\EM:\
+ :le=^H:bl=^G:cr=^M:it#8:ho=\E[H:nw=\EE:ta=^I:is=\E)0:\
+ :li#24:co#80:us=\E[4m:ue=\E[24m:so=\E[3m:se=\E[23m:\
+ :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:sr=\EM:al=\E[L:\
+ :AL=\E[%dL:dl=\E[M:DL=\E[%dM:cs=\E[%i%d;%dr:dc=\E[P:\
+ :DC=\E[%dP:ic=\E[@:IC=\E[%d@:\
+ :ks=\E[?1h\E=:ke=\E[?1l\E>:vb=\Eg:\
+ :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
+ :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:\
+ :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:\
+ :kh=\E[1~:kI=\E[2~:kD=\E[3~:kH=\E[4~:kP=\E[5~:kN=\E[6~:\
+ :eA=\E(B\E)0:as=^N:ae=^O:\
+ :vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l:\
+ :Co#8:pa#64:AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:AX:\
+ :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhii00:
+SW|screen-w|VT 100/ANSI X3.64 virtual terminal with 132 cols:\
+ :co#132:tc=screen:
+
diff --git a/release/picobsd/mfs_tree/stand/update b/release/picobsd/mfs_tree/stand/update
new file mode 100755
index 0000000..072493a
--- /dev/null
+++ b/release/picobsd/mfs_tree/stand/update
@@ -0,0 +1,50 @@
+#!/bin/sh
+# $FreeBSD$
+# script to edit and save some config file(s).
+# If called with no arguments, it edits 3 files in /etc
+thefiles=$*
+[ -z "$thefiles" ] && \
+ thefiles="/etc/rc.conf /etc/rc.firewall /etc/master.passwd"
+dev=`sysctl -n machdep.guessed_bootdev`
+[ -c "${dev}" ] || dev="/dev/fd0"
+mount ${dev} /mnt
+if [ "$?" != "0" ] ; then
+ echo ""
+ echo "Cannot mount ${dev} read-write!"
+ exit 1
+fi
+
+echo "Updating ${thefiles} on ${dev}: "
+
+for f in ${thefiles} ; do
+ case $f in
+ /etc )
+ echo "Update all files in $f :"
+ srcs=`ls $f`
+ for i in $srcs ; do
+ if [ -f /mnt${f}/${i}.gz ]; then
+ echo -n "$i ..."
+ gzip < $f/$i > /mnt${f}/${i}.gz
+ fi
+ done
+ echo " Done."
+ ;;
+
+ passwd|master.passwd)
+ mkdir -p /mnt/etc
+ ee /etc/master.passwd
+ pwd_mkdb /etc/master.passwd
+ gzip < /etc/master.passwd > /mnt/etc/master.passwd.gz
+ ;;
+
+ /*) # only absolute pathnames are ok
+ mkdir -p /mnt/etc /mnt/root
+ [ -f $f ] && ee $f && gzip < $f > /mnt${f}.gz
+ ;;
+
+ *)
+ echo "File $f not recognised, you must use an absolute pathname."
+ ;;
+ esac
+done
+umount /mnt
diff --git a/release/picobsd/qemu/PICOBSD b/release/picobsd/qemu/PICOBSD
new file mode 100644
index 0000000..16b1753
--- /dev/null
+++ b/release/picobsd/qemu/PICOBSD
@@ -0,0 +1,124 @@
+#
+# $FreeBSD$
+# A configuration file to run tests on qemu.
+# We disable SMP because it does not work well with qemu, and set HZ=1000
+# to avoid it being overridden.
+#
+# Line starting with #PicoBSD contains PicoBSD build parameters
+#marker def_sz init MFS_inodes floppy_inodes
+#PicoBSD 18000 init 8192 32768
+options MD_ROOT_SIZE=18000 # same as def_sz
+
+hints "PICOBSD.hints"
+
+# values accessible through getenv()
+# env "PICOBSD.env"
+
+#cpu I486_CPU
+cpu I586_CPU
+cpu I686_CPU
+ident PICOBSD
+
+# SMP seems to be needed for kern_et
+options SMP
+device apic
+
+options SCHED_ULE # mandatory to have one scheduler
+options PREEMPTION # needed for decent interrupt processing
+#options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+#options INET6
+options FFS #Berkeley Fast Filesystem
+#options BOOTP #Use BOOTP to obtain IP address/hostname
+options MD_ROOT #MD is a potential root device
+
+#options NFS #Network Filesystem
+#options NFS_ROOT #NFS usable as root device, NFS required
+
+#options MSDOSFS #MSDOS Filesystem
+#options CD9660 #ISO 9660 Filesystem
+#options CD9660_ROOT #CD-ROM usable as root, CD9660 required
+#options DEVFS #Device Filesystem
+#options PROCFS #Process filesystem
+options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
+
+options KDB
+options DDB
+
+options IPFIREWALL
+options IPFIREWALL_DEFAULT_TO_ACCEPT
+options IPDIVERT # divert (for natd)
+
+# Support for bridging and bandwidth limiting
+options DUMMYNET
+device if_bridge
+# Running with less than 1000 seems to give poor timing on
+# qemu, so we set HZ explicitly.
+options HZ=1000
+
+device random # used by ssh
+device pci
+
+# Floppy drives
+device fdc
+
+# ATA and ATAPI devices
+#device ata
+#device atadisk # ATA disk drives
+#device atapicd # ATAPI CDROM drives
+#options ATA_STATIC_ID #Static device numbering
+
+# atkbdc0 controls both the keyboard and the PS/2 mouse
+device atkbdc # At keyboard controller
+device atkbd
+#device psm # do we need the mouse ??
+
+device vga # VGA screen
+
+# syscons is the default console driver, resembling an SCO console
+device sc
+
+# Serial (COM) ports
+device uart
+
+# Audio support
+#device pcm
+
+# PCCARD (PCMCIA) support
+#device card # pccard bus
+#device pcic # PCMCIA bridge
+
+# Parallel port
+#device ppc
+#device ppbus # Parallel port bus (required)
+#device lpt # Printer
+#device plip # TCP/IP over parallel
+#device ppi # Parallel port interface device
+
+#
+# The following Ethernet NICs are all PCI devices.
+#
+device miibus
+device fxp # Intel EtherExpress PRO/100B (82557, 82558)
+device nfe # nVidia nForce MCP on-board Ethernet
+#device xl # 3Com
+device rl # RealTek 8129/8139
+device re # RealTek 8139C+/8169/8169S/8110S
+device sis # National/SiS
+device dc # DEC/Intel 21143 and various workalikes
+device ed
+
+device loop # Network loopback
+device ether # Ethernet support
+device tun # Packet tunnel.
+device pty # Pseudo-ttys (telnet etc)
+device md # Memory "disks"
+#device gif 4 # IPv6 and IPv4 tunneling
+device tap
+
+#options VIMAGE # soner or later we may want to test this
+#options DEVICE_POLLING
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+device bpf # Berkeley packet filter
diff --git a/release/picobsd/qemu/PICOBSD.hints b/release/picobsd/qemu/PICOBSD.hints
new file mode 100644
index 0000000..4f1b403
--- /dev/null
+++ b/release/picobsd/qemu/PICOBSD.hints
@@ -0,0 +1,39 @@
+# $FreeBSD$
+hint.fdc.0.at="isa"
+hint.fdc.0.port="0x3F0"
+hint.fdc.0.irq="6"
+hint.fdc.0.drq="2"
+hint.fd.0.at="fdc0"
+hint.fd.0.drive="0"
+hint.ata.0.at="isa"
+hint.ata.0.port="0x1F0"
+hint.ata.0.irq="14"
+hint.ata.1.at="isa"
+hint.ata.1.port="0x170"
+hint.ata.1.irq="15"
+hint.atkbdc.0.at="isa"
+hint.atkbdc.0.port="0x060"
+hint.atkbd.0.at="atkbdc"
+hint.atkbd.0.irq="1"
+hint.psm.0.at="atkbdc"
+hint.psm.0.irq="12"
+hint.vga.0.at="isa"
+hint.sc.0.at="isa"
+hint.npx.0.at="nexus"
+hint.npx.0.port="0x0F0"
+hint.npx.0.irq="13"
+hint.uart.0.at="isa"
+hint.uart.0.port="0x3F8"
+hint.uart.0.flags="0x10"
+hint.uart.0.irq="4"
+hint.uart.1.at="isa"
+hint.uart.1.port="0x2F8"
+hint.uart.1.irq="3"
+hint.ed.0.at="isa"
+hint.ed.0.port="0x280"
+hint.ed.0.irq="5"
+hint.ed.0.maddr="0xd8000"
+hint.ed.1.at="isa"
+hint.ed.1.port="0x300"
+hint.ed.1.irq="5"
+hint.ed.1.maddr="0xd0000"
diff --git a/release/picobsd/qemu/config b/release/picobsd/qemu/config
new file mode 100644
index 0000000..88f1954
--- /dev/null
+++ b/release/picobsd/qemu/config
@@ -0,0 +1,26 @@
+# configuration for picobsd build script.
+# $FreeBSD$
+# it should only contain variable definitions -- it is sourced
+# by the shell much like rc.conf* files
+
+fd_size="8192"
+
+# To copy individual files you can use the function do_copyfiles_user
+# as below (find_progs locates the programs and their libraries,
+# then you manually copy them.
+#copy_files="
+#"
+do_copyfiles_user() {
+ local dst=$1 # the destination root
+ log "--- put the libraries in /usr/lib to avoid conflicts"
+ mkdir -p ${dst}/usr/lib
+ log "-- import dropbear from its build directory --"
+ find_progs -L / -P /usr/ports/security/dropbear/work/dropbear-0.52 \
+ dbclient dropbear
+ cp -p ${u_progs} ${dst}/bin
+ cp -p ${u_libs} ${dst}/usr/lib
+ log "--- also import ssh, scp and sshd ---"
+ find_progs -L / /usr/bin/ssh /usr/bin/scp /usr/sbin/sshd
+ cp -p ${u_progs} ${dst}/bin
+ cp -p ${u_libs} ${dst}/usr/lib
+}
diff --git a/release/picobsd/qemu/crunch.conf b/release/picobsd/qemu/crunch.conf
new file mode 100644
index 0000000..58a5544
--- /dev/null
+++ b/release/picobsd/qemu/crunch.conf
@@ -0,0 +1,200 @@
+#
+# $FreeBSD$
+#
+# Configuration file for "qemu" images..
+#
+# Depending on your needs, you will almost surely need to
+# add/remove/change programs according to your needs.
+# Remember that some programs require matching kernel options to
+# enable device drivers etc.
+#
+# To figure out how much space is used by each program, do
+#
+# size build_dir-bridge/crunch/*lo
+#
+# Remember that programs require libraries, which add up to the
+# total size. The final binary is build_dir-bridge/mfs.tree/stand/crunch
+# and you can check which libraries it uses with
+#
+# ldd build_dir-bridge/mfs.tree/stand/crunch
+
+# crunchgen configuration to build the crunched binary, see "man crunchgen"
+# We need to specify generic build options, the places where to look
+# for sources, and the list of program and libraries we want to put
+# in the crunched binary.
+#
+# NOTE: the string "/usr/src" below will be automatically replaced with
+# the path set in the 'build' script.
+
+# Default build options. Basically tell the Makefiles
+# that to use the most compact possible version of the code.
+
+buildopts -DWITHOUT_PAM -DRELEASE_CRUNCH -DPPP_NO_NETGRAPH
+buildopts -DTRACEROUTE_NO_IPSEC -DNO_INET6
+buildopts -DWITHOUT_KERBEROS -DWITHOUT_OPENSSL
+
+# Directories where to look for sources of various binaries.
+# @__CWD__@ is a magic keyword in the picobsd's (Makefile.conf)
+# which is replaced with the directory with the picobsd configuration
+# corresponding to your image. This way you can have custom sources
+# in that directory overriding system programs.
+
+srcdirs @__CWD__@/src
+
+# Some programs are especially written for PicoBSD and reside in
+# release/picobsd/tinyware.
+# Put this entry near the head of the list to override standard binaries.
+
+srcdirs /usr/src/release/picobsd/tinyware
+
+# Other standard locations for sources.
+# If a program uses its own source directory, add
+
+srcdirs /usr/src/bin
+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
+srcdirs /usr/src/libexec
+
+# For programs that reside in different places, the best option
+# is to use the command "special XXX srcdir YYY" where XXX is the
+# program name and YYY is the directory path.
+# "special XXX ..." can be used to specify more options, see again
+# the crunchgen manpage.
+
+#--- Basic configuraton
+# init is always necessary (unless you have a replacement, oinit)
+progs init
+
+# fsck is almost always necessary, unless you have everything on the
+# image and use 'tar' or something similar to read/write raw blocks
+# from the floppy.
+
+progs fsck
+
+# ifconfig is needed if you want to configure interfaces.
+progs ifconfig
+
+# You will also need a shell and a bunch of utilities.
+# The standard shell is not that large, but you need many
+# external programs. In fact most of them do not take much space
+# as they merely issue a system call, and print the result.
+# For a more compact version of shell and utilities, you could
+# try busybox, however most system management commands in busybox
+# will not work as they use linux-specific interfaces.
+
+progs sh
+ln sh -sh
+
+# the small utilities
+progs echo
+progs pwd mkdir rmdir
+progs chmod chown
+ln chown chgrp
+progs mv ln cp rm ls
+progs cat tail tee
+progs test
+ln test [
+
+progs less
+ln less more
+progs mount
+progs minigzip
+ln minigzip gzip
+progs kill
+progs df
+progs ps
+progs ns # this is the picobsd version
+ln ns netstat
+progs vm
+progs hostname
+progs login
+progs getty
+progs stty
+progs w
+progs msg
+ln msg dmesg
+progs reboot
+
+progs sysctl
+progs swapon
+progs pwd_mkdb
+progs umount
+progs du
+progs passwd
+
+progs route
+
+# If you want to run natd, remember the alias library
+progs natd
+libs_so -lalias # natd
+progs tcpdump
+special tcpdump srcdir /usr/src/usr.sbin/tcpdump/tcpdump
+libs_so -lpcap # used by tcpdump
+libs_so -lcrypto # used by tcpdump with inet6
+
+# ppp is rather large. Note that as of Jan.01, RELEASE_CRUNCH
+# makes ppp not use libalias, so you cannot have aliasing.
+#progs ppp
+
+# You need an editor. ee is relatively small, though there are
+# smaller ones. vi is much larger.
+# The editor also usually need a curses library.
+progs ee
+
+progs arp
+
+# these require libgeom
+# progs bsdlabel fdisk mdconfig
+
+progs kldload kldunload kldstat
+progs kldxref
+progs grep
+libs_so -lgnuregex -lbz2
+# dhclient-script requires 'sed'
+progs dhclient
+progs sed
+progs date
+progs time
+progs ping
+progs ping6
+progs tar
+
+#progs routed
+progs ipfw
+progs traceroute
+progs mdmfs
+ln mdmfs mount_mfs
+# Various filesystem support -- remember to enable the kernel parts
+# progs mount_msdosfs
+progs mount_nfs
+# progs mount_cd9660
+ln mount_nfs nfs
+ln mount_cd9660 cd9660
+#progs newfs
+#ln newfs mount_mfs
+# ln mount_msdosfs msdos
+
+# For a small ssh client/server use dropbear
+progs jail jexec jls # why not...
+
+
+# Now the libraries
+libs_so -lc # the C library
+libs_so -ll # used by sh (really ?)
+libs_so -lufs # used by mount
+### ee uses ncurses but as a dependency
+#libs_so -lncurses
+libs_so -lm
+libs_so -ledit -lutil
+libs_so -lcrypt
+libs_so -lkvm
+libs_so -lz
+libs_so -lbsdxml
+libs_so -lsbuf
+libs_so -ljail # used by ifconfig
+libs_so -lipsec -lmd # used with ipv6
+libs_so -larchive -lbz2
+libs_so -llzma # added after 207840
diff --git a/release/picobsd/qemu/floppy.tree.exclude b/release/picobsd/qemu/floppy.tree.exclude
new file mode 100644
index 0000000..adfc6cc
--- /dev/null
+++ b/release/picobsd/qemu/floppy.tree.exclude
@@ -0,0 +1,2 @@
+etc/snmpd.conf
+etc/ppp
diff --git a/release/picobsd/tinyware/aps/Makefile b/release/picobsd/tinyware/aps/Makefile
new file mode 100644
index 0000000..d3e4792
--- /dev/null
+++ b/release/picobsd/tinyware/aps/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+#
+PROG=ps
+SRCS+=main.c
+MAN=
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/aps/README b/release/picobsd/tinyware/aps/README
new file mode 100644
index 0000000..f455c7b
--- /dev/null
+++ b/release/picobsd/tinyware/aps/README
@@ -0,0 +1,19 @@
+1998.07.12
+
+This is a small 'ps' replacement, which uses information available via
+procfs(5) interface. It's primitive, but gives you the most important
+informations, i.e. how many processes are running and on which vty, and the
+pid number to kill some of them. :-)
+
+When I have some time, I'll add usual switches and other functions that normal
+'ps' has...
+
+Also, what I'm now inclined to think is that it should be reworked to use
+more general (and less complicated) sysctl(3).
+
+<abial@freebsd.org>
+
+(As of 1998.07.31 this program is no longer used in PicoBSD. See sps(1) in
+TinyWare collection).
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/aps/main.c b/release/picobsd/tinyware/aps/main.c
new file mode 100644
index 0000000..eece247
--- /dev/null
+++ b/release/picobsd/tinyware/aps/main.c
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+/*
+ * Ok, I could extract almost anything from /proc, but I'm too lazy...
+ * I think it will suffice for now.
+ */
+
+int
+main(int argc, char *argv[])
+{
+ DIR *d;
+ struct dirent *e;
+ FILE *fd;
+ char buf[100];
+ char *tok, *sep=" ", *sep1=",";
+ char *name, *pid, *ppid, *uid, *gid;
+ char *pgid, *sid, *tty, *cred;
+ char *major, *minor;
+ char con[10];
+
+ d=opendir("/proc");
+ printf(" PID PPID TTY COMMAND\n");
+ while((e=readdir(d))!=NULL) {
+ /* Skip '.' and '..' */
+ if(e->d_name[0]=='.') continue;
+ /* Skip 'curproc' - it's us */
+ if(e->d_name[0]=='c') continue;
+ sprintf(buf,"/proc/%s/status",e->d_name);
+ fd=fopen(buf,"r");
+ fgets(buf,99,fd);
+ fclose(fd);
+ name=strtok(buf,sep);
+ pid=strtok(NULL,sep);
+ ppid=strtok(NULL,sep);
+ pgid=strtok(NULL,sep);
+ sid=strtok(NULL,sep);
+ tty=strtok(NULL,sep);
+ tok=strtok(NULL,sep); /* flags */
+ tok=strtok(NULL,sep); /* start */
+ tok=strtok(NULL,sep); /* user time */
+ tok=strtok(NULL,sep); /* system time */
+ tok=strtok(NULL,sep); /* wchan */
+ cred=strtok(NULL,sep); /* credentials */
+ major=strtok(tty,sep1);
+ minor=strtok(NULL,sep1);
+ if(strcmp(minor,"-1")==0) {
+ minor="?";
+ }
+ if(strcmp(major,"-1")==0) {
+ major="?";
+ } else if(strcmp(major,"12")==0) {
+ major="v";
+ } else if(strcmp(major,"0")==0) {
+ major="con";
+ minor="-";
+ } else if(strcmp(major,"5")==0) {
+ major="p";
+ } else major="x";
+ if((strcmp(major,"v")==0) && (strcmp(minor,"255")==0)) {
+ major="con";
+ minor="-";
+ }
+ sprintf(con,"%s%s",major,minor);
+ printf("%5s %5s %4s (%s)\n",pid,ppid,con,name);
+
+ }
+ closedir(d);
+ exit(0);
+}
diff --git a/release/picobsd/tinyware/help/Makefile b/release/picobsd/tinyware/help/Makefile
new file mode 100644
index 0000000..5c07536
--- /dev/null
+++ b/release/picobsd/tinyware/help/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+#
+PROG=help
+SRCS+=help.c
+MAN=
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/help/README b/release/picobsd/tinyware/help/README
new file mode 100644
index 0000000..9c9900f
--- /dev/null
+++ b/release/picobsd/tinyware/help/README
@@ -0,0 +1,8 @@
+1998.02.20
+
+This is work in progress. Eventually I'll prepare the help system for newbies,
+and these files are just the beginning of it...
+
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/help/help.c b/release/picobsd/tinyware/help/help.c
new file mode 100644
index 0000000..b57b4f6
--- /dev/null
+++ b/release/picobsd/tinyware/help/help.c
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 1998 Eric P. Scott <eps@sirius.com>
+ * Copyright (c) 1998 Andrzej Bialecki <abial@freebsd.org>
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <ar.h>
+#include <sys/ioctl.h>
+
+int display(FILE *, const char *);
+
+static int cnt, crt=-1;
+
+int
+main(int argc, char *argv[])
+{
+ register int i, s;
+ FILE *fd;
+ struct ttysize ts;
+
+ if (!(fd=fopen("/help.a", "r"))) {
+ (void)fputs("Couldn't open help archive.\n", stderr);
+ exit(1);
+ }
+ cnt=0;
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &ts)>=0) {
+ crt=ts.ts_lines-1;
+ }
+ if (crt<3) crt=23;
+ s=display(fd, argc>1 ? argv[1] : "help");
+ if (s<0) s=0;
+ else for (i=2;i<argc;) {
+ rewind(fd);
+ s|=display(fd, argv[i++]);
+ if (s<0) {
+ s=0;
+ break;
+ }
+ }
+ (void)fclose(fd);
+ exit(s);
+}
+
+int
+more(void)
+{
+ char buf[8];
+
+ (void)fflush(stdout);
+ (void)fputs("\033[7mPress Enter to continue\033[m", stderr);
+ (void)fflush(stderr);
+ cnt=0;
+ if (fgets(buf, sizeof buf, stdin)) return 0;
+ (void)fputc('\n', stderr);
+ return 1;
+}
+
+int
+display(FILE *fd, const char *fname)
+{
+ register char *p;
+ register int c, n, o;
+ struct ar_hdr ar;
+ char aname[20];
+
+ if (!fgets(aname, sizeof aname, fd)) {
+ return 1;
+ }
+ if (strncmp(aname, ARMAG, SARMAG)) return 1;
+ (void)snprintf(aname, sizeof(aname), "%s/", fname);
+ for (;;) {
+ if (fread((void *)&ar, sizeof ar, 1, fd)!=1) return 1;
+ if (strncmp(ar.ar_fmag, ARFMAG, 2)) return 1;
+ n=0;
+ p=ar.ar_size;
+ do {
+ if ((c=(int)(*p++-'0'))<0||c>9) break;
+ n*=10; n+=c;
+ } while (p<&ar.ar_size[sizeof ar.ar_size]);
+ if (!strncmp(ar.ar_name, aname, strlen(aname))) break;
+ if (fseek(fd, (long)n, SEEK_CUR)<0) return 1;
+ if ((n&1)&&fgetc(fd)!='\n') return 1;
+ }
+ if (cnt>=crt&&more()) return -1;
+ (void)fputc('\n', stdout);
+ cnt++;
+ o=0; while (o<n&&(c=fgetc(fd))!=EOF) {
+ per:
+ o++;
+ (void)fputc(c, stdout);
+ if (c!='\n') continue;
+ if (++cnt<crt) continue;
+ if (o>=n||(c=fgetc(fd))==EOF) break;
+ if (more()) return -1;
+ goto per;
+ }
+ if (cnt>=crt&&more()) return -1;
+ (void)fputc('\n', stdout);
+ cnt++;
+ if (!strcmp(fname, "help")) {
+ rewind(fd);
+ (void)fgets(aname, sizeof aname, fd);
+ if (cnt>=crt&&more()) return -1;
+ (void)fputs("The following help items are available:\n",
+ stdout);
+ cnt++;
+ o=0;
+ while (fread((void *)&ar, sizeof ar, 1, fd)==1) {
+ if (strncmp(ar.ar_fmag, ARFMAG, 2)) break;
+ if ((o%6)==0) {
+ (void)fputc('\n', stdout);
+ if (++cnt>=crt&&more()) return -1;
+ }
+ *(index(ar.ar_name,'/'))=' ';
+ (void)printf("%.13s", ar.ar_name);
+ ++o;
+ n=0;
+ p=ar.ar_size;
+ do {
+ if ((c=(int)(*p++-'0'))<0||c>9) break;
+ n*=10; n+=c;
+ } while (p<&ar.ar_size[sizeof ar.ar_size]);
+ if (fseek(fd, (long)n, SEEK_CUR)<0) break;
+ if ((n&1)&&fgetc(fd)!='\n') break;
+ }
+ if (cnt>=crt&&more()) return -1;
+ (void)fputc('\n', stdout);
+ cnt++;
+ }
+ return 0;
+}
diff --git a/release/picobsd/tinyware/login/Makefile b/release/picobsd/tinyware/login/Makefile
new file mode 100644
index 0000000..bc6156c
--- /dev/null
+++ b/release/picobsd/tinyware/login/Makefile
@@ -0,0 +1,25 @@
+# From: @(#)Makefile 8.1 (Berkeley) 7/19/93
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+.PATH: ${.CURDIR}/../../../../usr.bin/login
+
+PROG= login
+SRCS= pico-login.c login_fbtab.c
+MAN= login.1
+
+CFLAGS+=-DLOGALL
+
+LIBADD= util crypt
+
+.if ${MK_PAM_SUPPORT} != "no"
+CFLAGS+= -DUSE_PAM
+LIBADD+= pam
+.endif
+
+BINOWN= root
+BINMODE=4555
+PRECIOUSPROG=
+
+.include <bsd.prog.mk>
diff --git a/release/picobsd/tinyware/login/README b/release/picobsd/tinyware/login/README
new file mode 100644
index 0000000..4dba334
--- /dev/null
+++ b/release/picobsd/tinyware/login/README
@@ -0,0 +1,6 @@
+$FreeBSD$
+
+This is a modified login version for PicoBSD purposes, which does
+not demand PAM.
+The "login.c" file is replaced by pico-login.c in this directory,
+the remaining files are taken from usr.bin/login/
diff --git a/release/picobsd/tinyware/login/pathnames.h b/release/picobsd/tinyware/login/pathnames.h
new file mode 100644
index 0000000..333c2ca
--- /dev/null
+++ b/release/picobsd/tinyware/login/pathnames.h
@@ -0,0 +1,43 @@
+/*-
+ * 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
+ * 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.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/9/93
+ * $FreeBSD$
+ */
+
+#include <paths.h>
+
+#define _PATH_HUSHLOGIN ".hushlogin"
+#define _PATH_MOTDFILE "/etc/motd"
+#define _PATH_LOGACCESS "/etc/login.access"
+#define _PATH_FBTAB "/etc/fbtab"
+#define _PATH_LOGINDEVPERM "/etc/logindevperm"
diff --git a/release/picobsd/tinyware/login/pico-login.c b/release/picobsd/tinyware/login/pico-login.c
new file mode 100644
index 0000000..e540ca8
--- /dev/null
+++ b/release/picobsd/tinyware/login/pico-login.c
@@ -0,0 +1,1093 @@
+/*-
+ * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
+ * 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.
+ */
+
+#if 0
+static char copyright[] =
+"@(#) Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)login.c 8.4 (Berkeley) 4/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+/*
+ * login [ name ]
+ * login -h hostname (for telnetd, etc.)
+ * login -f name (for pre-authenticated login: datakit, xterm, etc.)
+ */
+
+#include <sys/copyright.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <grp.h>
+#include <libutil.h>
+#include <login_cap.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <ttyent.h>
+#include <unistd.h>
+#include <utmpx.h>
+
+#ifdef USE_PAM
+#include <security/pam_appl.h>
+#include <security/openpam.h>
+#include <sys/wait.h>
+#endif /* USE_PAM */
+
+#include "pathnames.h"
+
+void badlogin(char *);
+void checknologin(void);
+void dolastlog(int);
+void getloginname(void);
+void motd(const char *);
+int rootterm(char *);
+void sigint(int);
+void sleepexit(int);
+void refused(char *,char *,int);
+char *stypeof(char *);
+void timedout(int);
+int login_access(char *, char *);
+void login_fbtab(char *, uid_t, gid_t);
+
+#ifdef USE_PAM
+static int auth_pam(void);
+static int export_pam_environment(void);
+static int ok_to_export(const char *);
+
+static pam_handle_t *pamh = NULL;
+static char **environ_pam;
+
+#define PAM_END { \
+ if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) \
+ syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e)); \
+ if ((e = pam_close_session(pamh,0)) != PAM_SUCCESS) \
+ syslog(LOG_ERR, "pam_close_session: %s", pam_strerror(pamh, e)); \
+ if ((e = pam_end(pamh, e)) != PAM_SUCCESS) \
+ syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e)); \
+}
+#endif
+
+static int auth_traditional(void);
+static void usage(void);
+
+#define TTYGRPNAME "tty" /* name of group to own ttys */
+#define DEFAULT_BACKOFF 3
+#define DEFAULT_RETRIES 10
+#define DEFAULT_PROMPT "login: "
+#define DEFAULT_PASSWD_PROMPT "Password:"
+
+/*
+ * This bounds the time given to login. Not a define so it can
+ * be patched on machines where it's too small.
+ */
+u_int timeout = 300;
+
+/* Buffer for signal handling of timeout */
+jmp_buf timeout_buf;
+
+struct passwd *pwd;
+int failures;
+char *term, *envinit[1], *hostname, *tty, *username;
+const char *passwd_prompt, *prompt;
+char full_hostname[MAXHOSTNAMELEN];
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char **environ;
+ struct group *gr;
+ struct stat st;
+ struct utmpx utmp;
+ int rootok, retries, backoff;
+ int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
+ int changepass;
+ time_t now, warntime;
+ uid_t uid, euid;
+ gid_t egid;
+ char *p, *ttyn;
+ char tbuf[MAXPATHLEN + 2];
+ char tname[sizeof(_PATH_TTY) + 10];
+ const char *shell = NULL;
+ login_cap_t *lc = NULL;
+ int UT_HOSTSIZE = sizeof(utmp.ut_host);
+ int UT_NAMESIZE = sizeof(utmp.ut_user);
+#ifdef USE_PAM
+ pid_t pid;
+ int e;
+#endif /* USE_PAM */
+
+ (void)signal(SIGQUIT, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGHUP, SIG_IGN);
+ if (setjmp(timeout_buf)) {
+ if (failures)
+ badlogin(tbuf);
+ (void)fprintf(stderr, "Login timed out after %d seconds\n",
+ timeout);
+ exit(0);
+ }
+ (void)signal(SIGALRM, timedout);
+ (void)alarm(timeout);
+ (void)setpriority(PRIO_PROCESS, 0, 0);
+
+ openlog("login", LOG_ODELAY, LOG_AUTH);
+
+ /*
+ * -p is used by getty to tell login not to destroy the environment
+ * -f is used to skip a second login authentication
+ * -h is used by other servers to pass the name of the remote
+ * host to login so that it may be placed in utmp and wtmp
+ */
+ *full_hostname = '\0';
+ term = NULL;
+
+ fflag = hflag = pflag = 0;
+ uid = getuid();
+ euid = geteuid();
+ egid = getegid();
+ while ((ch = getopt(argc, argv, "fh:p")) != -1)
+ switch (ch) {
+ case 'f':
+ fflag = 1;
+ break;
+ case 'h':
+ if (uid)
+ errx(1, "-h option: %s", strerror(EPERM));
+ hflag = 1;
+ if (strlcpy(full_hostname, optarg,
+ sizeof(full_hostname)) >= sizeof(full_hostname))
+ errx(1, "-h option: %s: exceeds maximum "
+ "hostname size", optarg);
+
+ trimdomain(optarg, UT_HOSTSIZE);
+
+ if (strlen(optarg) > UT_HOSTSIZE) {
+ struct addrinfo hints, *res;
+ int ga_err;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ ga_err = getaddrinfo(optarg, NULL, &hints,
+ &res);
+ if (ga_err == 0) {
+ char hostbuf[MAXHOSTNAMELEN];
+
+ getnameinfo(res->ai_addr,
+ res->ai_addrlen,
+ hostbuf,
+ sizeof(hostbuf), NULL, 0,
+ NI_NUMERICHOST);
+ optarg = strdup(hostbuf);
+ if (optarg == NULL) {
+ syslog(LOG_NOTICE,
+ "strdup(): %m");
+ sleepexit(1);
+ }
+ } else
+ optarg = "invalid hostname";
+ if (res != NULL)
+ freeaddrinfo(res);
+ }
+ hostname = optarg;
+ break;
+ case 'p':
+ pflag = 1;
+ break;
+ case '?':
+ default:
+ if (!uid)
+ syslog(LOG_ERR, "invalid flag %c", ch);
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (*argv) {
+ username = *argv;
+ ask = 0;
+ } else
+ ask = 1;
+
+ for (cnt = getdtablesize(); cnt > 2; cnt--)
+ (void)close(cnt);
+
+ ttyn = ttyname(STDIN_FILENO);
+ if (ttyn == NULL || *ttyn == '\0') {
+ (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
+ ttyn = tname;
+ }
+ if ((tty = strrchr(ttyn, '/')) != NULL)
+ ++tty;
+ else
+ tty = ttyn;
+
+ /*
+ * Get "login-retries" & "login-backoff" from default class
+ */
+ lc = login_getclass(NULL);
+ prompt = login_getcapstr(lc, "login_prompt",
+ DEFAULT_PROMPT, DEFAULT_PROMPT);
+ passwd_prompt = login_getcapstr(lc, "passwd_prompt",
+ DEFAULT_PASSWD_PROMPT, DEFAULT_PASSWD_PROMPT);
+ retries = login_getcapnum(lc, "login-retries", DEFAULT_RETRIES,
+ DEFAULT_RETRIES);
+ backoff = login_getcapnum(lc, "login-backoff", DEFAULT_BACKOFF,
+ DEFAULT_BACKOFF);
+ login_close(lc);
+ lc = NULL;
+
+ for (cnt = 0;; ask = 1) {
+ if (ask) {
+ fflag = 0;
+ getloginname();
+ }
+ rootlogin = 0;
+ rootok = rootterm(tty); /* Default (auth may change) */
+
+ if (strlen(username) > UT_NAMESIZE)
+ username[UT_NAMESIZE] = '\0';
+
+ /*
+ * Note if trying multiple user names; log failures for
+ * previous user name, but don't bother logging one failure
+ * for nonexistent name (mistyped username).
+ */
+ if (failures && strcmp(tbuf, username)) {
+ if (failures > (pwd ? 0 : 1))
+ badlogin(tbuf);
+ }
+ (void)strlcpy(tbuf, username, sizeof(tbuf));
+
+ pwd = getpwnam(username);
+
+ /*
+ * if we have a valid account name, and it doesn't have a
+ * password, or the -f option was specified and the caller
+ * is root or the caller isn't changing their uid, don't
+ * authenticate.
+ */
+ if (pwd != NULL) {
+ if (pwd->pw_uid == 0)
+ rootlogin = 1;
+
+ if (fflag && (uid == (uid_t)0 ||
+ uid == (uid_t)pwd->pw_uid)) {
+ /* already authenticated */
+ break;
+ } else if (pwd->pw_passwd[0] == '\0') {
+ if (!rootlogin || rootok) {
+ /* pretend password okay */
+ rval = 0;
+ goto ttycheck;
+ }
+ }
+ }
+
+ fflag = 0;
+
+ (void)setpriority(PRIO_PROCESS, 0, -4);
+
+#ifdef USE_PAM
+ /*
+ * Try to authenticate using PAM. If a PAM system error
+ * occurs, perhaps because of a botched configuration,
+ * then fall back to using traditional Unix authentication.
+ */
+ if ((rval = auth_pam()) == -1)
+#endif /* USE_PAM */
+ rval = auth_traditional();
+
+ (void)setpriority(PRIO_PROCESS, 0, 0);
+
+#ifdef USE_PAM
+ /*
+ * PAM authentication may have changed "pwd" to the
+ * entry for the template user. Check again to see if
+ * this is a root login after all.
+ */
+ if (pwd != NULL && pwd->pw_uid == 0)
+ rootlogin = 1;
+#endif /* USE_PAM */
+
+ ttycheck:
+ /*
+ * If trying to log in as root without Kerberos,
+ * but with insecure terminal, refuse the login attempt.
+ */
+ if (pwd && !rval) {
+ if (rootlogin && !rootok)
+ refused(NULL, "NOROOT", 0);
+ else /* valid password & authenticated */
+ break;
+ }
+
+ (void)printf("Login incorrect\n");
+ failures++;
+
+ /*
+ * we allow up to 'retry' (10) tries,
+ * but after 'backoff' (3) we start backing off
+ */
+ if (++cnt > backoff) {
+ if (cnt >= retries) {
+ badlogin(username);
+ sleepexit(1);
+ }
+ sleep((u_int)((cnt - backoff) * 5));
+ }
+ }
+
+ /* committed to login -- turn off timeout */
+ (void)alarm((u_int)0);
+ (void)signal(SIGHUP, SIG_DFL);
+
+ endpwent();
+
+ /*
+ * Establish the login class.
+ */
+ lc = login_getpwclass(pwd);
+
+ /* if user not super-user, check for disabled logins */
+ if (!rootlogin)
+ auth_checknologin(lc);
+
+ quietlog = login_getcapbool(lc, "hushlogin", 0);
+ /*
+ * Switching needed for NFS with root access disabled.
+ *
+ * XXX: This change fails to modify the additional groups for the
+ * process, and as such, may restrict rights normally granted
+ * through those groups.
+ */
+ (void)setegid(pwd->pw_gid);
+ (void)seteuid(rootlogin ? 0 : pwd->pw_uid);
+ if (!*pwd->pw_dir || chdir(pwd->pw_dir) < 0) {
+ if (login_getcapbool(lc, "requirehome", 0))
+ refused("Home directory not available", "HOMEDIR", 1);
+ if (chdir("/") < 0)
+ refused("Cannot find root directory", "ROOTDIR", 1);
+ if (!quietlog || *pwd->pw_dir)
+ printf("No home directory.\nLogging in with home = \"/\".\n");
+ pwd->pw_dir = "/";
+ }
+ (void)seteuid(euid);
+ (void)setegid(egid);
+ if (!quietlog)
+ quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
+
+ now = time(NULL);
+
+#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
+
+ warntime = login_getcaptime(lc, "warnexpire", DEFAULT_WARN,
+ DEFAULT_WARN);
+
+ if (pwd->pw_expire) {
+ if (now >= pwd->pw_expire) {
+ refused("Sorry -- your account has expired", "EXPIRED",
+ 1);
+ } else if (pwd->pw_expire - now < warntime && !quietlog)
+ (void)printf("Warning: your account expires on %s",
+ ctime(&pwd->pw_expire));
+ }
+
+ warntime = login_getcaptime(lc, "warnpassword", DEFAULT_WARN,
+ DEFAULT_WARN);
+
+ changepass = 0;
+ if (pwd->pw_change) {
+ if (now >= pwd->pw_change) {
+ (void)printf("Sorry -- your password has expired.\n");
+ changepass = 1;
+ syslog(LOG_INFO, "%s Password expired - forcing change",
+ pwd->pw_name);
+ } else if (pwd->pw_change - now < warntime && !quietlog)
+ (void)printf("Warning: your password expires on %s",
+ ctime(&pwd->pw_change));
+ }
+
+ if (lc != NULL) {
+ if (hostname) {
+ struct addrinfo hints, *res;
+ int ga_err;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ ga_err = getaddrinfo(full_hostname, NULL, &hints,
+ &res);
+ if (ga_err == 0) {
+ char hostbuf[MAXHOSTNAMELEN];
+
+ getnameinfo(res->ai_addr, res->ai_addrlen,
+ hostbuf, sizeof(hostbuf), NULL, 0,
+ NI_NUMERICHOST);
+ if ((optarg = strdup(hostbuf)) == NULL) {
+ syslog(LOG_NOTICE, "strdup(): %m");
+ sleepexit(1);
+ }
+ } else
+ optarg = NULL;
+ if (res != NULL)
+ freeaddrinfo(res);
+ if (!auth_hostok(lc, full_hostname, optarg))
+ refused("Permission denied", "HOST", 1);
+ }
+
+ if (!auth_ttyok(lc, tty))
+ refused("Permission denied", "TTY", 1);
+
+ if (!auth_timeok(lc, time(NULL)))
+ refused("Logins not available right now", "TIME", 1);
+ }
+ shell = login_getcapstr(lc, "shell", pwd->pw_shell, pwd->pw_shell);
+ if (*pwd->pw_shell == '\0')
+ pwd->pw_shell = _PATH_BSHELL;
+ if (*shell == '\0') /* Not overridden */
+ shell = pwd->pw_shell;
+ if ((shell = strdup(shell)) == NULL) {
+ syslog(LOG_NOTICE, "strdup(): %m");
+ sleepexit(1);
+ }
+
+#ifdef LOGIN_ACCESS
+ if (login_access(pwd->pw_name, hostname ? full_hostname : tty) == 0)
+ refused("Permission denied", "ACCESS", 1);
+#endif /* LOGIN_ACCESS */
+
+#if 1
+ ulog_login(tty, username, hostname);
+#else
+ /* Nothing else left to fail -- really log in. */
+ memset((void *)&utmp, 0, sizeof(utmp));
+ (void)gettimeofday(&utmp.ut_tv, NULL);
+ (void)strncpy(utmp.ut_user, username, sizeof(utmp.ut_user));
+ if (hostname)
+ (void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
+ (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
+ login(&utmp);
+#endif
+
+ dolastlog(quietlog);
+
+ /*
+ * Set device protections, depending on what terminal the
+ * user is logged in. This feature is used on Suns to give
+ * console users better privacy.
+ */
+ login_fbtab(tty, pwd->pw_uid, pwd->pw_gid);
+
+ /*
+ * Clear flags of the tty. None should be set, and when the
+ * user sets them otherwise, this can cause the chown to fail.
+ * Since it isn't clear that flags are useful on character
+ * devices, we just clear them.
+ */
+ if (chflags(ttyn, 0) && errno != EOPNOTSUPP)
+ syslog(LOG_ERR, "chflags(%s): %m", ttyn);
+ if (chown(ttyn, pwd->pw_uid,
+ (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid))
+ syslog(LOG_ERR, "chown(%s): %m", ttyn);
+
+
+ /*
+ * Preserve TERM if it happens to be already set.
+ */
+ if ((term = getenv("TERM")) != NULL) {
+ if ((term = strdup(term)) == NULL) {
+ syslog(LOG_NOTICE,
+ "strdup(): %m");
+ sleepexit(1);
+ }
+ }
+
+ /*
+ * Exclude cons/vt/ptys only, assume dialup otherwise
+ * TODO: Make dialup tty determination a library call
+ * for consistency (finger etc.)
+ */
+ if (hostname==NULL && isdialuptty(tty))
+ syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
+
+#ifdef LOGALL
+ /*
+ * Syslog each successful login, so we don't have to watch hundreds
+ * of wtmp or lastlogin files.
+ */
+ if (hostname)
+ syslog(LOG_INFO, "login from %s on %s as %s",
+ full_hostname, tty, pwd->pw_name);
+ else
+ syslog(LOG_INFO, "login on %s as %s",
+ tty, pwd->pw_name);
+#endif
+
+ /*
+ * If fflag is on, assume caller/authenticator has logged root login.
+ */
+ if (rootlogin && fflag == 0)
+ {
+ if (hostname)
+ syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
+ username, tty, full_hostname);
+ else
+ syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s",
+ username, tty);
+ }
+
+ /*
+ * Destroy environment unless user has requested its preservation.
+ * We need to do this before setusercontext() because that may
+ * set or reset some environment variables.
+ */
+ if (!pflag)
+ environ = envinit;
+
+ /*
+ * PAM modules might add supplementary groups during pam_setcred().
+ */
+ if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) != 0) {
+ syslog(LOG_ERR, "setusercontext() failed - exiting");
+ exit(1);
+ }
+
+#ifdef USE_PAM
+ if (pamh) {
+ if ((e = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_open_session: %s",
+ pam_strerror(pamh, e));
+ } else if ((e = pam_setcred(pamh, PAM_ESTABLISH_CRED))
+ != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_setcred: %s",
+ pam_strerror(pamh, e));
+ }
+
+ /*
+ * Add any environmental variables that the
+ * PAM modules may have set.
+ * Call *after* opening session!
+ */
+ if (pamh) {
+ environ_pam = pam_getenvlist(pamh);
+ if (environ_pam)
+ export_pam_environment();
+ }
+
+ /*
+ * We must fork() before setuid() because we need to call
+ * pam_close_session() as root.
+ */
+ pid = fork();
+ if (pid < 0) {
+ err(1, "fork");
+ PAM_END;
+ exit(0);
+ } else if (pid) {
+ /* parent - wait for child to finish, then cleanup
+ session */
+ wait(NULL);
+ PAM_END;
+ exit(0);
+ } else {
+ if ((e = pam_end(pamh, 0)) != PAM_SUCCESS)
+ syslog(LOG_ERR, "pam_end: %s",
+ pam_strerror(pamh, e));
+ }
+ }
+#endif /* USE_PAM */
+
+ /*
+ * We don't need to be root anymore, so
+ * set the user and session context
+ */
+ if (setlogin(username) != 0) {
+ syslog(LOG_ERR, "setlogin(%s): %m - exiting", username);
+ exit(1);
+ }
+ if (setusercontext(lc, pwd, pwd->pw_uid,
+ LOGIN_SETALL & ~(LOGIN_SETLOGIN|LOGIN_SETGROUP)) != 0) {
+ syslog(LOG_ERR, "setusercontext() failed - exiting");
+ exit(1);
+ }
+
+ (void)setenv("SHELL", pwd->pw_shell, 1);
+ (void)setenv("HOME", pwd->pw_dir, 1);
+ if (term != NULL && *term != '\0')
+ (void)setenv("TERM", term, 1); /* Preset overrides */
+ else {
+ (void)setenv("TERM", stypeof(tty), 0); /* Fallback doesn't */
+ }
+ (void)setenv("LOGNAME", username, 1);
+ (void)setenv("USER", username, 1);
+ (void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
+
+ if (!quietlog) {
+ const char *cw;
+
+ cw = login_getcapstr(lc, "copyright", NULL, NULL);
+ if (cw != NULL && access(cw, F_OK) == 0)
+ motd(cw);
+ else
+ (void)printf("%s\n\t%s %s\n",
+ "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
+ "The Regents of the University of California. ",
+ "All rights reserved.");
+
+ (void)printf("\n");
+
+ cw = login_getcapstr(lc, "welcome", NULL, NULL);
+ if (cw == NULL || access(cw, F_OK) != 0)
+ cw = _PATH_MOTDFILE;
+ motd(cw);
+
+ cw = getenv("MAIL"); /* $MAIL may have been set by class */
+ if (cw != NULL)
+ strlcpy(tbuf, cw, sizeof(tbuf));
+ else
+ snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR,
+ pwd->pw_name);
+ if (stat(tbuf, &st) == 0 && st.st_size != 0)
+ (void)printf("You have %smail.\n",
+ (st.st_mtime > st.st_atime) ? "new " : "");
+ }
+
+ login_close(lc);
+
+ (void)signal(SIGALRM, SIG_DFL);
+ (void)signal(SIGQUIT, SIG_DFL);
+ (void)signal(SIGINT, SIG_DFL);
+ (void)signal(SIGTSTP, SIG_IGN);
+
+ /*
+ * Login shells have a leading '-' in front of argv[0]
+ */
+ if (snprintf(tbuf, sizeof(tbuf), "-%s",
+ (p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell) >=
+ sizeof(tbuf)) {
+ syslog(LOG_ERR, "user: %s: shell exceeds maximum pathname size",
+ username);
+ errx(1, "shell exceeds maximum pathname size");
+ }
+
+ execlp(shell, tbuf, (char *)0);
+ err(1, "%s", shell);
+}
+
+static int
+auth_traditional()
+{
+ int rval;
+ char *p;
+ char *ep;
+ char *salt;
+
+ rval = 1;
+ salt = pwd != NULL ? pwd->pw_passwd : "xx";
+
+ p = getpass(passwd_prompt);
+ ep = crypt(p, salt);
+
+ if (pwd) {
+ if (!p[0] && pwd->pw_passwd[0])
+ ep = ":";
+ if (strcmp(ep, pwd->pw_passwd) == 0)
+ rval = 0;
+ }
+
+ /* clear entered password */
+ memset(p, 0, strlen(p));
+ return rval;
+}
+
+#ifdef USE_PAM
+/*
+ * Attempt to authenticate the user using PAM. Returns 0 if the user is
+ * authenticated, or 1 if not authenticated. If some sort of PAM system
+ * error occurs (e.g., the "/etc/pam.conf" file is missing) then this
+ * function returns -1. This can be used as an indication that we should
+ * fall back to a different authentication mechanism.
+ */
+static int
+auth_pam()
+{
+ const char *tmpl_user;
+ const void *item;
+ int rval;
+ int e;
+ static struct pam_conv conv = { openpam_ttyconv, NULL };
+
+ if ((e = pam_start("login", username, &conv, &pamh)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
+ return -1;
+ }
+ if ((e = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_set_item(PAM_TTY): %s",
+ pam_strerror(pamh, e));
+ return -1;
+ }
+ if (hostname != NULL &&
+ (e = pam_set_item(pamh, PAM_RHOST, full_hostname)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
+ pam_strerror(pamh, e));
+ return -1;
+ }
+ e = pam_authenticate(pamh, 0);
+ switch (e) {
+
+ case PAM_SUCCESS:
+ /*
+ * With PAM we support the concept of a "template"
+ * user. The user enters a login name which is
+ * authenticated by PAM, usually via a remote service
+ * such as RADIUS or TACACS+. If authentication
+ * succeeds, a different but related "template" name
+ * is used for setting the credentials, shell, and
+ * home directory. The name the user enters need only
+ * exist on the remote authentication server, but the
+ * template name must be present in the local password
+ * database.
+ *
+ * This is supported by two various mechanisms in the
+ * individual modules. However, from the application's
+ * point of view, the template user is always passed
+ * back as a changed value of the PAM_USER item.
+ */
+ if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
+ PAM_SUCCESS) {
+ tmpl_user = (const char *) item;
+ if (strcmp(username, tmpl_user) != 0)
+ pwd = getpwnam(tmpl_user);
+ } else
+ syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
+ pam_strerror(pamh, e));
+ rval = 0;
+ break;
+
+ case PAM_AUTH_ERR:
+ case PAM_USER_UNKNOWN:
+ case PAM_MAXTRIES:
+ rval = 1;
+ break;
+
+ default:
+ syslog(LOG_ERR, "pam_authenticate: %s", pam_strerror(pamh, e));
+ rval = -1;
+ break;
+ }
+
+ if (rval == 0) {
+ e = pam_acct_mgmt(pamh, 0);
+ if (e == PAM_NEW_AUTHTOK_REQD) {
+ e = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (e != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_chauthtok: %s",
+ pam_strerror(pamh, e));
+ rval = 1;
+ }
+ } else if (e != PAM_SUCCESS) {
+ rval = 1;
+ }
+ }
+
+ if (rval != 0) {
+ if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
+ }
+ pamh = NULL;
+ }
+ return rval;
+}
+
+static int
+export_pam_environment()
+{
+ char **pp;
+
+ for (pp = environ_pam; *pp != NULL; pp++) {
+ if (ok_to_export(*pp))
+ (void) putenv(*pp);
+ free(*pp);
+ }
+ return PAM_SUCCESS;
+}
+
+/*
+ * Sanity checks on PAM environmental variables:
+ * - Make sure there is an '=' in the string.
+ * - Make sure the string doesn't run on too long.
+ * - Do not export certain variables. This list was taken from the
+ * Solaris pam_putenv(3) man page.
+ */
+static int
+ok_to_export(s)
+ const char *s;
+{
+ static const char *noexport[] = {
+ "SHELL", "HOME", "LOGNAME", "MAIL", "CDPATH",
+ "IFS", "PATH", NULL
+ };
+ const char **pp;
+ size_t n;
+
+ if (strlen(s) > 1024 || strchr(s, '=') == NULL)
+ return 0;
+ if (strncmp(s, "LD_", 3) == 0)
+ return 0;
+ for (pp = noexport; *pp != NULL; pp++) {
+ n = strlen(*pp);
+ if (s[n] == '=' && strncmp(s, *pp, n) == 0)
+ return 0;
+ }
+ return 1;
+}
+#endif /* USE_PAM */
+
+static void
+usage()
+{
+
+ (void)fprintf(stderr, "usage: login [-fp] [-h hostname] [username]\n");
+ exit(1);
+}
+
+/*
+ * Allow for authentication style and/or kerberos instance
+ */
+
+#define NBUFSIZ 128 // XXX was UT_NAMESIZE + 64
+
+void
+getloginname()
+{
+ int ch;
+ char *p;
+ static char nbuf[NBUFSIZ];
+
+ for (;;) {
+ (void)printf("%s", prompt);
+ for (p = nbuf; (ch = getchar()) != '\n'; ) {
+ if (ch == EOF) {
+ badlogin(username);
+ exit(0);
+ }
+ if (p < nbuf + (NBUFSIZ - 1))
+ *p++ = ch;
+ }
+ if (p > nbuf) {
+ if (nbuf[0] == '-')
+ (void)fprintf(stderr,
+ "login names may not start with '-'.\n");
+ else {
+ *p = '\0';
+ username = nbuf;
+ break;
+ }
+ }
+ }
+}
+
+int
+rootterm(ttyn)
+ char *ttyn;
+{
+ struct ttyent *t;
+
+ return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
+}
+
+volatile int motdinterrupt;
+
+void
+sigint(signo)
+ int signo __unused;
+{
+ motdinterrupt = 1;
+}
+
+void
+motd(motdfile)
+ const char *motdfile;
+{
+ int fd, nchars;
+ sig_t oldint;
+ char tbuf[256];
+
+ if ((fd = open(motdfile, O_RDONLY, 0)) < 0)
+ return;
+ motdinterrupt = 0;
+ oldint = signal(SIGINT, sigint);
+ while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0 && !motdinterrupt)
+ (void)write(fileno(stdout), tbuf, nchars);
+ (void)signal(SIGINT, oldint);
+ (void)close(fd);
+}
+
+/* ARGSUSED */
+void
+timedout(signo)
+ int signo;
+{
+
+ longjmp(timeout_buf, signo);
+}
+
+
+void
+dolastlog(quiet)
+ int quiet;
+{
+#if 0 /* XXX not implemented after utmp->utmpx change */
+ struct lastlog ll;
+ int fd;
+
+ if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
+ (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
+ if (!quiet) {
+ if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
+ ll.ll_time != 0) {
+ (void)printf("Last login: %.*s ",
+ 24-5, (char *)ctime(&ll.ll_time));
+ if (*ll.ll_host != '\0')
+ (void)printf("from %.*s\n",
+ (int)sizeof(ll.ll_host),
+ ll.ll_host);
+ else
+ (void)printf("on %.*s\n",
+ (int)sizeof(ll.ll_line),
+ ll.ll_line);
+ }
+ (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
+ }
+ memset((void *)&ll, 0, sizeof(ll));
+ (void)time(&ll.ll_time);
+ (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
+ if (hostname)
+ (void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
+ (void)write(fd, (char *)&ll, sizeof(ll));
+ (void)close(fd);
+ } else {
+ syslog(LOG_ERR, "cannot open %s: %m", _PATH_LASTLOG);
+ }
+#endif
+}
+
+void
+badlogin(name)
+ char *name;
+{
+
+ if (failures == 0)
+ return;
+ if (hostname) {
+ syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
+ failures, failures > 1 ? "S" : "", full_hostname);
+ syslog(LOG_AUTHPRIV|LOG_NOTICE,
+ "%d LOGIN FAILURE%s FROM %s, %s",
+ failures, failures > 1 ? "S" : "", full_hostname, name);
+ } else {
+ syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
+ failures, failures > 1 ? "S" : "", tty);
+ syslog(LOG_AUTHPRIV|LOG_NOTICE,
+ "%d LOGIN FAILURE%s ON %s, %s",
+ failures, failures > 1 ? "S" : "", tty, name);
+ }
+ failures = 0;
+}
+
+#undef UNKNOWN
+#define UNKNOWN "su"
+
+char *
+stypeof(ttyid)
+ char *ttyid;
+{
+ struct ttyent *t;
+
+ if (ttyid != NULL && *ttyid != '\0') {
+ t = getttynam(ttyid);
+ if (t != NULL && t->ty_type != NULL)
+ return (t->ty_type);
+ }
+ return (UNKNOWN);
+}
+
+void
+refused(msg, rtype, lout)
+ char *msg;
+ char *rtype;
+ int lout;
+{
+
+ if (msg != NULL)
+ printf("%s.\n", msg);
+ if (hostname)
+ syslog(LOG_NOTICE, "LOGIN %s REFUSED (%s) FROM %s ON TTY %s",
+ pwd->pw_name, rtype, full_hostname, tty);
+ else
+ syslog(LOG_NOTICE, "LOGIN %s REFUSED (%s) ON TTY %s",
+ pwd->pw_name, rtype, tty);
+ if (lout)
+ sleepexit(1);
+}
+
+void
+sleepexit(eval)
+ int eval;
+{
+
+ (void)sleep(5);
+ exit(eval);
+}
diff --git a/release/picobsd/tinyware/msg/Makefile b/release/picobsd/tinyware/msg/Makefile
new file mode 100644
index 0000000..ab0ad2b
--- /dev/null
+++ b/release/picobsd/tinyware/msg/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+#
+PROG=msg
+SRCS= msg.c
+MAN=
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/msg/README b/release/picobsd/tinyware/msg/README
new file mode 100644
index 0000000..d26e383
--- /dev/null
+++ b/release/picobsd/tinyware/msg/README
@@ -0,0 +1,15 @@
+1998.09.14, Warsaw
+
+This program replaces 'dmesg' utility, aand allows you to retrieve the
+system's message buffer without resorting to such dirty tricks as normal
+'dmesg' uses (using libkvm and /dev/kmem to directly read kernel
+memory.. *shudder*).
+
+This utility uses sysctl(3) interface. The mib variable it uses was
+recently added to the kernel sources, so if you don't mind patching your
+kernel tree, contact me directly - the patches are very small and simple.
+
+Andrzej Bialecki
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/msg/msg.c b/release/picobsd/tinyware/msg/msg.c
new file mode 100644
index 0000000..4d0c3c1
--- /dev/null
+++ b/release/picobsd/tinyware/msg/msg.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki <abial@freebsd.org>
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Small replacement for 'dmesg'. It doesn't need libkvm nor /dev/kmem.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+int
+main(int argc, char *argv[])
+{
+ int len,i;
+ char *buf,*p;
+ char *mib="kern.msgbuf";
+
+ /* We use sysctlbyname, because the oid is unknown (OID_AUTO) */
+
+ /* get the buffer size */
+ i=sysctlbyname(mib,NULL,&len,NULL,0);
+ if(i) {
+ perror("buffer sizing");
+ exit(-1);
+ }
+ buf=(char *)malloc(len*sizeof(char));
+ i=sysctlbyname(mib,buf,&len,NULL,0);
+ if(i) {
+ perror("retrieving data");
+ exit(-1);
+ }
+ p=buf;
+ i=0;
+ while(p<(buf+len)) {
+ switch(*p) {
+ case '\0':
+ /* skip initial NULLs */
+ break;
+ default:
+ putchar(*p);
+ }
+ p++;
+ }
+ if(*--p!='\n') putchar('\n');
+ free(buf);
+ exit(0);
+}
diff --git a/release/picobsd/tinyware/msh/Makefile b/release/picobsd/tinyware/msh/Makefile
new file mode 100644
index 0000000..e1a1b54
--- /dev/null
+++ b/release/picobsd/tinyware/msh/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+#
+PROG=msh
+SRCS= sh1.c sh2.c sh3.c sh4.c sh5.c sh6.c
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/msh/README b/release/picobsd/tinyware/msh/README
new file mode 100644
index 0000000..1b95b82
--- /dev/null
+++ b/release/picobsd/tinyware/msh/README
@@ -0,0 +1,13 @@
+This is a port of Minix /bin/sh shell.
+
+It's quite limited, but also quite small. One of most serious
+limitations is lack of support for user-defined functions. Also,
+globbing should be implemented with our glob(3) - the version in
+sh4.c is rather primitive.
+
+This version is under BSD license.
+
+Andrzej Bialecki
+<abial@FreeBSD.org>
+
+$Id$
diff --git a/release/picobsd/tinyware/msh/msh.1 b/release/picobsd/tinyware/msh/msh.1
new file mode 100644
index 0000000..bbfa255
--- /dev/null
+++ b/release/picobsd/tinyware/msh/msh.1
@@ -0,0 +1,260 @@
+.TH SH 1
+.SH NAME
+sh, ., break, case, cd, continue, eval, exec, exit, export, for, if, read, readonly, set, shift, trap, umask, wait, while \- shell
+.SH SYNOPSIS
+\fBsh\fR [\fB\-eiknqstvxu\fR] [\fB\-c \fIstr\fR] \fB[\fIfile\fR]\fR
+.br
+.de FL
+.TP
+\\fB\\$1\\fR
+\\$2
+..
+.de EX
+.TP 20
+\\fB\\$1\\fR
+# \\$2
+..
+.SH OPTIONS
+.FL "\-c" "Execute the commands in \fIstr\fR"
+.FL "\-e" "Quit on error"
+.FL "\-i" "Interactive mode; ignore QUIT, TERMINATE, INTERRUPT"
+.FL "\-k" "Look for name=value everywhere on command line"
+.FL "\-n" "Do not execute commands"
+.FL "\-q" "Change qflag from sig_ign to sig_del"
+.FL "\-s" "Read commands from standard input"
+.FL "\-t" "Exit after reading and executing one command"
+.FL "\-v" "Echo input lines as they are read"
+.FL "\-x" "Trace"
+.FL "\-u" "Unset variables"
+.SH EXAMPLES
+.EX "sh script" "Run a shell script"
+.SH DESCRIPTION
+.I Sh
+is the shell, which forms the user's main interface with the system.
+On startup, the shell reads /etc/profile and $HOME/.profile, if they exist,
+and executes any commands they contain. The Minix shell has most of the
+features of the V7 (Bourne) shell, including redirection of input and output,
+pipes, magic characters, background processes, and shell scripts. A brief
+summary follows, but whole books have been written on shell programming alone.
+.LP
+Some of the more common notations are:
+.PP
+.in +2.45i
+.ta 2i 2.2i
+.ti -2.2i
+date # Regular command
+.ti -2.2i
+sort <file # Redirect \fIstdin\fR (standard input)
+.ti -2.2i
+sort <file1 >file2 # Redirect \fIstdin\fR and \fIstdout\fR
+.ti -2.2i
+cc file.c 2>error # Redirect \fIstderr\fR
+.ti -2.2i
+a.out >f 2>&1 # Combine standard output and standard error
+.ti -2.2i
+sort <file1 >>file2 # Append output to \fIfile2\fR
+.ti -2.2i
+sort <file1 >file2 & # Background job
+.ti -2.2i
+(ls \-l; a.out) & # Run two background commands sequentially
+.ti -2.2i
+sort <file | wc # Two-process pipeline
+.ti -2.2i
+sort <f | uniq | wc # Three-process pipeline
+.ti -2.2i
+ls \-l *.c # List all files ending in \fI.c\fR
+.ti -2.2i
+ls \-l [\fIa-c\fR]* # List all files beginning with \fIa\fR, \fIb\fR, or \fIc\fR
+.ti -2.2i
+ls \-l ? # List all one-character file names
+.ti -2.2i
+ls \e? # List the file whose name is question mark
+.ti -2.2i
+ls \(fm???\(fm # List the file whose name is three question marks
+.ti -2.2i
+v=/usr/ast # Set shell variable \fIv\fR
+.ti -2.2i
+ls \-l $v # Use shell variable \fIv\fR
+.ti -2.2i
+PS1=\(fmHi! \(fm # Change the primary prompt to \fIHi!\fR
+.ti -2.2i
+PS2=\(fmMore: \(fm # Change the secondary prompt to \fIMore:\fR
+.ti -2.2i
+ls \-l $HOME # List the home directory
+.ti -2.2i
+echo $PATH # Echo the search path
+.ti -2.2i
+echo $? # Echo exit status of previous command in decimal
+.ti -2.2i
+echo $$ # Echo shell's pid in decimal
+.ti -2.2i
+echo $! # Echo PID of last background process
+.ti -2.2i
+echo $# # Echo number of parameters (shell script)
+.ti -2.2i
+echo $2 # Echo second parameter (shell script)
+.ti -2.2i
+echo "$2" # Echo second parameter without expanding spaces
+.ti -2.2i
+echo $* # Echo all parameters (shell script)
+.ti -2.2i
+echo $@ # Echo all parameters (shell script)
+.ti -2.2i
+echo "$@" # Echo all parameters without expanding spaces
+.in -2.45i
+.LP
+The shell uses the following variables for specific purposes:
+.PP
+.in +2.25i
+.ta 2i
+.ti -2i
+SHELL the path of the current shell
+.ti -2i
+HOME the default value for the cd(1) command
+.ti -2i
+PATH the directories to be searched to find commands
+.ti -2i
+IFS the internal field separators for command strings
+.ti -2i
+PS1 the primary shell prompt
+.ti -2i
+PS2 the secondary shell prompt
+.in -2.25i
+.LP
+There are various forms of substitution on the shell command line:
+.PP
+.in +2.25i
+.ta 2i
+.ti -2i
+`...` Command string between back-quotes is replaced by its output
+.ti -2i
+"..." Permits variable substitution between quotes
+.ti -2i
+\&'...' Inhibits variable substitution between quotes
+.ti -2i
+$VAR Replaced by contents of variable VAR
+.ti -2i
+${VAR} Delimits variable VAR from any following string
+.in -2.25i
+.LP
+The expressions below depend on whether or not VAR has ever been set.
+If VAR has been set, they give:
+.PP
+.in +2.25i
+.ta 2i
+.ti -2i
+${VAR-str} Replace expression by VAR, else by str
+.ti -2i
+${VAR=str} Replace expression by VAR, else by str and set VAR to str
+.ti -2i
+${VAR?str} Replace expression by VAR, else print str and exit shell
+.ti -2i
+${VAR+str} Replace expression by str, else by null string
+.in -2.25i
+.LP
+If a colon is placed after VAR, the expressions depend on whether or not
+VAR is currently set and non-null.
+.LP
+The shell has a number of built-in commands:
+.PP
+.in +2.25i
+.ta 2i
+.ti -2i
+: return true status
+.ti -2i
+\&. fn execute shell script fn on current path
+.ti -2i
+break [n] break from a for, until or while loop; exit n levels
+.ti -2i
+continue [n] continue a for, until or while loop; resume nth loop
+.ti -2i
+cd [dir] change current working directory; move to $HOME
+.ti -2i
+eval cmd rescan cmd, performing substitutions
+.ti -2i
+eval rescan the current command line
+.ti -2i
+exec cmd execute cmd without creating a new process
+.ti -2i
+exec <|> with no command name, modify shell I/O
+.ti -2i
+exit [n] exit a shell program, with exit value n
+.ti -2i
+export [var] export var to shell's children; list exported variables
+.ti -2i
+pwd print the name of the current working directory
+.ti -2i
+read var read a line from stdin and assign to var
+.ti -2i
+readonly [var] make var readonly; list readonly variables
+.ti -2i
+set -f set shell flag (+f unsets flag)
+.ti -2i
+set str set positional parameter to str
+.ti -2i
+set show the current shell variables
+.ti -2i
+shift reassign positional parameters (except ${0}) one left
+.ti -2i
+times print accumulated user and system times for processes
+.ti -2i
+trap arg sigs trap signals sigs and run arg on receipt
+.ti -2i
+trap list trapped signals
+.ti -2i
+umask [n] set the user file creation mask; show the current umask
+.ti -2i
+wait [n] wait for process pid n; wait for all processes
+.in -2.25i
+.LP
+The shell also contains a programming language, which has the following
+operators and flow control statements:
+.PP
+.in +3.50i
+.ta 2i 3.25i
+.ti -3.25i
+# Comment The rest of the line is ignored
+.ti -3.25i
+= Assignment Set a shell variable
+.ti -3.25i
+&& Logical AND Execute second command only if first succeeds
+.ti -3.25i
+|| Logical OR Execute second command only if first fails
+.ti -3.25i
+(...) Group Execute enclosed commands before continuing
+.in -3.50i
+.PP
+.in +2.25i
+.ta 2i
+.ti -2i
+for For loop (for ... in ... do ... done)
+.ti -2i
+case Case statement ((case ... ) ... ;; ... esac)
+.ti -2i
+esac Case statement end
+.ti -2i
+while While loop (while ... do ... done)
+.ti -2i
+do Do/For/While loop start (do ... until ...)
+.ti -2i
+done For/While loop end
+.ti -2i
+if Conditional statement (if ... else ... elif ... fi)
+.ti -2i
+in For loop selection
+.ti -2i
+then Conditional statement start
+.ti -2i
+else Conditional statement alternative
+.ti -2i
+elif Conditional statement end
+.ti -2i
+until Do loop end
+.ti -2i
+fi Conditional statement end
+.in -2.25i
+.SH "SEE ALSO"
+.BR echo (1),
+.BR expr (1),
+.BR pwd (1),
+.BR true (1).
diff --git a/release/picobsd/tinyware/msh/sh.h b/release/picobsd/tinyware/msh/sh.h
new file mode 100644
index 0000000..223761e
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh.h
@@ -0,0 +1,388 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* Need a way to have void used for ANSI, nothing for K&R. */
+#ifndef _ANSI
+#undef _VOID
+#define _VOID
+#endif
+
+/* -------- sh.h -------- */
+/*
+ * shell
+ */
+
+#define LINELIM 2100
+#define NPUSH 8 /* limit to input nesting */
+
+#define NOFILE 20 /* Number of open files */
+#define NUFILE 10 /* Number of user-accessible files */
+#define FDBASE 10 /* First file usable by Shell */
+
+/*
+ * values returned by wait
+ */
+#define WAITSIG(s) ((s)&0177)
+#define WAITVAL(s) (((s)>>8)&0377)
+#define WAITCORE(s) (((s)&0200)!=0)
+
+/*
+ * library and system defintions
+ */
+#ifdef __STDC__
+typedef void xint; /* base type of jmp_buf, for not broken compilers */
+#else
+typedef char * xint; /* base type of jmp_buf, for broken compilers */
+#endif
+
+/*
+ * shell components
+ */
+/* #include "area.h" */
+/* #include "word.h" */
+/* #include "io.h" */
+/* #include "var.h" */
+
+#define QUOTE 0200
+
+#define NOBLOCK ((struct op *)NULL)
+#define NOWORD ((char *)NULL)
+#define NOWORDS ((char **)NULL)
+#define NOPIPE ((int *)NULL)
+
+/*
+ * Description of a command or an operation on commands.
+ * Might eventually use a union.
+ */
+struct op {
+ int type; /* operation type, see below */
+ char **words; /* arguments to a command */
+ struct ioword **ioact; /* IO actions (eg, < > >>) */
+ struct op *left;
+ struct op *right;
+ char *str; /* identifier for case and for */
+};
+
+#define TCOM 1 /* command */
+#define TPAREN 2 /* (c-list) */
+#define TPIPE 3 /* a | b */
+#define TLIST 4 /* a [&;] b */
+#define TOR 5 /* || */
+#define TAND 6 /* && */
+#define TFOR 7
+#define TDO 8
+#define TCASE 9
+#define TIF 10
+#define TWHILE 11
+#define TUNTIL 12
+#define TELIF 13
+#define TPAT 14 /* pattern in case */
+#define TBRACE 15 /* {c-list} */
+#define TASYNC 16 /* c & */
+
+/*
+ * actions determining the environment of a process
+ */
+#define BIT(i) (1<<(i))
+#define FEXEC BIT(0) /* execute without forking */
+
+/*
+ * flags to control evaluation of words
+ */
+#define DOSUB 1 /* interpret $, `, and quotes */
+#define DOBLANK 2 /* perform blank interpretation */
+#define DOGLOB 4 /* interpret [?* */
+#define DOKEY 8 /* move words with `=' to 2nd arg. list */
+#define DOTRIM 16 /* trim resulting string */
+
+#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM)
+
+Extern char **dolv;
+Extern int dolc;
+Extern int exstat;
+Extern char gflg;
+Extern int talking; /* interactive (talking-type wireless) */
+Extern int execflg;
+Extern int multiline; /* \n changed to ; */
+Extern struct op *outtree; /* result from parser */
+
+Extern xint *failpt;
+Extern xint *errpt;
+
+struct brkcon {
+ jmp_buf brkpt;
+ struct brkcon *nextlev;
+} ;
+Extern struct brkcon *brklist;
+Extern int isbreak;
+
+/*
+ * redirection
+ */
+struct ioword {
+ short io_unit; /* unit affected */
+ short io_flag; /* action (below) */
+ char *io_name; /* file name */
+};
+#define IOREAD 1 /* < */
+#define IOHERE 2 /* << (here file) */
+#define IOWRITE 4 /* > */
+#define IOCAT 8 /* >> */
+#define IOXHERE 16 /* ${}, ` in << */
+#define IODUP 32 /* >&digit */
+#define IOCLOSE 64 /* >&- */
+
+#define IODEFAULT (-1) /* token for default IO unit */
+
+Extern struct wdblock *wdlist;
+Extern struct wdblock *iolist;
+
+/*
+ * parsing & execution environment
+ */
+extern struct env {
+ char *linep;
+ struct io *iobase;
+ struct io *iop;
+ xint *errpt;
+ int iofd;
+ struct env *oenv;
+} e;
+
+/*
+ * flags:
+ * -e: quit on error
+ * -k: look for name=value everywhere on command line
+ * -n: no execution
+ * -t: exit after reading and executing one command
+ * -v: echo as read
+ * -x: trace
+ * -u: unset variables net diagnostic
+ */
+extern char *flag;
+
+extern char *null; /* null value for variable */
+extern int intr; /* interrupt pending */
+
+Extern char *trap[_NSIG+1];
+Extern char ourtrap[_NSIG+1];
+Extern int trapset; /* trap pending */
+
+extern int heedint; /* heed interrupt signals */
+
+Extern int yynerrs; /* yacc */
+
+Extern char line[LINELIM];
+extern char *elinep;
+
+/*
+ * other functions
+ */
+#ifdef __STDC__
+int (*inbuilt(char *s ))(void);
+#else
+int (*inbuilt())();
+#endif
+
+#ifdef __FreeBSD__
+#define _PROTOTYPE(x,y) x ## y
+#endif
+
+_PROTOTYPE(char *rexecve , (char *c , char **v , char **envp ));
+_PROTOTYPE(char *space , (int n ));
+_PROTOTYPE(char *strsave , (char *s , int a ));
+_PROTOTYPE(char *evalstr , (char *cp , int f ));
+_PROTOTYPE(char *putn , (int n ));
+_PROTOTYPE(char *itoa , (unsigned u , int n ));
+_PROTOTYPE(char *unquote , (char *as ));
+_PROTOTYPE(struct var *lookup , (char *n ));
+_PROTOTYPE(int rlookup , (char *n ));
+_PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb ));
+_PROTOTYPE(int subgetc , (int ec , int quoted ));
+_PROTOTYPE(char **makenv , (void));
+_PROTOTYPE(char **eval , (char **ap , int f ));
+_PROTOTYPE(int setstatus , (int s ));
+_PROTOTYPE(int waitfor , (int lastpid , int canintr ));
+
+_PROTOTYPE(void onintr , (int s )); /* SIGINT handler */
+
+_PROTOTYPE(int newenv , (int f ));
+_PROTOTYPE(void quitenv , (void));
+_PROTOTYPE(void err , (char *s ));
+_PROTOTYPE(int anys , (char *s1 , char *s2 ));
+_PROTOTYPE(int any , (int c , char *s ));
+_PROTOTYPE(void next , (int f ));
+_PROTOTYPE(void setdash , (void));
+_PROTOTYPE(void onecommand , (void));
+_PROTOTYPE(void runtrap , (int i ));
+_PROTOTYPE(void xfree , (char *s ));
+_PROTOTYPE(int letter , (int c ));
+_PROTOTYPE(int digit , (int c ));
+_PROTOTYPE(int letnum , (int c ));
+_PROTOTYPE(int gmatch , (char *s , char *p ));
+
+/*
+ * error handling
+ */
+_PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */
+_PROTOTYPE(void fail , (void)); /* fail but return to process next command */
+_PROTOTYPE(void warn , (char *s ));
+_PROTOTYPE(void sig , (int i )); /* default signal handler */
+
+/* -------- var.h -------- */
+
+struct var {
+ char *value;
+ char *name;
+ struct var *next;
+ char status;
+};
+#define COPYV 1 /* flag to setval, suggesting copy */
+#define RONLY 01 /* variable is read-only */
+#define EXPORT 02 /* variable is to be exported */
+#define GETCELL 04 /* name & value space was got with getcell */
+
+Extern struct var *vlist; /* dictionary */
+
+Extern struct var *homedir; /* home directory */
+Extern struct var *prompt; /* main prompt */
+Extern struct var *cprompt; /* continuation prompt */
+Extern struct var *path; /* search path for commands */
+Extern struct var *shell; /* shell to interpret command files */
+Extern struct var *ifs; /* field separators */
+
+_PROTOTYPE(int yyparse , (void));
+_PROTOTYPE(struct var *lookup , (char *n ));
+_PROTOTYPE(void setval , (struct var *vp , char *val ));
+_PROTOTYPE(void nameval , (struct var *vp , char *val , char *name ));
+_PROTOTYPE(void export , (struct var *vp ));
+_PROTOTYPE(void ronly , (struct var *vp ));
+_PROTOTYPE(int isassign , (char *s ));
+_PROTOTYPE(int checkname , (char *cp ));
+_PROTOTYPE(int assign , (char *s , int cf ));
+_PROTOTYPE(void putvlist , (int f , int out ));
+_PROTOTYPE(int eqname , (char *n1 , char *n2 ));
+
+_PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act ));
+
+/* -------- io.h -------- */
+/* io buffer */
+struct iobuf {
+ unsigned id; /* buffer id */
+ char buf[512]; /* buffer */
+ char *bufp; /* pointer into buffer */
+ char *ebufp; /* pointer to end of buffer */
+};
+
+/* possible arguments to an IO function */
+struct ioarg {
+ char *aword;
+ char **awordlist;
+ int afile; /* file descriptor */
+ unsigned afid; /* buffer id */
+ long afpos; /* file position */
+ struct iobuf *afbuf; /* buffer for this file */
+};
+Extern struct ioarg ioargstack[NPUSH];
+#define AFID_NOBUF (~0)
+#define AFID_ID 0
+
+/* an input generator's state */
+struct io {
+ int (*iofn)(_VOID);
+ struct ioarg *argp;
+ int peekc;
+ char prev; /* previous character read by readc() */
+ char nlcount; /* for `'s */
+ char xchar; /* for `'s */
+ char task; /* reason for pushed IO */
+};
+Extern struct io iostack[NPUSH];
+#define XOTHER 0 /* none of the below */
+#define XDOLL 1 /* expanding ${} */
+#define XGRAVE 2 /* expanding `'s */
+#define XIO 3 /* file IO */
+
+/* in substitution */
+#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL)
+
+/*
+ * input generators for IO structure
+ */
+_PROTOTYPE(int nlchar , (struct ioarg *ap ));
+_PROTOTYPE(int strchar , (struct ioarg *ap ));
+_PROTOTYPE(int qstrchar , (struct ioarg *ap ));
+_PROTOTYPE(int filechar , (struct ioarg *ap ));
+_PROTOTYPE(int herechar , (struct ioarg *ap ));
+_PROTOTYPE(int linechar , (struct ioarg *ap ));
+_PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop ));
+_PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop ));
+_PROTOTYPE(int dolchar , (struct ioarg *ap ));
+_PROTOTYPE(int wdchar , (struct ioarg *ap ));
+_PROTOTYPE(void scraphere , (void));
+_PROTOTYPE(void freehere , (int area ));
+_PROTOTYPE(void gethere , (void));
+_PROTOTYPE(void markhere , (char *s , struct ioword *iop ));
+_PROTOTYPE(int herein , (char *hname , int xdoll ));
+_PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID)));
+
+/*
+ * IO functions
+ */
+_PROTOTYPE(int eofc , (void));
+_PROTOTYPE(int getc , (int ec ));
+_PROTOTYPE(int readc , (void));
+_PROTOTYPE(void unget , (int c ));
+_PROTOTYPE(void ioecho , (int c ));
+_PROTOTYPE(void prs , (char *s ));
+_PROTOTYPE(void putc , (int c ));
+_PROTOTYPE(void prn , (unsigned u ));
+_PROTOTYPE(void closef , (int i ));
+_PROTOTYPE(void closeall , (void));
+
+/*
+ * IO control
+ */
+_PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID)));
+_PROTOTYPE(int remap , (int fd ));
+_PROTOTYPE(int openpipe , (int *pv ));
+_PROTOTYPE(void closepipe , (int *pv ));
+_PROTOTYPE(struct io *setbase , (struct io *ip ));
+
+extern struct ioarg temparg; /* temporary for PUSHIO */
+#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))
+#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
+
+/* -------- word.h -------- */
+#ifndef WORD_H
+#define WORD_H 1
+struct wdblock {
+ short w_bsize;
+ short w_nword;
+ /* bounds are arbitrary */
+ char *w_words[1];
+};
+
+_PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb ));
+_PROTOTYPE(struct wdblock *newword , (int nw ));
+_PROTOTYPE(char **getwords , (struct wdblock *wb ));
+#endif
+
+/* -------- area.h -------- */
+
+/*
+ * storage allocation
+ */
+_PROTOTYPE(char *getcell , (unsigned nbytes ));
+_PROTOTYPE(void garbage , (void));
+_PROTOTYPE(void setarea , (char *cp , int a ));
+_PROTOTYPE(int getarea , (char *cp ));
+_PROTOTYPE(void freearea , (int a ));
+_PROTOTYPE(void freecell , (char *cp ));
+
+Extern int areanum; /* current allocation area */
+
+#define NEW(type) (type *)getcell(sizeof(type))
+#define DELETE(obj) freecell((char *)obj)
diff --git a/release/picobsd/tinyware/msh/sh1.c b/release/picobsd/tinyware/msh/sh1.c
new file mode 100644
index 0000000..34b024d
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh1.c
@@ -0,0 +1,953 @@
+#define Extern extern
+#include <sys/types.h>
+#include <signal.h>
+#define _NSIG NSIG
+#include <errno.h>
+#include <setjmp.h>
+#include "sh.h"
+/* -------- sh.c -------- */
+/*
+ * shell
+ */
+
+/* #include "sh.h" */
+
+int intr;
+int inparse;
+char flags['z'-'a'+1];
+char *flag = flags-'a';
+char *elinep = line+sizeof(line)-5;
+char *null = "";
+int heedint =1;
+struct env e ={line, iostack, iostack-1,
+ (xint *)NULL, FDBASE, (struct env *)NULL};
+
+extern char **environ; /* environment pointer */
+
+/*
+ * default shell, search rules
+ */
+char shellname[] = "/bin/sh";
+char search[] = ":/bin:/usr/bin";
+
+_PROTOTYPE(void (*qflag), (int)) = SIG_IGN;
+
+_PROTOTYPE(int main, (int argc, char **argv ));
+_PROTOTYPE(int newfile, (char *s ));
+_PROTOTYPE(static char *findeq, (char *cp ));
+_PROTOTYPE(static char *cclass, (char *p, int sub ));
+_PROTOTYPE(void initarea, (void));
+
+int main(argc, argv)
+int argc;
+register char **argv;
+{
+ register int f;
+ register char *s;
+ int cflag;
+ char *name, **ap;
+ int (*iof)();
+
+ initarea();
+ if ((ap = environ) != NULL) {
+ while (*ap)
+ assign(*ap++, !COPYV);
+ for (ap = environ; *ap;)
+ export(lookup(*ap++));
+ }
+ closeall();
+ areanum = 1;
+
+ shell = lookup("SHELL");
+ if (shell->value == null)
+ setval(shell, shellname);
+ export(shell);
+
+ homedir = lookup("HOME");
+ if (homedir->value == null)
+ setval(homedir, "/");
+ export(homedir);
+
+ setval(lookup("$"), itoa(getpid(), 5));
+
+ path = lookup("PATH");
+ if (path->value == null)
+ setval(path, search);
+ export(path);
+
+ ifs = lookup("IFS");
+ if (ifs->value == null)
+ setval(ifs, " \t\n");
+
+ prompt = lookup("PS1");
+ if (prompt->value == null)
+#ifndef UNIXSHELL
+ setval(prompt, "$ ");
+#else
+ setval(prompt, "% ");
+#endif
+
+ if (geteuid() == 0) {
+ setval(prompt, "# ");
+ prompt->status &= ~EXPORT;
+ }
+ cprompt = lookup("PS2");
+ if (cprompt->value == null)
+ setval(cprompt, "> ");
+
+ iof = filechar;
+ cflag = 0;
+ name = *argv++;
+ if (--argc >= 1) {
+ if(argv[0][0] == '-' && argv[0][1] != '\0') {
+ for (s = argv[0]+1; *s; s++)
+ switch (*s) {
+ case 'c':
+ prompt->status &= ~EXPORT;
+ cprompt->status &= ~EXPORT;
+ setval(prompt, "");
+ setval(cprompt, "");
+ cflag = 1;
+ if (--argc > 0)
+ PUSHIO(aword, *++argv, iof = nlchar);
+ break;
+
+ case 'q':
+ qflag = SIG_DFL;
+ break;
+
+ case 's':
+ /* standard input */
+ break;
+
+ case 't':
+ prompt->status &= ~EXPORT;
+ setval(prompt, "");
+ iof = linechar;
+ break;
+
+ case 'i':
+ talking++;
+ default:
+ if (*s>='a' && *s<='z')
+ flag[*s]++;
+ }
+ } else {
+ argv--;
+ argc++;
+ }
+ if (iof == filechar && --argc > 0) {
+ setval(prompt, "");
+ setval(cprompt, "");
+ prompt->status &= ~EXPORT;
+ cprompt->status &= ~EXPORT;
+ if (newfile(name = *++argv))
+ exit(1);
+ }
+ }
+ setdash();
+ if (e.iop < iostack) {
+ PUSHIO(afile, 0, iof);
+ if (isatty(0) && isatty(1) && !cflag)
+ talking++;
+ }
+ signal(SIGQUIT, qflag);
+ if (name && name[0] == '-') {
+ talking++;
+ if ((f = open(".profile", 0)) >= 0)
+ next(remap(f));
+ if ((f = open("/etc/profile", 0)) >= 0)
+ next(remap(f));
+ }
+ if (talking)
+ signal(SIGTERM, sig);
+ if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+ signal(SIGINT, onintr);
+ dolv = argv;
+ dolc = argc;
+ dolv[0] = name;
+ if (dolc > 1)
+ for (ap = ++argv; --argc > 0;)
+ if (assign(*ap = *argv++, !COPYV))
+ dolc--; /* keyword */
+ else
+ ap++;
+ setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
+
+ for (;;) {
+ if (talking && e.iop <= iostack)
+ prs(prompt->value);
+ onecommand();
+ }
+}
+
+void
+setdash()
+{
+ register char *cp, c;
+ char m['z'-'a'+1];
+
+ cp = m;
+ for (c='a'; c<='z'; c++)
+ if (flag[c])
+ *cp++ = c;
+ *cp = 0;
+ setval(lookup("-"), m);
+}
+
+int
+newfile(s)
+register char *s;
+{
+ register f;
+
+ if (strcmp(s, "-") != 0) {
+ f = open(s, 0);
+ if (f < 0) {
+ prs(s);
+ err(": cannot open");
+ return(1);
+ }
+ } else
+ f = 0;
+ next(remap(f));
+ return(0);
+}
+
+void
+onecommand()
+{
+ register i;
+ jmp_buf m1;
+
+ while (e.oenv)
+ quitenv();
+ areanum = 1;
+ freehere(areanum);
+ freearea(areanum);
+ garbage();
+ wdlist = 0;
+ iolist = 0;
+ e.errpt = 0;
+ e.linep = line;
+ yynerrs = 0;
+ multiline = 0;
+ inparse = 1;
+ intr = 0;
+ execflg = 0;
+ setjmp(failpt = m1); /* Bruce Evans' fix */
+ if (setjmp(failpt = m1) || yyparse() || intr) {
+ while (e.oenv)
+ quitenv();
+ scraphere();
+ if (!talking && intr)
+ leave();
+ inparse = 0;
+ intr = 0;
+ return;
+ }
+ inparse = 0;
+ brklist = 0;
+ intr = 0;
+ execflg = 0;
+ if (!flag['n'])
+ execute(outtree, NOPIPE, NOPIPE, 0);
+ if (!talking && intr) {
+ execflg = 0;
+ leave();
+ }
+ if ((i = trapset) != 0) {
+ trapset = 0;
+ runtrap(i);
+ }
+}
+
+void
+fail()
+{
+ longjmp(failpt, 1);
+ /* NOTREACHED */
+}
+
+void
+leave()
+{
+ if (execflg)
+ fail();
+ scraphere();
+ freehere(1);
+ runtrap(0);
+ exit(exstat);
+ /* NOTREACHED */
+}
+
+void
+warn(s)
+register char *s;
+{
+ if(*s) {
+ prs(s);
+ exstat = -1;
+ }
+ prs("\n");
+ if (flag['e'])
+ leave();
+}
+
+void
+err(s)
+char *s;
+{
+ warn(s);
+ if (flag['n'])
+ return;
+ if (!talking)
+ leave();
+ if (e.errpt)
+ longjmp(e.errpt, 1);
+ closeall();
+ e.iop = e.iobase = iostack;
+}
+
+int
+newenv(f)
+int f;
+{
+ register struct env *ep;
+
+ if (f) {
+ quitenv();
+ return(1);
+ }
+ ep = (struct env *) space(sizeof(*ep));
+ if (ep == NULL) {
+ while (e.oenv)
+ quitenv();
+ fail();
+ }
+ *ep = e;
+ e.oenv = ep;
+ e.errpt = errpt;
+ return(0);
+}
+
+void
+quitenv()
+{
+ register struct env *ep;
+ register fd;
+
+ if ((ep = e.oenv) != NULL) {
+ fd = e.iofd;
+ e = *ep;
+ /* should close `'d files */
+ DELETE(ep);
+ while (--fd >= e.iofd)
+ close(fd);
+ }
+}
+
+/*
+ * Is any character from s1 in s2?
+ */
+int
+anys(s1, s2)
+register char *s1, *s2;
+{
+ while (*s1)
+ if (any(*s1++, s2))
+ return(1);
+ return(0);
+}
+
+/*
+ * Is character c in s?
+ */
+int
+any(c, s)
+register int c;
+register char *s;
+{
+ while (*s)
+ if (*s++ == c)
+ return(1);
+ return(0);
+}
+
+char *
+putn(n)
+register int n;
+{
+ return(itoa(n, -1));
+}
+
+char *
+itoa(u, n)
+register unsigned u;
+int n;
+{
+ register char *cp;
+ static char s[20];
+ int m;
+
+ m = 0;
+ if (n < 0 && (int) u < 0) {
+ m++;
+ u = -u;
+ }
+ cp = s+sizeof(s);
+ *--cp = 0;
+ do {
+ *--cp = u%10 + '0';
+ u /= 10;
+ } while (--n > 0 || u);
+ if (m)
+ *--cp = '-';
+ return(cp);
+}
+
+void
+next(f)
+int f;
+{
+ PUSHIO(afile, f, filechar);
+}
+
+void
+onintr(s)
+int s; /* ANSI C requires a parameter */
+{
+ signal(SIGINT, onintr);
+ intr = 1;
+ if (talking) {
+ if (inparse) {
+ prs("\n");
+ fail();
+ }
+ }
+ else if (heedint) {
+ execflg = 0;
+ leave();
+ }
+}
+
+int
+letter(c)
+register c;
+{
+ return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
+}
+
+int
+digit(c)
+register c;
+{
+ return(c >= '0' && c <= '9');
+}
+
+int
+letnum(c)
+register c;
+{
+ return(letter(c) || digit(c));
+}
+
+char *
+space(n)
+int n;
+{
+ register char *cp;
+
+ if ((cp = getcell(n)) == 0)
+ err("out of string space");
+ return(cp);
+}
+
+char *
+strsave(s, a)
+register char *s;
+int a;
+{
+ register char *cp, *xp;
+
+ if ((cp = space(strlen(s)+1)) != NULL) {
+ setarea((char *)cp, a);
+ for (xp = cp; (*xp++ = *s++) != '\0';)
+ ;
+ return(cp);
+ }
+ return("");
+}
+
+void
+xfree(s)
+register char *s;
+{
+ DELETE(s);
+}
+
+/*
+ * trap handling
+ */
+void
+sig(i)
+register int i;
+{
+ trapset = i;
+ signal(i, sig);
+}
+
+void runtrap(i)
+int i;
+{
+ char *trapstr;
+
+ if ((trapstr = trap[i]) == NULL)
+ return;
+ if (i == 0)
+ trap[i] = 0;
+ RUN(aword, trapstr, nlchar);
+}
+
+/* -------- var.c -------- */
+/* #include "sh.h" */
+
+/*
+ * Find the given name in the dictionary
+ * and return its value. If the name was
+ * not previously there, enter it now and
+ * return a null value.
+ */
+struct var *
+lookup(n)
+register char *n;
+{
+ register struct var *vp;
+ register char *cp;
+ register int c;
+ static struct var dummy;
+
+ if (digit(*n)) {
+ dummy.name = n;
+ for (c = 0; digit(*n) && c < 1000; n++)
+ c = c*10 + *n-'0';
+ dummy.status = RONLY;
+ dummy.value = c <= dolc? dolv[c]: null;
+ return(&dummy);
+ }
+ for (vp = vlist; vp; vp = vp->next)
+ if (eqname(vp->name, n))
+ return(vp);
+ cp = findeq(n);
+ vp = (struct var *)space(sizeof(*vp));
+ if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) {
+ dummy.name = dummy.value = "";
+ return(&dummy);
+ }
+ for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++)
+ ;
+ if (*cp == 0)
+ *cp = '=';
+ *++cp = 0;
+ setarea((char *)vp, 0);
+ setarea((char *)vp->name, 0);
+ vp->value = null;
+ vp->next = vlist;
+ vp->status = GETCELL;
+ vlist = vp;
+ return(vp);
+}
+
+/*
+ * give variable at `vp' the value `val'.
+ */
+void
+setval(vp, val)
+struct var *vp;
+char *val;
+{
+ nameval(vp, val, (char *)NULL);
+}
+
+/*
+ * if name is not NULL, it must be
+ * a prefix of the space `val',
+ * and end with `='.
+ * this is all so that exporting
+ * values is reasonably painless.
+ */
+void
+nameval(vp, val, name)
+register struct var *vp;
+char *val, *name;
+{
+ register char *cp, *xp;
+ char *nv;
+ int fl;
+
+ if (vp->status & RONLY) {
+ for (xp = vp->name; *xp && *xp != '=';)
+ putc(*xp++);
+ err(" is read-only");
+ return;
+ }
+ fl = 0;
+ if (name == NULL) {
+ xp = space(strlen(vp->name)+strlen(val)+2);
+ if (xp == 0)
+ return;
+ /* make string: name=value */
+ setarea((char *)xp, 0);
+ name = xp;
+ for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++)
+ ;
+ if (*xp++ == 0)
+ xp[-1] = '=';
+ nv = xp;
+ for (cp = val; (*xp++ = *cp++) != '\0';)
+ ;
+ val = nv;
+ fl = GETCELL;
+ }
+ if (vp->status & GETCELL)
+ xfree(vp->name); /* form new string `name=value' */
+ vp->name = name;
+ vp->value = val;
+ vp->status |= fl;
+}
+
+void
+export(vp)
+struct var *vp;
+{
+ vp->status |= EXPORT;
+}
+
+void
+ronly(vp)
+struct var *vp;
+{
+ if (letter(vp->name[0])) /* not an internal symbol ($# etc) */
+ vp->status |= RONLY;
+}
+
+int
+isassign(s)
+register char *s;
+{
+ if (!letter((int)*s))
+ return(0);
+ for (; *s != '='; s++)
+ if (*s == 0 || !letnum(*s))
+ return(0);
+ return(1);
+}
+
+int
+assign(s, cf)
+register char *s;
+int cf;
+{
+ register char *cp;
+ struct var *vp;
+
+ if (!letter(*s))
+ return(0);
+ for (cp = s; *cp != '='; cp++)
+ if (*cp == 0 || !letnum(*cp))
+ return(0);
+ vp = lookup(s);
+ nameval(vp, ++cp, cf == COPYV? (char *)NULL: s);
+ if (cf != COPYV)
+ vp->status &= ~GETCELL;
+ return(1);
+}
+
+int
+checkname(cp)
+register char *cp;
+{
+ if (!letter(*cp++))
+ return(0);
+ while (*cp)
+ if (!letnum(*cp++))
+ return(0);
+ return(1);
+}
+
+void
+putvlist(f, out)
+register int f, out;
+{
+ register struct var *vp;
+
+ for (vp = vlist; vp; vp = vp->next)
+ if (vp->status & f && letter(*vp->name)) {
+ if (vp->status & EXPORT)
+ write(out, "export ", 7);
+ if (vp->status & RONLY)
+ write(out, "readonly ", 9);
+ write(out, vp->name, (int)(findeq(vp->name) - vp->name));
+ write(out, "\n", 1);
+ }
+}
+
+int
+eqname(n1, n2)
+register char *n1, *n2;
+{
+ for (; *n1 != '=' && *n1 != 0; n1++)
+ if (*n2++ != *n1)
+ return(0);
+ return(*n2 == 0 || *n2 == '=');
+}
+
+static char *
+findeq(cp)
+register char *cp;
+{
+ while (*cp != '\0' && *cp != '=')
+ cp++;
+ return(cp);
+}
+
+/* -------- gmatch.c -------- */
+/*
+ * int gmatch(string, pattern)
+ * char *string, *pattern;
+ *
+ * Match a pattern as in sh(1).
+ */
+
+#define CMASK 0377
+#define QUOTE 0200
+#define QMASK (CMASK&~QUOTE)
+#define NOT '!' /* might use ^ */
+
+int
+gmatch(s, p)
+register char *s, *p;
+{
+ register int sc, pc;
+
+ if (s == NULL || p == NULL)
+ return(0);
+ while ((pc = *p++ & CMASK) != '\0') {
+ sc = *s++ & QMASK;
+ switch (pc) {
+ case '[':
+ if ((p = cclass(p, sc)) == NULL)
+ return(0);
+ break;
+
+ case '?':
+ if (sc == 0)
+ return(0);
+ break;
+
+ case '*':
+ s--;
+ do {
+ if (*p == '\0' || gmatch(s, p))
+ return(1);
+ } while (*s++ != '\0');
+ return(0);
+
+ default:
+ if (sc != (pc&~QUOTE))
+ return(0);
+ }
+ }
+ return(*s == 0);
+}
+
+static char *
+cclass(p, sub)
+register char *p;
+register int sub;
+{
+ register int c, d, not, found;
+
+ if ((not = *p == NOT) != 0)
+ p++;
+ found = not;
+ do {
+ if (*p == '\0')
+ return((char *)NULL);
+ c = *p & CMASK;
+ if (p[1] == '-' && p[2] != ']') {
+ d = p[2] & CMASK;
+ p++;
+ } else
+ d = c;
+ if (c == sub || (c <= sub && sub <= d))
+ found = !not;
+ } while (*++p != ']');
+ return(found? p+1: (char *)NULL);
+}
+
+/* -------- area.c -------- */
+#define REGSIZE sizeof(struct region)
+#define GROWBY 256
+#undef SHRINKBY 64
+#define FREE 32767
+#define BUSY 0
+#define ALIGN (sizeof(int)-1)
+
+/* #include "area.h" */
+
+struct region {
+ struct region *next;
+ int area;
+};
+
+/*
+ * All memory between (char *)areabot and (char *)(areatop+1) is
+ * exclusively administered by the area management routines.
+ * It is assumed that sbrk() and brk() manipulate the high end.
+ */
+static struct region *areabot; /* bottom of area */
+static struct region *areatop; /* top of area */
+static struct region *areanxt; /* starting point of scan */
+
+void
+initarea()
+{
+ while ((int)sbrk(0) & ALIGN)
+ sbrk(1);
+ areabot = (struct region *)sbrk(REGSIZE);
+ areabot->next = areabot;
+ areabot->area = BUSY;
+ areatop = areabot;
+ areanxt = areabot;
+}
+
+char *
+getcell(nbytes)
+unsigned nbytes;
+{
+ register int nregio;
+ register struct region *p, *q;
+ register i;
+
+ if (nbytes == 0)
+ abort(); /* silly and defeats the algorithm */
+ /*
+ * round upwards and add administration area
+ */
+ nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1;
+ for (p = areanxt;;) {
+ if (p->area > areanum) {
+ /*
+ * merge free cells
+ */
+ while ((q = p->next)->area > areanum && q != areanxt)
+ p->next = q->next;
+ /*
+ * exit loop if cell big enough
+ */
+ if (q >= p + nregio)
+ goto found;
+ }
+ p = p->next;
+ if (p == areanxt)
+ break;
+ }
+ i = nregio >= GROWBY ? nregio : GROWBY;
+ p = (struct region *)sbrk(i * REGSIZE);
+ if (p == (struct region *)-1)
+ return((char *)NULL);
+ p--;
+ if (p != areatop)
+ abort(); /* allocated areas are contiguous */
+ q = p + i;
+ p->next = q;
+ p->area = FREE;
+ q->next = areabot;
+ q->area = BUSY;
+ areatop = q;
+found:
+ /*
+ * we found a FREE area big enough, pointed to by 'p', and up to 'q'
+ */
+ areanxt = p + nregio;
+ if (areanxt < q) {
+ /*
+ * split into requested area and rest
+ */
+ if (areanxt+1 > q)
+ abort(); /* insufficient space left for admin */
+ areanxt->next = q;
+ areanxt->area = FREE;
+ p->next = areanxt;
+ }
+ p->area = areanum;
+ return((char *)(p+1));
+}
+
+void
+freecell(cp)
+char *cp;
+{
+ register struct region *p;
+
+ if ((p = (struct region *)cp) != NULL) {
+ p--;
+ if (p < areanxt)
+ areanxt = p;
+ p->area = FREE;
+ }
+}
+
+void
+freearea(a)
+register int a;
+{
+ register struct region *p, *top;
+
+ top = areatop;
+ for (p = areabot; p != top; p = p->next)
+ if (p->area >= a)
+ p->area = FREE;
+}
+
+void
+setarea(cp,a)
+char *cp;
+int a;
+{
+ register struct region *p;
+
+ if ((p = (struct region *)cp) != NULL)
+ (p-1)->area = a;
+}
+
+int
+getarea(cp)
+char *cp;
+{
+ return ((struct region*)cp-1)->area;
+}
+
+void
+garbage()
+{
+ register struct region *p, *q, *top;
+
+ top = areatop;
+ for (p = areabot; p != top; p = p->next) {
+ if (p->area > areanum) {
+ while ((q = p->next)->area > areanum)
+ p->next = q->next;
+ areanxt = p;
+ }
+ }
+#ifdef SHRINKBY
+ if (areatop >= q + SHRINKBY && q->area > areanum) {
+ brk((char *)(q+1));
+ q->next = areabot;
+ q->area = BUSY;
+ areatop = q;
+ }
+#endif
+}
diff --git a/release/picobsd/tinyware/msh/sh2.c b/release/picobsd/tinyware/msh/sh2.c
new file mode 100644
index 0000000..f7eaf017
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh2.c
@@ -0,0 +1,801 @@
+#define Extern extern
+#include <sys/types.h>
+#include <signal.h>
+#define _NSIG NSIG
+#include <errno.h>
+#include <setjmp.h>
+#include "sh.h"
+
+/* -------- csyn.c -------- */
+/*
+ * shell: syntax (C version)
+ */
+
+typedef union {
+ char *cp;
+ char **wp;
+ int i;
+ struct op *o;
+} YYSTYPE;
+#define WORD 256
+#define LOGAND 257
+#define LOGOR 258
+#define BREAK 259
+#define IF 260
+#define THEN 261
+#define ELSE 262
+#define ELIF 263
+#define FI 264
+#define CASE 265
+#define ESAC 266
+#define FOR 267
+#define WHILE 268
+#define UNTIL 269
+#define DO 270
+#define DONE 271
+#define IN 272
+#define YYERRCODE 300
+
+/* flags to yylex */
+#define CONTIN 01 /* skip new lines to complete command */
+
+/* #include "sh.h" */
+#define SYNTAXERR zzerr()
+static int startl;
+static int peeksym;
+static int nlseen;
+static int iounit = IODEFAULT;
+
+static YYSTYPE yylval;
+
+_PROTOTYPE(static struct op *pipeline, (int cf ));
+_PROTOTYPE(static struct op *andor, (void));
+_PROTOTYPE(static struct op *c_list, (void));
+_PROTOTYPE(static int synio, (int cf ));
+_PROTOTYPE(static void musthave, (int c, int cf ));
+_PROTOTYPE(static struct op *simple, (void));
+_PROTOTYPE(static struct op *nested, (int type, int mark ));
+_PROTOTYPE(static struct op *command, (int cf ));
+_PROTOTYPE(static struct op *dogroup, (int onlydone ));
+_PROTOTYPE(static struct op *thenpart, (void));
+_PROTOTYPE(static struct op *elsepart, (void));
+_PROTOTYPE(static struct op *caselist, (void));
+_PROTOTYPE(static struct op *casepart, (void));
+_PROTOTYPE(static char **pattern, (void));
+_PROTOTYPE(static char **wordlist, (void));
+_PROTOTYPE(static struct op *list, (struct op *t1, struct op *t2 ));
+_PROTOTYPE(static struct op *block, (int type, struct op *t1, struct op *t2, char **wp ));
+_PROTOTYPE(static struct op *newtp, (void));
+_PROTOTYPE(static struct op *namelist, (struct op *t ));
+_PROTOTYPE(static char **copyw, (void));
+_PROTOTYPE(static void word, (char *cp ));
+_PROTOTYPE(static struct ioword **copyio, (void));
+_PROTOTYPE(static struct ioword *io, (int u, int f, char *cp ));
+_PROTOTYPE(static void zzerr, (void));
+_PROTOTYPE(void yyerror, (char *s ));
+_PROTOTYPE(static int yylex, (int cf ));
+_PROTOTYPE(int collect, (int c, int c1 ));
+_PROTOTYPE(int dual, (int c ));
+_PROTOTYPE(static void diag, (int ec ));
+_PROTOTYPE(static char *tree, (unsigned size ));
+_PROTOTYPE(void printf, (char *s ));
+
+int
+yyparse()
+{
+ startl = 1;
+ peeksym = 0;
+ yynerrs = 0;
+ outtree = c_list();
+ musthave('\n', 0);
+ return(yynerrs!=0);
+}
+
+static struct op *
+pipeline(cf)
+int cf;
+{
+ register struct op *t, *p;
+ register int c;
+
+ t = command(cf);
+ if (t != NULL) {
+ while ((c = yylex(0)) == '|') {
+ if ((p = command(CONTIN)) == NULL)
+ SYNTAXERR;
+ if (t->type != TPAREN && t->type != TCOM) {
+ /* shell statement */
+ t = block(TPAREN, t, NOBLOCK, NOWORDS);
+ }
+ t = block(TPIPE, t, p, NOWORDS);
+ }
+ peeksym = c;
+ }
+ return(t);
+}
+
+static struct op *
+andor()
+{
+ register struct op *t, *p;
+ register int c;
+
+ t = pipeline(0);
+ if (t != NULL) {
+ while ((c = yylex(0)) == LOGAND || c == LOGOR) {
+ if ((p = pipeline(CONTIN)) == NULL)
+ SYNTAXERR;
+ t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
+ }
+ peeksym = c;
+ }
+ return(t);
+}
+
+static struct op *
+c_list()
+{
+ register struct op *t, *p;
+ register int c;
+
+ t = andor();
+ if (t != NULL) {
+ if((peeksym = yylex(0)) == '&')
+ t = block(TASYNC, t, NOBLOCK, NOWORDS);
+ while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) {
+ if ((p = andor()) == NULL)
+ return(t);
+ if((peeksym = yylex(0)) == '&')
+ p = block(TASYNC, p, NOBLOCK, NOWORDS);
+ t = list(t, p);
+ }
+ peeksym = c;
+ }
+ return(t);
+}
+
+
+static int
+synio(cf)
+int cf;
+{
+ register struct ioword *iop;
+ register int i;
+ register int c;
+
+ if ((c = yylex(cf)) != '<' && c != '>') {
+ peeksym = c;
+ return(0);
+ }
+ i = yylval.i;
+ musthave(WORD, 0);
+ iop = io(iounit, i, yylval.cp);
+ iounit = IODEFAULT;
+ if (i & IOHERE)
+ markhere(yylval.cp, iop);
+ return(1);
+}
+
+static void
+musthave(c, cf)
+int c, cf;
+{
+ if ((peeksym = yylex(cf)) != c)
+ SYNTAXERR;
+ peeksym = 0;
+}
+
+static struct op *
+simple()
+{
+ register struct op *t;
+
+ t = NULL;
+ for (;;) {
+ switch (peeksym = yylex(0)) {
+ case '<':
+ case '>':
+ (void) synio(0);
+ break;
+
+ case WORD:
+ if (t == NULL) {
+ t = newtp();
+ t->type = TCOM;
+ }
+ peeksym = 0;
+ word(yylval.cp);
+ break;
+
+ default:
+ return(t);
+ }
+ }
+}
+
+static struct op *
+nested(type, mark)
+int type, mark;
+{
+ register struct op *t;
+
+ multiline++;
+ t = c_list();
+ musthave(mark, 0);
+ multiline--;
+ return(block(type, t, NOBLOCK, NOWORDS));
+}
+
+static struct op *
+command(cf)
+int cf;
+{
+ register struct op *t;
+ struct wdblock *iosave;
+ register int c;
+
+ iosave = iolist;
+ iolist = NULL;
+ if (multiline)
+ cf |= CONTIN;
+ while (synio(cf))
+ cf = 0;
+ switch (c = yylex(cf)) {
+ default:
+ peeksym = c;
+ if ((t = simple()) == NULL) {
+ if (iolist == NULL)
+ return((struct op *)NULL);
+ t = newtp();
+ t->type = TCOM;
+ }
+ break;
+
+ case '(':
+ t = nested(TPAREN, ')');
+ break;
+
+ case '{':
+ t = nested(TBRACE, '}');
+ break;
+
+ case FOR:
+ t = newtp();
+ t->type = TFOR;
+ musthave(WORD, 0);
+ startl = 1;
+ t->str = yylval.cp;
+ multiline++;
+ t->words = wordlist();
+ if ((c = yylex(0)) != '\n' && c != ';')
+ peeksym = c;
+ t->left = dogroup(0);
+ multiline--;
+ break;
+
+ case WHILE:
+ case UNTIL:
+ multiline++;
+ t = newtp();
+ t->type = c == WHILE? TWHILE: TUNTIL;
+ t->left = c_list();
+ t->right = dogroup(1);
+ t->words = NULL;
+ multiline--;
+ break;
+
+ case CASE:
+ t = newtp();
+ t->type = TCASE;
+ musthave(WORD, 0);
+ t->str = yylval.cp;
+ startl++;
+ multiline++;
+ musthave(IN, CONTIN);
+ startl++;
+ t->left = caselist();
+ musthave(ESAC, 0);
+ multiline--;
+ break;
+
+ case IF:
+ multiline++;
+ t = newtp();
+ t->type = TIF;
+ t->left = c_list();
+ t->right = thenpart();
+ musthave(FI, 0);
+ multiline--;
+ break;
+ }
+ while (synio(0))
+ ;
+ t = namelist(t);
+ iolist = iosave;
+ return(t);
+}
+
+static struct op *
+dogroup(onlydone)
+int onlydone;
+{
+ register int c;
+ register struct op *list;
+
+ c = yylex(CONTIN);
+ if (c == DONE && onlydone)
+ return((struct op *)NULL);
+ if (c != DO)
+ SYNTAXERR;
+ list = c_list();
+ musthave(DONE, 0);
+ return(list);
+}
+
+static struct op *
+thenpart()
+{
+ register int c;
+ register struct op *t;
+
+ if ((c = yylex(0)) != THEN) {
+ peeksym = c;
+ return((struct op *)NULL);
+ }
+ t = newtp();
+ t->type = 0;
+ t->left = c_list();
+ if (t->left == NULL)
+ SYNTAXERR;
+ t->right = elsepart();
+ return(t);
+}
+
+static struct op *
+elsepart()
+{
+ register int c;
+ register struct op *t;
+
+ switch (c = yylex(0)) {
+ case ELSE:
+ if ((t = c_list()) == NULL)
+ SYNTAXERR;
+ return(t);
+
+ case ELIF:
+ t = newtp();
+ t->type = TELIF;
+ t->left = c_list();
+ t->right = thenpart();
+ return(t);
+
+ default:
+ peeksym = c;
+ return((struct op *)NULL);
+ }
+}
+
+static struct op *
+caselist()
+{
+ register struct op *t;
+
+ t = NULL;
+ while ((peeksym = yylex(CONTIN)) != ESAC)
+ t = list(t, casepart());
+ return(t);
+}
+
+static struct op *
+casepart()
+{
+ register struct op *t;
+
+ t = newtp();
+ t->type = TPAT;
+ t->words = pattern();
+ musthave(')', 0);
+ t->left = c_list();
+ if ((peeksym = yylex(CONTIN)) != ESAC)
+ musthave(BREAK, CONTIN);
+ return(t);
+}
+
+static char **
+pattern()
+{
+ register int c, cf;
+
+ cf = CONTIN;
+ do {
+ musthave(WORD, cf);
+ word(yylval.cp);
+ cf = 0;
+ } while ((c = yylex(0)) == '|');
+ peeksym = c;
+ word(NOWORD);
+ return(copyw());
+}
+
+static char **
+wordlist()
+{
+ register int c;
+
+ if ((c = yylex(0)) != IN) {
+ peeksym = c;
+ return((char **)NULL);
+ }
+ startl = 0;
+ while ((c = yylex(0)) == WORD)
+ word(yylval.cp);
+ word(NOWORD);
+ peeksym = c;
+ return(copyw());
+}
+
+/*
+ * supporting functions
+ */
+static struct op *
+list(t1, t2)
+register struct op *t1, *t2;
+{
+ if (t1 == NULL)
+ return(t2);
+ if (t2 == NULL)
+ return(t1);
+ return(block(TLIST, t1, t2, NOWORDS));
+}
+
+static struct op *
+block(type, t1, t2, wp)
+int type;
+struct op *t1, *t2;
+char **wp;
+{
+ register struct op *t;
+
+ t = newtp();
+ t->type = type;
+ t->left = t1;
+ t->right = t2;
+ t->words = wp;
+ return(t);
+}
+
+struct res {
+ char *r_name;
+ int r_val;
+} restab[] = {
+ "for", FOR,
+ "case", CASE,
+ "esac", ESAC,
+ "while", WHILE,
+ "do", DO,
+ "done", DONE,
+ "if", IF,
+ "in", IN,
+ "then", THEN,
+ "else", ELSE,
+ "elif", ELIF,
+ "until", UNTIL,
+ "fi", FI,
+
+ ";;", BREAK,
+ "||", LOGOR,
+ "&&", LOGAND,
+ "{", '{',
+ "}", '}',
+
+ 0,
+};
+
+int
+rlookup(n)
+register char *n;
+{
+ register struct res *rp;
+
+ for (rp = restab; rp->r_name; rp++)
+ if (strcmp(rp->r_name, n) == 0)
+ return(rp->r_val);
+ return(0);
+}
+
+static struct op *
+newtp()
+{
+ register struct op *t;
+
+ t = (struct op *)tree(sizeof(*t));
+ t->type = 0;
+ t->words = NULL;
+ t->ioact = NULL;
+ t->left = NULL;
+ t->right = NULL;
+ t->str = NULL;
+ return(t);
+}
+
+static struct op *
+namelist(t)
+register struct op *t;
+{
+ if (iolist) {
+ iolist = addword((char *)NULL, iolist);
+ t->ioact = copyio();
+ } else
+ t->ioact = NULL;
+ if (t->type != TCOM) {
+ if (t->type != TPAREN && t->ioact != NULL) {
+ t = block(TPAREN, t, NOBLOCK, NOWORDS);
+ t->ioact = t->left->ioact;
+ t->left->ioact = NULL;
+ }
+ return(t);
+ }
+ word(NOWORD);
+ t->words = copyw();
+ return(t);
+}
+
+static char **
+copyw()
+{
+ register char **wd;
+
+ wd = getwords(wdlist);
+ wdlist = 0;
+ return(wd);
+}
+
+static void
+word(cp)
+char *cp;
+{
+ wdlist = addword(cp, wdlist);
+}
+
+static struct ioword **
+copyio()
+{
+ register struct ioword **iop;
+
+ iop = (struct ioword **) getwords(iolist);
+ iolist = 0;
+ return(iop);
+}
+
+static struct ioword *
+io(u, f, cp)
+int u;
+int f;
+char *cp;
+{
+ register struct ioword *iop;
+
+ iop = (struct ioword *) tree(sizeof(*iop));
+ iop->io_unit = u;
+ iop->io_flag = f;
+ iop->io_name = cp;
+ iolist = addword((char *)iop, iolist);
+ return(iop);
+}
+
+static void
+zzerr()
+{
+ yyerror("syntax error");
+}
+
+void
+yyerror(s)
+char *s;
+{
+ yynerrs++;
+ if (talking && e.iop <= iostack) {
+ multiline = 0;
+ while (eofc() == 0 && yylex(0) != '\n')
+ ;
+ }
+ err(s);
+ fail();
+}
+
+static int
+yylex(cf)
+int cf;
+{
+ register int c, c1;
+ int atstart;
+
+ if ((c = peeksym) > 0) {
+ peeksym = 0;
+ if (c == '\n')
+ startl = 1;
+ return(c);
+ }
+ nlseen = 0;
+ e.linep = line;
+ atstart = startl;
+ startl = 0;
+ yylval.i = 0;
+
+loop:
+ while ((c = getc(0)) == ' ' || c == '\t')
+ ;
+ switch (c) {
+ default:
+ if (any(c, "0123456789")) {
+ unget(c1 = getc(0));
+ if (c1 == '<' || c1 == '>') {
+ iounit = c - '0';
+ goto loop;
+ }
+ *e.linep++ = c;
+ c = c1;
+ }
+ break;
+
+ case '#':
+ while ((c = getc(0)) != 0 && c != '\n')
+ ;
+ unget(c);
+ goto loop;
+
+ case 0:
+ return(c);
+
+ case '$':
+ *e.linep++ = c;
+ if ((c = getc(0)) == '{') {
+ if ((c = collect(c, '}')) != '\0')
+ return(c);
+ goto pack;
+ }
+ break;
+
+ case '`':
+ case '\'':
+ case '"':
+ if ((c = collect(c, c)) != '\0')
+ return(c);
+ goto pack;
+
+ case '|':
+ case '&':
+ case ';':
+ if ((c1 = dual(c)) != '\0') {
+ startl = 1;
+ return(c1);
+ }
+ startl = 1;
+ return(c);
+ case '^':
+ startl = 1;
+ return('|');
+ case '>':
+ case '<':
+ diag(c);
+ return(c);
+
+ case '\n':
+ nlseen++;
+ gethere();
+ startl = 1;
+ if (multiline || cf & CONTIN) {
+ if (talking && e.iop <= iostack)
+ prs(cprompt->value);
+ if (cf & CONTIN)
+ goto loop;
+ }
+ return(c);
+
+ case '(':
+ case ')':
+ startl = 1;
+ return(c);
+ }
+
+ unget(c);
+
+pack:
+ while ((c = getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n"))
+ if (e.linep >= elinep)
+ err("word too long");
+ else
+ *e.linep++ = c;
+ unget(c);
+ if(any(c, "\"'`$"))
+ goto loop;
+ *e.linep++ = '\0';
+ if (atstart && (c = rlookup(line))!=0) {
+ startl = 1;
+ return(c);
+ }
+ yylval.cp = strsave(line, areanum);
+ return(WORD);
+}
+
+int
+collect(c, c1)
+register c, c1;
+{
+ char s[2];
+
+ *e.linep++ = c;
+ while ((c = getc(c1)) != c1) {
+ if (c == 0) {
+ unget(c);
+ s[0] = c1;
+ s[1] = 0;
+ prs("no closing "); yyerror(s);
+ return(YYERRCODE);
+ }
+ if (talking && c == '\n' && e.iop <= iostack)
+ prs(cprompt->value);
+ *e.linep++ = c;
+ }
+ *e.linep++ = c;
+ return(0);
+}
+
+int
+dual(c)
+register c;
+{
+ char s[3];
+ register char *cp = s;
+
+ *cp++ = c;
+ *cp++ = getc(0);
+ *cp = 0;
+ if ((c = rlookup(s)) == 0)
+ unget(*--cp);
+ return(c);
+}
+
+static void
+diag(ec)
+register int ec;
+{
+ register int c;
+
+ c = getc(0);
+ if (c == '>' || c == '<') {
+ if (c != ec)
+ zzerr();
+ yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE;
+ c = getc(0);
+ } else
+ yylval.i = ec == '>'? IOWRITE: IOREAD;
+ if (c != '&' || yylval.i == IOHERE)
+ unget(c);
+ else
+ yylval.i |= IODUP;
+}
+
+static char *
+tree(size)
+unsigned size;
+{
+ register char *t;
+
+ if ((t = getcell(size)) == NULL) {
+ prs("command line too complicated\n");
+ fail();
+ /* NOTREACHED */
+ }
+ return(t);
+}
+
+/* VARARGS1 */
+/* ARGSUSED */
+void
+printf(s) /* yyparse calls it */
+char *s;
+{
+}
+
diff --git a/release/picobsd/tinyware/msh/sh3.c b/release/picobsd/tinyware/msh/sh3.c
new file mode 100644
index 0000000..9aa61d2
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh3.c
@@ -0,0 +1,1143 @@
+#define Extern extern
+#include <sys/types.h>
+#include <signal.h>
+#define _NSIG NSIG
+#include <errno.h>
+#include <setjmp.h>
+#include <stddef.h>
+#include <time.h>
+#include <sys/times.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#undef NULL
+#include "sh.h"
+
+/* -------- exec.c -------- */
+/* #include "sh.h" */
+
+/*
+ * execute tree
+ */
+
+static char *signame[] = {
+ "Signal 0",
+ "Hangup",
+ (char *)NULL, /* interrupt */
+ "Quit",
+ "Illegal instruction",
+ "Trace/BPT trap",
+ "Abort",
+ "EMT trap",
+ "Floating exception",
+ "Killed",
+ "Bus error",
+ "Memory fault",
+ "Bad system call",
+ (char *)NULL, /* broken pipe */
+ "Alarm clock",
+ "Terminated",
+};
+#define NSIGNAL (sizeof(signame)/sizeof(signame[0]))
+
+
+_PROTOTYPE(static int forkexec, (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked ));
+_PROTOTYPE(static int parent, (void));
+_PROTOTYPE(int iosetup, (struct ioword *iop, int pipein, int pipeout ));
+_PROTOTYPE(static void echo, (char **wp ));
+_PROTOTYPE(static struct op **find1case, (struct op *t, char *w ));
+_PROTOTYPE(static struct op *findcase, (struct op *t, char *w ));
+_PROTOTYPE(static void brkset, (struct brkcon *bc ));
+_PROTOTYPE(int dolabel, (void));
+_PROTOTYPE(int dochdir, (struct op *t ));
+_PROTOTYPE(int doshift, (struct op *t ));
+_PROTOTYPE(int dologin, (struct op *t ));
+_PROTOTYPE(int doumask, (struct op *t ));
+_PROTOTYPE(int doexec, (struct op *t ));
+_PROTOTYPE(int dodot, (struct op *t ));
+_PROTOTYPE(int dowait, (struct op *t ));
+_PROTOTYPE(int doread, (struct op *t ));
+_PROTOTYPE(int doeval, (struct op *t ));
+_PROTOTYPE(int dotrap, (struct op *t ));
+_PROTOTYPE(int getsig, (char *s ));
+_PROTOTYPE(void setsig, (int n, void (*f)()));
+_PROTOTYPE(int getn, (char *as ));
+_PROTOTYPE(int dobreak, (struct op *t ));
+_PROTOTYPE(int docontinue, (struct op *t ));
+_PROTOTYPE(static int brkcontin, (char *cp, int val ));
+_PROTOTYPE(int doexit, (struct op *t ));
+_PROTOTYPE(int doexport, (struct op *t ));
+_PROTOTYPE(int doreadonly, (struct op *t ));
+_PROTOTYPE(static void rdexp, (char **wp, void (*f)(), int key));
+_PROTOTYPE(static void badid, (char *s ));
+_PROTOTYPE(int doset, (struct op *t ));
+_PROTOTYPE(void varput, (char *s, int out ));
+_PROTOTYPE(int dotimes, (void));
+
+int
+execute(t, pin, pout, act)
+register struct op *t;
+int *pin, *pout;
+int act;
+{
+ register struct op *t1;
+ int i, pv[2], rv, child, a;
+ char *cp, **wp, **wp2;
+ struct var *vp;
+ struct brkcon bc;
+
+ if (t == NULL)
+ return(0);
+ rv = 0;
+ a = areanum++;
+ wp = (wp2 = t->words) != NULL
+ ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY)
+ : NULL;
+
+ switch(t->type) {
+ case TPAREN:
+ case TCOM:
+ rv = forkexec(t, pin, pout, act, wp, &child);
+ if (child) {
+ exstat = rv;
+ leave();
+ }
+ break;
+
+ case TPIPE:
+ if ((rv = openpipe(pv)) < 0)
+ break;
+ pv[0] = remap(pv[0]);
+ pv[1] = remap(pv[1]);
+ (void) execute(t->left, pin, pv, 0);
+ rv = execute(t->right, pv, pout, 0);
+ break;
+
+ case TLIST:
+ (void) execute(t->left, pin, pout, 0);
+ rv = execute(t->right, pin, pout, 0);
+ break;
+
+ case TASYNC:
+ i = parent();
+ if (i != 0) {
+ if (i != -1) {
+ setval(lookup("!"), putn(i));
+ if (pin != NULL)
+ closepipe(pin);
+ if (talking) {
+ prs(putn(i));
+ prs("\n");
+ }
+ } else
+ rv = -1;
+ setstatus(rv);
+ } else {
+ signal(SIGINT, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+ if (talking)
+ signal(SIGTERM, SIG_DFL);
+ talking = 0;
+ if (pin == NULL) {
+ close(0);
+ open("/dev/null", 0);
+ }
+ exit(execute(t->left, pin, pout, FEXEC));
+ }
+ break;
+
+ case TOR:
+ case TAND:
+ rv = execute(t->left, pin, pout, 0);
+ if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND))
+ rv = execute(t1, pin, pout, 0);
+ break;
+
+ case TFOR:
+ if (wp == NULL) {
+ wp = dolv+1;
+ if ((i = dolc) < 0)
+ i = 0;
+ } else {
+ i = -1;
+ while (*wp++ != NULL)
+ ;
+ }
+ vp = lookup(t->str);
+ while (setjmp(bc.brkpt))
+ if (isbreak)
+ goto broken;
+ brkset(&bc);
+ for (t1 = t->left; i-- && *wp != NULL;) {
+ setval(vp, *wp++);
+ rv = execute(t1, pin, pout, 0);
+ }
+ brklist = brklist->nextlev;
+ break;
+
+ case TWHILE:
+ case TUNTIL:
+ while (setjmp(bc.brkpt))
+ if (isbreak)
+ goto broken;
+ brkset(&bc);
+ t1 = t->left;
+ while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE))
+ rv = execute(t->right, pin, pout, 0);
+ brklist = brklist->nextlev;
+ break;
+
+ case TIF:
+ case TELIF:
+ if (t->right != NULL) {
+ rv = !execute(t->left, pin, pout, 0) ?
+ execute(t->right->left, pin, pout, 0):
+ execute(t->right->right, pin, pout, 0);
+ }
+ break;
+
+ case TCASE:
+ if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0)
+ cp = "";
+ if ((t1 = findcase(t->left, cp)) != NULL)
+ rv = execute(t1, pin, pout, 0);
+ break;
+
+ case TBRACE:
+/*
+ if (iopp = t->ioact)
+ while (*iopp)
+ if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) {
+ rv = -1;
+ break;
+ }
+*/
+ if (rv >= 0 && (t1 = t->left))
+ rv = execute(t1, pin, pout, 0);
+ break;
+ }
+
+broken:
+ t->words = wp2;
+ isbreak = 0;
+ freehere(areanum);
+ freearea(areanum);
+ areanum = a;
+ if (talking && intr) {
+ closeall();
+ fail();
+ }
+ if ((i = trapset) != 0) {
+ trapset = 0;
+ runtrap(i);
+ }
+ return(rv);
+}
+
+static int
+forkexec(t, pin, pout, act, wp, pforked)
+register struct op *t;
+int *pin, *pout;
+int act;
+char **wp;
+int *pforked;
+{
+ int i, rv, (*shcom)();
+ register int f;
+ char *cp;
+ struct ioword **iopp;
+ int resetsig;
+ char **owp;
+
+ owp = wp;
+ resetsig = 0;
+ *pforked = 0;
+ shcom = NULL;
+ rv = -1; /* system-detected error */
+ if (t->type == TCOM) {
+ while ((cp = *wp++) != NULL)
+ ;
+ cp = *wp;
+
+ /* strip all initial assignments */
+ /* not correct wrt PATH=yyy command etc */
+ if (flag['x'])
+ echo (cp ? wp: owp);
+ if (cp == NULL && t->ioact == NULL) {
+ while ((cp = *owp++) != NULL && assign(cp, COPYV))
+ ;
+ return(setstatus(0));
+ }
+ else if (cp != NULL)
+ shcom = inbuilt(cp);
+ }
+ t->words = wp;
+ f = act;
+ if (shcom == NULL && (f & FEXEC) == 0) {
+ i = parent();
+ if (i != 0) {
+ if (i == -1)
+ return(rv);
+ if (pin != NULL)
+ closepipe(pin);
+ return(pout==NULL? setstatus(waitfor(i,0)): 0);
+ }
+ if (talking) {
+ signal(SIGINT, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+ resetsig = 1;
+ }
+ talking = 0;
+ intr = 0;
+ (*pforked)++;
+ brklist = 0;
+ execflg = 0;
+ }
+ if (owp != NULL)
+ while ((cp = *owp++) != NULL && assign(cp, COPYV))
+ if (shcom == NULL)
+ export(lookup(cp));
+#ifdef COMPIPE
+ if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) {
+ err("piping to/from shell builtins not yet done");
+ return(-1);
+ }
+#endif
+ if (pin != NULL) {
+ dup2(pin[0], 0);
+ closepipe(pin);
+ }
+ if (pout != NULL) {
+ dup2(pout[1], 1);
+ closepipe(pout);
+ }
+ if ((iopp = t->ioact) != NULL) {
+ if (shcom != NULL && shcom != doexec) {
+ prs(cp);
+ err(": cannot redirect shell command");
+ return(-1);
+ }
+ while (*iopp)
+ if (iosetup(*iopp++, pin!=NULL, pout!=NULL))
+ return(rv);
+ }
+ if (shcom)
+ return(setstatus((*shcom)(t)));
+ /* should use FIOCEXCL */
+ for (i=FDBASE; i<NOFILE; i++)
+ close(i);
+ if (resetsig) {
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ }
+ if (t->type == TPAREN)
+ exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
+ if (wp[0] == NULL)
+ exit(0);
+ cp = rexecve(wp[0], wp, makenv());
+ prs(wp[0]); prs(": "); warn(cp);
+ if (!execflg)
+ trap[0] = NULL;
+ leave();
+ /* NOTREACHED */
+}
+
+/*
+ * common actions when creating a new child
+ */
+static int
+parent()
+{
+ register int i;
+
+ i = fork();
+ if (i != 0) {
+ if (i == -1)
+ warn("try again");
+ }
+ return(i);
+}
+
+/*
+ * 0< 1> are ignored as required
+ * within pipelines.
+ */
+int
+iosetup(iop, pipein, pipeout)
+register struct ioword *iop;
+int pipein, pipeout;
+{
+ register u;
+ char *cp, *msg;
+
+ if (iop->io_unit == IODEFAULT) /* take default */
+ iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1;
+ if (pipein && iop->io_unit == 0)
+ return(0);
+ if (pipeout && iop->io_unit == 1)
+ return(0);
+ msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create";
+ if ((iop->io_flag & IOHERE) == 0) {
+ cp = iop->io_name;
+ if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL)
+ return(1);
+ }
+ if (iop->io_flag & IODUP) {
+ if (cp[1] || (!digit(*cp) && *cp != '-')) {
+ prs(cp);
+ err(": illegal >& argument");
+ return(1);
+ }
+ if (*cp == '-')
+ iop->io_flag = IOCLOSE;
+ iop->io_flag &= ~(IOREAD|IOWRITE);
+ }
+ switch (iop->io_flag) {
+ case IOREAD:
+ u = open(cp, 0);
+ break;
+
+ case IOHERE:
+ case IOHERE|IOXHERE:
+ u = herein(iop->io_name, iop->io_flag&IOXHERE);
+ cp = "here file";
+ break;
+
+ case IOWRITE|IOCAT:
+ if ((u = open(cp, 1)) >= 0) {
+ lseek(u, (long)0, 2);
+ break;
+ }
+ case IOWRITE:
+ u = creat(cp, 0666);
+ break;
+
+ case IODUP:
+ u = dup2(*cp-'0', iop->io_unit);
+ break;
+
+ case IOCLOSE:
+ close(iop->io_unit);
+ return(0);
+ }
+ if (u < 0) {
+ prs(cp);
+ prs(": cannot ");
+ warn(msg);
+ return(1);
+ } else {
+ if (u != iop->io_unit) {
+ dup2(u, iop->io_unit);
+ close(u);
+ }
+ }
+ return(0);
+}
+
+static void
+echo(wp)
+register char **wp;
+{
+ register i;
+
+ prs("+");
+ for (i=0; wp[i]; i++) {
+ if (i)
+ prs(" ");
+ prs(wp[i]);
+ }
+ prs("\n");
+}
+
+static struct op **
+find1case(t, w)
+struct op *t;
+char *w;
+{
+ register struct op *t1;
+ struct op **tp;
+ register char **wp, *cp;
+
+ if (t == NULL)
+ return((struct op **)NULL);
+ if (t->type == TLIST) {
+ if ((tp = find1case(t->left, w)) != NULL)
+ return(tp);
+ t1 = t->right; /* TPAT */
+ } else
+ t1 = t;
+ for (wp = t1->words; *wp;)
+ if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp))
+ return(&t1->left);
+ return((struct op **)NULL);
+}
+
+static struct op *
+findcase(t, w)
+struct op *t;
+char *w;
+{
+ register struct op **tp;
+
+ return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL);
+}
+
+/*
+ * Enter a new loop level (marked for break/continue).
+ */
+static void
+brkset(bc)
+struct brkcon *bc;
+{
+ bc->nextlev = brklist;
+ brklist = bc;
+}
+
+/*
+ * Wait for the last process created.
+ * Print a message for each process found
+ * that was killed by a signal.
+ * Ignore interrupt signals while waiting
+ * unless `canintr' is true.
+ */
+int
+waitfor(lastpid, canintr)
+register int lastpid;
+int canintr;
+{
+ register int pid, rv;
+ int s;
+ int oheedint = heedint;
+
+ heedint = 0;
+ rv = 0;
+ do {
+ pid = wait(&s);
+ if (pid == -1) {
+ if (errno != EINTR || canintr)
+ break;
+ } else {
+ if ((rv = WAITSIG(s)) != 0) {
+ if (rv < NSIGNAL) {
+ if (signame[rv] != NULL) {
+ if (pid != lastpid) {
+ prn(pid);
+ prs(": ");
+ }
+ prs(signame[rv]);
+ }
+ } else {
+ if (pid != lastpid) {
+ prn(pid);
+ prs(": ");
+ }
+ prs("Signal "); prn(rv); prs(" ");
+ }
+ if (WAITCORE(s))
+ prs(" - core dumped");
+ if (rv >= NSIGNAL || signame[rv])
+ prs("\n");
+ rv = -1;
+ } else
+ rv = WAITVAL(s);
+ }
+ } while (pid != lastpid);
+ heedint = oheedint;
+ if (intr)
+ if (talking) {
+ if (canintr)
+ intr = 0;
+ } else {
+ if (exstat == 0) exstat = rv;
+ onintr(0);
+ }
+ return(rv);
+}
+
+int
+setstatus(s)
+register int s;
+{
+ exstat = s;
+ setval(lookup("?"), putn(s));
+ return(s);
+}
+
+/*
+ * PATH-searching interface to execve.
+ * If getenv("PATH") were kept up-to-date,
+ * execvp might be used.
+ */
+char *
+rexecve(c, v, envp)
+char *c, **v, **envp;
+{
+ register int i;
+ register char *sp, *tp;
+ int eacces = 0, asis = 0;
+
+ sp = any('/', c)? "": path->value;
+ asis = *sp == '\0';
+ while (asis || *sp != '\0') {
+ asis = 0;
+ tp = e.linep;
+ for (; *sp != '\0'; tp++)
+ if ((*tp = *sp++) == ':') {
+ asis = *sp == '\0';
+ break;
+ }
+ if (tp != e.linep)
+ *tp++ = '/';
+ for (i = 0; (*tp++ = c[i++]) != '\0';)
+ ;
+ execve(e.linep, v, envp);
+ switch (errno) {
+ case ENOEXEC:
+ *v = e.linep;
+ tp = *--v;
+ *v = e.linep;
+ execve("/bin/sh", v, envp);
+ *v = tp;
+ return("no Shell");
+
+ case ENOMEM:
+ return("program too big");
+
+ case E2BIG:
+ return("argument list too long");
+
+ case EACCES:
+ eacces++;
+ break;
+ }
+ }
+ return(errno==ENOENT ? "not found" : "cannot execute");
+}
+
+/*
+ * Run the command produced by generator `f'
+ * applied to stream `arg'.
+ */
+int
+run(argp, f)
+struct ioarg *argp;
+int (*f)();
+{
+ struct op *otree;
+ struct wdblock *swdlist;
+ struct wdblock *siolist;
+ jmp_buf ev, rt;
+ xint *ofail;
+ int rv;
+
+ areanum++;
+ swdlist = wdlist;
+ siolist = iolist;
+ otree = outtree;
+ ofail = failpt;
+ rv = -1;
+ if (newenv(setjmp(errpt = ev)) == 0) {
+ wdlist = 0;
+ iolist = 0;
+ pushio(argp, f);
+ e.iobase = e.iop;
+ yynerrs = 0;
+ if (setjmp(failpt = rt) == 0 && yyparse() == 0)
+ rv = execute(outtree, NOPIPE, NOPIPE, 0);
+ quitenv();
+ }
+ wdlist = swdlist;
+ iolist = siolist;
+ failpt = ofail;
+ outtree = otree;
+ freearea(areanum--);
+ return(rv);
+}
+
+/* -------- do.c -------- */
+/* #include "sh.h" */
+
+/*
+ * built-in commands: doX
+ */
+
+int
+dolabel()
+{
+ return(0);
+}
+
+int
+dochdir(t)
+register struct op *t;
+{
+ register char *cp, *er;
+
+ if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL)
+ er = ": no home directory";
+ else if(chdir(cp) < 0)
+ er = ": bad directory";
+ else
+ return(0);
+ prs(cp != NULL? cp: "cd");
+ err(er);
+ return(1);
+}
+
+int
+doshift(t)
+register struct op *t;
+{
+ register n;
+
+ n = t->words[1]? getn(t->words[1]): 1;
+ if(dolc < n) {
+ err("nothing to shift");
+ return(1);
+ }
+ dolv[n] = dolv[0];
+ dolv += n;
+ dolc -= n;
+ setval(lookup("#"), putn(dolc));
+ return(0);
+}
+
+/*
+ * execute login and newgrp directly
+ */
+int
+dologin(t)
+struct op *t;
+{
+ register char *cp;
+
+ if (talking) {
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ }
+ cp = rexecve(t->words[0], t->words, makenv());
+ prs(t->words[0]); prs(": "); err(cp);
+ return(1);
+}
+
+int
+doumask(t)
+register struct op *t;
+{
+ register int i, n;
+ register char *cp;
+
+ if ((cp = t->words[1]) == NULL) {
+ i = umask(0);
+ umask(i);
+ for (n=3*4; (n-=3) >= 0;)
+ putc('0'+((i>>n)&07));
+ putc('\n');
+ } else {
+ for (n=0; *cp>='0' && *cp<='9'; cp++)
+ n = n*8 + (*cp-'0');
+ umask(n);
+ }
+ return(0);
+}
+
+int
+doexec(t)
+register struct op *t;
+{
+ register i;
+ jmp_buf ex;
+ xint *ofail;
+
+ t->ioact = NULL;
+ for(i = 0; (t->words[i]=t->words[i+1]) != NULL; i++)
+ ;
+ if (i == 0)
+ return(1);
+ execflg = 1;
+ ofail = failpt;
+ if (setjmp(failpt = ex) == 0)
+ execute(t, NOPIPE, NOPIPE, FEXEC);
+ failpt = ofail;
+ execflg = 0;
+ return(1);
+}
+
+int
+dodot(t)
+struct op *t;
+{
+ register i;
+ register char *sp, *tp;
+ char *cp;
+
+ if ((cp = t->words[1]) == NULL)
+ return(0);
+ sp = any('/', cp)? ":": path->value;
+ while (*sp) {
+ tp = e.linep;
+ while (*sp && (*tp = *sp++) != ':')
+ tp++;
+ if (tp != e.linep)
+ *tp++ = '/';
+ for (i = 0; (*tp++ = cp[i++]) != '\0';)
+ ;
+ if ((i = open(e.linep, 0)) >= 0) {
+ exstat = 0;
+ next(remap(i));
+ return(exstat);
+ }
+ }
+ prs(cp);
+ err(": not found");
+ return(-1);
+}
+
+int
+dowait(t)
+struct op *t;
+{
+ register i;
+ register char *cp;
+
+ if ((cp = t->words[1]) != NULL) {
+ i = getn(cp);
+ if (i == 0)
+ return(0);
+ } else
+ i = -1;
+ setstatus(waitfor(i, 1));
+ return(0);
+}
+
+int
+doread(t)
+struct op *t;
+{
+ register char *cp, **wp;
+ register nb;
+ register int nl = 0;
+
+ if (t->words[1] == NULL) {
+ err("usage: read name ...");
+ return(1);
+ }
+ for (wp = t->words+1; *wp; wp++) {
+ for (cp = e.linep; !nl && cp < elinep-1; cp++)
+ if ((nb = read(0, cp, sizeof(*cp))) != sizeof(*cp) ||
+ (nl = (*cp == '\n')) ||
+ (wp[1] && any(*cp, ifs->value)))
+ break;
+ *cp = 0;
+ if (nb <= 0)
+ break;
+ setval(lookup(*wp), e.linep);
+ }
+ return(nb <= 0);
+}
+
+int
+doeval(t)
+register struct op *t;
+{
+ return(RUN(awordlist, t->words+1, wdchar));
+}
+
+int
+dotrap(t)
+register struct op *t;
+{
+ register int n, i;
+ register int resetsig;
+
+ if (t->words[1] == NULL) {
+ for (i=0; i<=_NSIG; i++)
+ if (trap[i]) {
+ prn(i);
+ prs(": ");
+ prs(trap[i]);
+ prs("\n");
+ }
+ return(0);
+ }
+ resetsig = digit(*t->words[1]);
+ for (i = resetsig ? 1 : 2; t->words[i] != NULL; ++i) {
+ n = getsig(t->words[i]);
+ xfree(trap[n]);
+ trap[n] = 0;
+ if (!resetsig) {
+ if (*t->words[1] != '\0') {
+ trap[n] = strsave(t->words[1], 0);
+ setsig(n, sig);
+ } else
+ setsig(n, SIG_IGN);
+ } else {
+ if (talking)
+ if (n == SIGINT)
+ setsig(n, onintr);
+ else
+ setsig(n, n == SIGQUIT ? SIG_IGN
+ : SIG_DFL);
+ else
+ setsig(n, SIG_DFL);
+ }
+ }
+ return(0);
+}
+
+int
+getsig(s)
+char *s;
+{
+ register int n;
+
+ if ((n = getn(s)) < 0 || n > _NSIG) {
+ err("trap: bad signal number");
+ n = 0;
+ }
+ return(n);
+}
+
+void
+setsig(n, f)
+register n;
+_PROTOTYPE(void (*f), (int));
+{
+ if (n == 0)
+ return;
+ if (signal(n, SIG_IGN) != SIG_IGN || ourtrap[n]) {
+ ourtrap[n] = 1;
+ signal(n, f);
+ }
+}
+
+int
+getn(as)
+char *as;
+{
+ register char *s;
+ register n, m;
+
+ s = as;
+ m = 1;
+ if (*s == '-') {
+ m = -1;
+ s++;
+ }
+ for (n = 0; digit(*s); s++)
+ n = (n*10) + (*s-'0');
+ if (*s) {
+ prs(as);
+ err(": bad number");
+ }
+ return(n*m);
+}
+
+int
+dobreak(t)
+struct op *t;
+{
+ return(brkcontin(t->words[1], 1));
+}
+
+int
+docontinue(t)
+struct op *t;
+{
+ return(brkcontin(t->words[1], 0));
+}
+
+static int
+brkcontin(cp, val)
+register char *cp;
+int val;
+{
+ register struct brkcon *bc;
+ register nl;
+
+ nl = cp == NULL? 1: getn(cp);
+ if (nl <= 0)
+ nl = 999;
+ do {
+ if ((bc = brklist) == NULL)
+ break;
+ brklist = bc->nextlev;
+ } while (--nl);
+ if (nl) {
+ err("bad break/continue level");
+ return(1);
+ }
+ isbreak = val;
+ longjmp(bc->brkpt, 1);
+ /* NOTREACHED */
+}
+
+int
+doexit(t)
+struct op *t;
+{
+ register char *cp;
+
+ execflg = 0;
+ if ((cp = t->words[1]) != NULL)
+ setstatus(getn(cp));
+ leave();
+ /* NOTREACHED */
+}
+
+int
+doexport(t)
+struct op *t;
+{
+ rdexp(t->words+1, export, EXPORT);
+ return(0);
+}
+
+int
+doreadonly(t)
+struct op *t;
+{
+ rdexp(t->words+1, ronly, RONLY);
+ return(0);
+}
+
+static void
+rdexp(wp, f, key)
+register char **wp;
+void (*f)();
+int key;
+{
+ if (*wp != NULL) {
+ for (; *wp != NULL; wp++)
+ if (checkname(*wp))
+ (*f)(lookup(*wp));
+ else
+ badid(*wp);
+ } else
+ putvlist(key, 1);
+}
+
+static void
+badid(s)
+register char *s;
+{
+ prs(s);
+ err(": bad identifier");
+}
+
+int
+doset(t)
+register struct op *t;
+{
+ register struct var *vp;
+ register char *cp;
+ register n;
+
+ if ((cp = t->words[1]) == NULL) {
+ for (vp = vlist; vp; vp = vp->next)
+ varput(vp->name, 1);
+ return(0);
+ }
+ if (*cp == '-') {
+ /* bad: t->words++; */
+ for(n = 0; (t->words[n]=t->words[n+1]) != NULL; n++)
+ ;
+ if (*++cp == 0)
+ flag['x'] = flag['v'] = 0;
+ else
+ for (; *cp; cp++)
+ switch (*cp) {
+ case 'e':
+ if (!talking)
+ flag['e']++;
+ break;
+
+ default:
+ if (*cp>='a' && *cp<='z')
+ flag[*cp]++;
+ break;
+ }
+ setdash();
+ }
+ if (t->words[1]) {
+ t->words[0] = dolv[0];
+ for (n=1; t->words[n]; n++)
+ setarea((char *)t->words[n], 0);
+ dolc = n-1;
+ dolv = t->words;
+ setval(lookup("#"), putn(dolc));
+ setarea((char *)(dolv-1), 0);
+ }
+ return(0);
+}
+
+void
+varput(s, out)
+register char *s;
+int out;
+{
+ if (letnum(*s)) {
+ write(out, s, strlen(s));
+ write(out, "\n", 1);
+ }
+}
+
+
+#define SECS 60L
+#define MINS 3600L
+
+int
+dotimes()
+{
+ struct tms tbuf;
+
+ times(&tbuf);
+
+ prn((int)(tbuf.tms_cutime / MINS));
+ prs("m");
+ prn((int)((tbuf.tms_cutime % MINS) / SECS));
+ prs("s ");
+ prn((int)(tbuf.tms_cstime / MINS));
+ prs("m");
+ prn((int)((tbuf.tms_cstime % MINS) / SECS));
+ prs("s\n");
+ return(0);
+}
+
+struct builtin {
+ char *command;
+ int (*fn)();
+};
+static struct builtin builtin[] = {
+ ":", dolabel,
+ "cd", dochdir,
+ "shift", doshift,
+ "exec", doexec,
+ "wait", dowait,
+ "read", doread,
+ "eval", doeval,
+ "trap", dotrap,
+ "break", dobreak,
+ "continue", docontinue,
+ "exit", doexit,
+ "export", doexport,
+ "readonly", doreadonly,
+ "set", doset,
+ ".", dodot,
+ "umask", doumask,
+ "login", dologin,
+ "newgrp", dologin,
+ "times", dotimes,
+ 0,
+};
+
+int (*inbuilt(s))()
+register char *s;
+{
+ register struct builtin *bp;
+
+ for (bp = builtin; bp->command != NULL; bp++)
+ if (strcmp(bp->command, s) == 0)
+ return(bp->fn);
+ return((int(*)())NULL);
+}
+
diff --git a/release/picobsd/tinyware/msh/sh4.c b/release/picobsd/tinyware/msh/sh4.c
new file mode 100644
index 0000000..ac2a582
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh4.c
@@ -0,0 +1,767 @@
+#define Extern extern
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <limits.h>
+#include <signal.h>
+#define _NSIG NSIG
+#include <errno.h>
+#include <setjmp.h>
+#include "sh.h"
+
+/* -------- eval.c -------- */
+/* #include "sh.h" */
+/* #include "word.h" */
+
+/*
+ * ${}
+ * `command`
+ * blank interpretation
+ * quoting
+ * glob
+ */
+
+_PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f ));
+_PROTOTYPE(static char *blank, (int f ));
+_PROTOTYPE(static int dollar, (int quoted ));
+_PROTOTYPE(static int grave, (int quoted ));
+_PROTOTYPE(void globname, (char *we, char *pp ));
+_PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end ));
+_PROTOTYPE(static int anyspcl, (struct wdblock *wb ));
+_PROTOTYPE(static int xstrcmp, (char *p1, char *p2 ));
+_PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *)));
+_PROTOTYPE(void glob1, (char *base, char *lim ));
+_PROTOTYPE(void glob2, (char *i, char *j ));
+_PROTOTYPE(void glob3, (char *i, char *j, char *k ));
+_PROTOTYPE(char *memcopy, (char *ato, char *from, int nb ));
+
+char **
+eval(ap, f)
+register char **ap;
+int f;
+{
+ struct wdblock *wb;
+ char **wp;
+ char **wf;
+ jmp_buf ev;
+
+ wp = NULL;
+ wb = NULL;
+ wf = NULL;
+ if (newenv(setjmp(errpt = ev)) == 0) {
+ while (*ap && isassign(*ap))
+ expand(*ap++, &wb, f & ~DOGLOB);
+ if (flag['k']) {
+ for (wf = ap; *wf; wf++) {
+ if (isassign(*wf))
+ expand(*wf, &wb, f & ~DOGLOB);
+ }
+ }
+ for (wb = addword((char *)0, wb); *ap; ap++) {
+ if (!flag['k'] || !isassign(*ap))
+ expand(*ap, &wb, f & ~DOKEY);
+ }
+ wb = addword((char *)0, wb);
+ wp = getwords(wb);
+ quitenv();
+ } else
+ gflg = 1;
+ return(gflg? (char **)NULL: wp);
+}
+
+/*
+ * Make the exported environment from the exported
+ * names in the dictionary. Keyword assignments
+ * will already have been done.
+ */
+char **
+makenv()
+
+{
+ register struct wdblock *wb;
+ register struct var *vp;
+
+ wb = NULL;
+ for (vp = vlist; vp; vp = vp->next)
+ if (vp->status & EXPORT)
+ wb = addword(vp->name, wb);
+ wb = addword((char *)0, wb);
+ return(getwords(wb));
+}
+
+char *
+evalstr(cp, f)
+register char *cp;
+int f;
+{
+ struct wdblock *wb;
+
+ wb = NULL;
+ if (expand(cp, &wb, f)) {
+ if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)
+ cp = "";
+ DELETE(wb);
+ } else
+ cp = NULL;
+ return(cp);
+}
+
+static int
+expand(cp, wbp, f)
+register char *cp;
+register struct wdblock **wbp;
+int f;
+{
+ jmp_buf ev;
+
+ gflg = 0;
+ if (cp == NULL)
+ return(0);
+ if (!anys("$`'\"", cp) &&
+ !anys(ifs->value, cp) &&
+ ((f&DOGLOB)==0 || !anys("[*?", cp))) {
+ cp = strsave(cp, areanum);
+ if (f & DOTRIM)
+ unquote(cp);
+ *wbp = addword(cp, *wbp);
+ return(1);
+ }
+ if (newenv(setjmp(errpt = ev)) == 0) {
+ PUSHIO(aword, cp, strchar);
+ e.iobase = e.iop;
+ while ((cp = blank(f)) && gflg == 0) {
+ e.linep = cp;
+ cp = strsave(cp, areanum);
+ if ((f&DOGLOB) == 0) {
+ if (f & DOTRIM)
+ unquote(cp);
+ *wbp = addword(cp, *wbp);
+ } else
+ *wbp = glob(cp, *wbp);
+ }
+ quitenv();
+ } else
+ gflg = 1;
+ return(gflg == 0);
+}
+
+/*
+ * Blank interpretation and quoting
+ */
+static char *
+blank(f)
+int f;
+{
+ register c, c1;
+ register char *sp;
+ int scanequals, foundequals;
+
+ sp = e.linep;
+ scanequals = f & DOKEY;
+ foundequals = 0;
+
+loop:
+ switch (c = subgetc('"', foundequals)) {
+ case 0:
+ if (sp == e.linep)
+ return(0);
+ *e.linep++ = 0;
+ return(sp);
+
+ default:
+ if (f & DOBLANK && any(c, ifs->value))
+ goto loop;
+ break;
+
+ case '"':
+ case '\'':
+ scanequals = 0;
+ if (INSUB())
+ break;
+ for (c1 = c; (c = subgetc(c1, 1)) != c1;) {
+ if (c == 0)
+ break;
+ if (c == '\'' || !any(c, "$`\""))
+ c |= QUOTE;
+ *e.linep++ = c;
+ }
+ c = 0;
+ }
+ unget(c);
+ if (!letter(c))
+ scanequals = 0;
+ for (;;) {
+ c = subgetc('"', foundequals);
+ if (c == 0 ||
+ f & (DOBLANK && any(c, ifs->value)) ||
+ (!INSUB() && any(c, "\"'"))) {
+ scanequals = 0;
+ unget(c);
+ if (any(c, "\"'"))
+ goto loop;
+ break;
+ }
+ if (scanequals)
+ if (c == '=') {
+ foundequals = 1;
+ scanequals = 0;
+ }
+ else if (!letnum(c))
+ scanequals = 0;
+ *e.linep++ = c;
+ }
+ *e.linep++ = 0;
+ return(sp);
+}
+
+/*
+ * Get characters, substituting for ` and $
+ */
+int
+subgetc(ec, quoted)
+register char ec;
+int quoted;
+{
+ register char c;
+
+again:
+ c = getc(ec);
+ if (!INSUB() && ec != '\'') {
+ if (c == '`') {
+ if (grave(quoted) == 0)
+ return(0);
+ e.iop->task = XGRAVE;
+ goto again;
+ }
+ if (c == '$' && (c = dollar(quoted)) == 0) {
+ e.iop->task = XDOLL;
+ goto again;
+ }
+ }
+ return(c);
+}
+
+/*
+ * Prepare to generate the string returned by ${} substitution.
+ */
+static int
+dollar(quoted)
+int quoted;
+{
+ int otask;
+ struct io *oiop;
+ char *dolp;
+ register char *s, c, *cp;
+ struct var *vp;
+
+ c = readc();
+ s = e.linep;
+ if (c != '{') {
+ *e.linep++ = c;
+ if (letter(c)) {
+ while ((c = readc())!=0 && letnum(c))
+ if (e.linep < elinep)
+ *e.linep++ = c;
+ unget(c);
+ }
+ c = 0;
+ } else {
+ oiop = e.iop;
+ otask = e.iop->task;
+ e.iop->task = XOTHER;
+ while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')
+ if (e.linep < elinep)
+ *e.linep++ = c;
+ if (oiop == e.iop)
+ e.iop->task = otask;
+ if (c != '}') {
+ err("unclosed ${");
+ gflg++;
+ return(c);
+ }
+ }
+ if (e.linep >= elinep) {
+ err("string in ${} too long");
+ gflg++;
+ e.linep -= 10;
+ }
+ *e.linep = 0;
+ if (*s)
+ for (cp = s+1; *cp; cp++)
+ if (any(*cp, "=-+?")) {
+ c = *cp;
+ *cp++ = 0;
+ break;
+ }
+ if (s[1] == 0 && (*s == '*' || *s == '@')) {
+ if (dolc > 1) {
+ /* currently this does not distinguish $* and $@ */
+ /* should check dollar */
+ e.linep = s;
+ PUSHIO(awordlist, dolv+1, dolchar);
+ return(0);
+ } else { /* trap the nasty ${=} */
+ s[0] = '1';
+ s[1] = 0;
+ }
+ }
+ vp = lookup(s);
+ if ((dolp = vp->value) == null) {
+ switch (c) {
+ case '=':
+ if (digit(*s)) {
+ err("cannot use ${...=...} with $n");
+ gflg++;
+ break;
+ }
+ setval(vp, cp);
+ dolp = vp->value;
+ break;
+
+ case '-':
+ dolp = strsave(cp, areanum);
+ break;
+
+ case '?':
+ if (*cp == 0) {
+ prs("missing value for ");
+ err(s);
+ } else
+ err(cp);
+ gflg++;
+ break;
+ }
+ } else if (c == '+')
+ dolp = strsave(cp, areanum);
+ if (flag['u'] && dolp == null) {
+ prs("unset variable: ");
+ err(s);
+ gflg++;
+ }
+ e.linep = s;
+ PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
+ return(0);
+}
+
+/*
+ * Run the command in `...` and read its output.
+ */
+static int
+grave(quoted)
+int quoted;
+{
+ register char *cp;
+ register int i;
+ int pf[2];
+
+ for (cp = e.iop->argp->aword; *cp != '`'; cp++)
+ if (*cp == 0) {
+ err("no closing `");
+ return(0);
+ }
+ if (openpipe(pf) < 0)
+ return(0);
+ if ((i = fork()) == -1) {
+ closepipe(pf);
+ err("try again");
+ return(0);
+ }
+ if (i != 0) {
+ e.iop->argp->aword = ++cp;
+ close(pf[1]);
+ PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);
+ return(1);
+ }
+ *cp = 0;
+ /* allow trapped signals */
+ for (i=0; i<=_NSIG; i++)
+ if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)
+ signal(i, SIG_DFL);
+ dup2(pf[1], 1);
+ closepipe(pf);
+ flag['e'] = 0;
+ flag['v'] = 0;
+ flag['n'] = 0;
+ cp = strsave(e.iop->argp->aword, 0);
+ areanum = 1;
+ freehere(areanum);
+ freearea(areanum); /* free old space */
+ e.oenv = NULL;
+ e.iop = (e.iobase = iostack) - 1;
+ unquote(cp);
+ talking = 0;
+ PUSHIO(aword, cp, nlchar);
+ onecommand();
+ exit(1);
+}
+
+char *
+unquote(as)
+register char *as;
+{
+ register char *s;
+
+ if ((s = as) != NULL)
+ while (*s)
+ *s++ &= ~QUOTE;
+ return(as);
+}
+
+/* -------- glob.c -------- */
+/* #include "sh.h" */
+
+/*
+ * glob
+ */
+
+#define scopy(x) strsave((x), areanum)
+#define BLKSIZ 512
+#define NDENT ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent))
+
+static struct wdblock *cl, *nl;
+static char spcl[] = "[?*";
+
+struct wdblock *
+glob(cp, wb)
+char *cp;
+struct wdblock *wb;
+{
+ register i;
+ register char *pp;
+
+ if (cp == 0)
+ return(wb);
+ i = 0;
+ for (pp = cp; *pp; pp++)
+ if (any(*pp, spcl))
+ i++;
+ else if (!any(*pp & ~QUOTE, spcl))
+ *pp &= ~QUOTE;
+ if (i != 0) {
+ for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) {
+ nl = newword(cl->w_nword*2);
+ for(i=0; i<cl->w_nword; i++) { /* for each argument */
+ for (pp = cl->w_words[i]; *pp; pp++)
+ if (any(*pp, spcl)) {
+ globname(cl->w_words[i], pp);
+ break;
+ }
+ if (*pp == '\0')
+ nl = addword(scopy(cl->w_words[i]), nl);
+ }
+ for(i=0; i<cl->w_nword; i++)
+ DELETE(cl->w_words[i]);
+ DELETE(cl);
+ }
+ for(i=0; i<cl->w_nword; i++)
+ unquote(cl->w_words[i]);
+ glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp);
+ if (cl->w_nword) {
+ for (i=0; i<cl->w_nword; i++)
+ wb = addword(cl->w_words[i], wb);
+ DELETE(cl);
+ return(wb);
+ }
+ }
+ wb = addword(unquote(cp), wb);
+ return(wb);
+}
+
+void
+globname(we, pp)
+char *we;
+register char *pp;
+{
+ register char *np, *cp;
+ char *name, *gp, *dp;
+ int dn, j, n, k;
+ DIR *dirp;
+ struct dirent *de;
+ char dname[NAME_MAX+1];
+ struct stat dbuf;
+
+ for (np = we; np != pp; pp--)
+ if (pp[-1] == '/')
+ break;
+ for (dp = cp = space((int)(pp-np)+3); np < pp;)
+ *cp++ = *np++;
+ *cp++ = '.';
+ *cp = '\0';
+ for (gp = cp = space(strlen(pp)+1); *np && *np != '/';)
+ *cp++ = *np++;
+ *cp = '\0';
+ dirp = opendir(dp);
+ if (dirp == 0) {
+ DELETE(dp);
+ DELETE(gp);
+ return;
+ }
+ dname[NAME_MAX] = '\0';
+ while ((de=readdir(dirp))!=NULL) {
+ /* XXX Hmmm... What this could be? (abial) */
+ /*
+ if (ent[j].d_ino == 0)
+ continue;
+ */
+ strncpy(dname, de->d_name, NAME_MAX);
+ if (dname[0] == '.')
+ if (*gp != '.')
+ continue;
+ for(k=0; k<NAME_MAX; k++)
+ if (any(dname[k], spcl))
+ dname[k] |= QUOTE;
+ if (gmatch(dname, gp)) {
+ name = generate(we, pp, dname, np);
+ if (*np && !anys(np, spcl)) {
+ if (stat(name,&dbuf)) {
+ DELETE(name);
+ continue;
+ }
+ }
+ nl = addword(name, nl);
+ }
+ }
+ closedir(dirp);
+ DELETE(dp);
+ DELETE(gp);
+}
+
+/*
+ * generate a pathname as below.
+ * start..end1 / middle end
+ * the slashes come for free
+ */
+static char *
+generate(start1, end1, middle, end)
+char *start1;
+register char *end1;
+char *middle, *end;
+{
+ char *p;
+ register char *op, *xp;
+
+ p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);
+ for (xp = start1; xp != end1;)
+ *op++ = *xp++;
+ for (xp = middle; (*op++ = *xp++) != '\0';)
+ ;
+ op--;
+ for (xp = end; (*op++ = *xp++) != '\0';)
+ ;
+ return(p);
+}
+
+static int
+anyspcl(wb)
+register struct wdblock *wb;
+{
+ register i;
+ register char **wd;
+
+ wd = wb->w_words;
+ for (i=0; i<wb->w_nword; i++)
+ if (anys(spcl, *wd++))
+ return(1);
+ return(0);
+}
+
+static int
+xstrcmp(p1, p2)
+char *p1, *p2;
+{
+ return(strcmp(*(char **)p1, *(char **)p2));
+}
+
+/* -------- word.c -------- */
+/* #include "sh.h" */
+/* #include "word.h" */
+
+#define NSTART 16 /* default number of words to allow for initially */
+
+struct wdblock *
+newword(nw)
+register int nw;
+{
+ register struct wdblock *wb;
+
+ wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));
+ wb->w_bsize = nw;
+ wb->w_nword = 0;
+ return(wb);
+}
+
+struct wdblock *
+addword(wd, wb)
+char *wd;
+register struct wdblock *wb;
+{
+ register struct wdblock *wb2;
+ register nw;
+
+ if (wb == NULL)
+ wb = newword(NSTART);
+ if ((nw = wb->w_nword) >= wb->w_bsize) {
+ wb2 = newword(nw * 2);
+ memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *));
+ wb2->w_nword = nw;
+ DELETE(wb);
+ wb = wb2;
+ }
+ wb->w_words[wb->w_nword++] = wd;
+ return(wb);
+}
+
+char **
+getwords(wb)
+register struct wdblock *wb;
+{
+ register char **wd;
+ register nb;
+
+ if (wb == NULL)
+ return((char **)NULL);
+ if (wb->w_nword == 0) {
+ DELETE(wb);
+ return((char **)NULL);
+ }
+ wd = (char **) space(nb = sizeof(*wd) * wb->w_nword);
+ memcopy((char *)wd, (char *)wb->w_words, nb);
+ DELETE(wb); /* perhaps should done by caller */
+ return(wd);
+}
+
+_PROTOTYPE(int (*func), (char *, char *));
+int globv;
+
+void
+glob0(a0, a1, a2, a3)
+char *a0;
+unsigned a1;
+int a2;
+_PROTOTYPE(int (*a3), (char *, char *));
+{
+ func = a3;
+ globv = a2;
+ glob1(a0, a0 + a1 * a2);
+}
+
+void
+glob1(base, lim)
+char *base, *lim;
+{
+ register char *i, *j;
+ int v2;
+ char *lptr, *hptr;
+ int c;
+ unsigned n;
+
+
+ v2 = globv;
+
+top:
+ if ((n=(int)(lim-base)) <= v2)
+ return;
+ n = v2 * (n / (2*v2));
+ hptr = lptr = base+n;
+ i = base;
+ j = lim-v2;
+ for(;;) {
+ if (i < lptr) {
+ if ((c = (*func)(i, lptr)) == 0) {
+ glob2(i, lptr -= v2);
+ continue;
+ }
+ if (c < 0) {
+ i += v2;
+ continue;
+ }
+ }
+
+begin:
+ if (j > hptr) {
+ if ((c = (*func)(hptr, j)) == 0) {
+ glob2(hptr += v2, j);
+ goto begin;
+ }
+ if (c > 0) {
+ if (i == lptr) {
+ glob3(i, hptr += v2, j);
+ i = lptr += v2;
+ goto begin;
+ }
+ glob2(i, j);
+ j -= v2;
+ i += v2;
+ continue;
+ }
+ j -= v2;
+ goto begin;
+ }
+
+
+ if (i == lptr) {
+ if (lptr-base >= lim-hptr) {
+ glob1(hptr+v2, lim);
+ lim = lptr;
+ } else {
+ glob1(base, lptr);
+ base = hptr+v2;
+ }
+ goto top;
+ }
+
+
+ glob3(j, lptr -= v2, i);
+ j = hptr -= v2;
+ }
+}
+
+void
+glob2(i, j)
+char *i, *j;
+{
+ register char *index1, *index2, c;
+ int m;
+
+ m = globv;
+ index1 = i;
+ index2 = j;
+ do {
+ c = *index1;
+ *index1++ = *index2;
+ *index2++ = c;
+ } while(--m);
+}
+
+void
+glob3(i, j, k)
+char *i, *j, *k;
+{
+ register char *index1, *index2, *index3;
+ int c;
+ int m;
+
+ m = globv;
+ index1 = i;
+ index2 = j;
+ index3 = k;
+ do {
+ c = *index1;
+ *index1++ = *index3;
+ *index3++ = *index2;
+ *index2++ = c;
+ } while(--m);
+}
+
+char *
+memcopy(ato, from, nb)
+register char *ato, *from;
+register int nb;
+{
+ register char *to;
+
+ to = ato;
+ while (--nb >= 0)
+ *to++ = *from++;
+ return(ato);
+}
diff --git a/release/picobsd/tinyware/msh/sh5.c b/release/picobsd/tinyware/msh/sh5.c
new file mode 100644
index 0000000..74feac9
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh5.c
@@ -0,0 +1,675 @@
+#define Extern extern
+#include <sys/types.h>
+#include <signal.h>
+#define _NSIG NSIG
+#include <errno.h>
+#include <setjmp.h>
+#include "sh.h"
+
+/* -------- io.c -------- */
+/* #include "sh.h" */
+
+/*
+ * shell IO
+ */
+
+static struct iobuf sharedbuf = {AFID_NOBUF};
+static struct iobuf mainbuf = {AFID_NOBUF};
+static unsigned bufid = AFID_ID; /* buffer id counter */
+
+struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
+
+_PROTOTYPE(static void readhere, (char **name, char *s, int ec ));
+_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)()));
+_PROTOTYPE(static int xxchar, (struct ioarg *ap ));
+_PROTOTYPE(void tempname, (char *tname ));
+
+int
+getc(ec)
+register int ec;
+{
+ register int c;
+
+ if(e.linep > elinep) {
+ while((c=readc()) != '\n' && c)
+ ;
+ err("input line too long");
+ gflg++;
+ return(c);
+ }
+ c = readc();
+ if (ec != '\'' && e.iop->task != XGRAVE) {
+ if(c == '\\') {
+ c = readc();
+ if (c == '\n' && ec != '\"')
+ return(getc(ec));
+ c |= QUOTE;
+ }
+ }
+ return(c);
+}
+
+void
+unget(c)
+int c;
+{
+ if (e.iop >= e.iobase)
+ e.iop->peekc = c;
+}
+
+int
+eofc()
+
+{
+ return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
+}
+
+int
+readc()
+{
+ register c;
+
+ for (; e.iop >= e.iobase; e.iop--)
+ if ((c = e.iop->peekc) != '\0') {
+ e.iop->peekc = 0;
+ return(c);
+ }
+ else {
+ if (e.iop->prev != 0) {
+ if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {
+ if (c == -1) {
+ e.iop++;
+ continue;
+ }
+ if (e.iop == iostack)
+ ioecho(c);
+ return(e.iop->prev = c);
+ }
+ else if (e.iop->task == XIO && e.iop->prev != '\n') {
+ e.iop->prev = 0;
+ if (e.iop == iostack)
+ ioecho('\n');
+ return '\n';
+ }
+ }
+ if (e.iop->task == XIO) {
+ if (multiline)
+ return e.iop->prev = 0;
+ if (talking && e.iop == iostack+1)
+ prs(prompt->value);
+ }
+ }
+ if (e.iop >= iostack)
+ return(0);
+ leave();
+ /* NOTREACHED */
+}
+
+void
+ioecho(c)
+char c;
+{
+ if (flag['v'])
+ write(2, &c, sizeof c);
+}
+
+void
+pushio(argp, fn)
+struct ioarg *argp;
+int (*fn)();
+{
+ if (++e.iop >= &iostack[NPUSH]) {
+ e.iop--;
+ err("Shell input nested too deeply");
+ gflg++;
+ return;
+ }
+ e.iop->iofn = fn;
+
+ if (argp->afid != AFID_NOBUF)
+ e.iop->argp = argp;
+ else {
+ e.iop->argp = ioargstack + (e.iop - iostack);
+ *e.iop->argp = *argp;
+ e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
+ if (isatty(e.iop->argp->afile) == 0 &&
+ (e.iop == &iostack[0] ||
+ lseek(e.iop->argp->afile, 0L, 1) != -1)) {
+ if (++bufid == AFID_NOBUF)
+ bufid = AFID_ID;
+ e.iop->argp->afid = bufid;
+ }
+ }
+
+ e.iop->prev = ~'\n';
+ e.iop->peekc = 0;
+ e.iop->xchar = 0;
+ e.iop->nlcount = 0;
+ if (fn == filechar || fn == linechar)
+ e.iop->task = XIO;
+ else if (fn == gravechar || fn == qgravechar)
+ e.iop->task = XGRAVE;
+ else
+ e.iop->task = XOTHER;
+}
+
+struct io *
+setbase(ip)
+struct io *ip;
+{
+ register struct io *xp;
+
+ xp = e.iobase;
+ e.iobase = ip;
+ return(xp);
+}
+
+/*
+ * Input generating functions
+ */
+
+/*
+ * Produce the characters of a string, then a newline, then EOF.
+ */
+int
+nlchar(ap)
+register struct ioarg *ap;
+{
+ register int c;
+
+ if (ap->aword == NULL)
+ return(0);
+ if ((c = *ap->aword++) == 0) {
+ ap->aword = NULL;
+ return('\n');
+ }
+ return(c);
+}
+
+/*
+ * Given a list of words, produce the characters
+ * in them, with a space after each word.
+ */
+int
+wdchar(ap)
+register struct ioarg *ap;
+{
+ register char c;
+ register char **wl;
+
+ if ((wl = ap->awordlist) == NULL)
+ return(0);
+ if (*wl != NULL) {
+ if ((c = *(*wl)++) != 0)
+ return(c & 0177);
+ ap->awordlist++;
+ return(' ');
+ }
+ ap->awordlist = NULL;
+ return('\n');
+}
+
+/*
+ * Return the characters of a list of words,
+ * producing a space between them.
+ */
+int
+dolchar(ap)
+register struct ioarg *ap;
+{
+ register char *wp;
+
+ if ((wp = *ap->awordlist++) != NULL) {
+ PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
+ return(-1);
+ }
+ return(0);
+}
+
+static int
+xxchar(ap)
+register struct ioarg *ap;
+{
+ register int c;
+
+ if (ap->aword == NULL)
+ return(0);
+ if ((c = *ap->aword++) == '\0') {
+ ap->aword = NULL;
+ return(' ');
+ }
+ return(c);
+}
+
+/*
+ * Produce the characters from a single word (string).
+ */
+int
+strchar(ap)
+register struct ioarg *ap;
+{
+ register int c;
+
+ if (ap->aword == NULL || (c = *ap->aword++) == 0)
+ return(0);
+ return(c);
+}
+
+/*
+ * Produce quoted characters from a single word (string).
+ */
+int
+qstrchar(ap)
+register struct ioarg *ap;
+{
+ register int c;
+
+ if (ap->aword == NULL || (c = *ap->aword++) == 0)
+ return(0);
+ return(c|QUOTE);
+}
+
+/*
+ * Return the characters from a file.
+ */
+int
+filechar(ap)
+register struct ioarg *ap;
+{
+ register int i;
+ char c;
+ struct iobuf *bp = ap->afbuf;
+
+ if (ap->afid != AFID_NOBUF) {
+ if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
+ if (i)
+ lseek(ap->afile, ap->afpos, 0);
+ do {
+ i = read(ap->afile, bp->buf, sizeof(bp->buf));
+ } while (i < 0 && errno == EINTR);
+ if (i <= 0) {
+ closef(ap->afile);
+ return 0;
+ }
+ bp->id = ap->afid;
+ bp->ebufp = (bp->bufp = bp->buf) + i;
+ }
+ ap->afpos++;
+ return *bp->bufp++ & 0177;
+ }
+
+ do {
+ i = read(ap->afile, &c, sizeof(c));
+ } while (i < 0 && errno == EINTR);
+ return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
+}
+
+/*
+ * Return the characters from a here temp file.
+ */
+int
+herechar(ap)
+register struct ioarg *ap;
+{
+ char c;
+
+
+ if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {
+ close(ap->afile);
+ c = 0;
+ }
+ return (c);
+
+}
+
+/*
+ * Return the characters produced by a process (`...`).
+ * Quote them if required, and remove any trailing newline characters.
+ */
+int
+gravechar(ap, iop)
+struct ioarg *ap;
+struct io *iop;
+{
+ register int c;
+
+ if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
+ c = ' ';
+ return(c);
+}
+
+int
+qgravechar(ap, iop)
+register struct ioarg *ap;
+struct io *iop;
+{
+ register int c;
+
+ if (iop->xchar) {
+ if (iop->nlcount) {
+ iop->nlcount--;
+ return('\n'|QUOTE);
+ }
+ c = iop->xchar;
+ iop->xchar = 0;
+ } else if ((c = filechar(ap)) == '\n') {
+ iop->nlcount = 1;
+ while ((c = filechar(ap)) == '\n')
+ iop->nlcount++;
+ iop->xchar = c;
+ if (c == 0)
+ return(c);
+ iop->nlcount--;
+ c = '\n';
+ }
+ return(c!=0? c|QUOTE: 0);
+}
+
+/*
+ * Return a single command (usually the first line) from a file.
+ */
+int
+linechar(ap)
+register struct ioarg *ap;
+{
+ register int c;
+
+ if ((c = filechar(ap)) == '\n') {
+ if (!multiline) {
+ closef(ap->afile);
+ ap->afile = -1; /* illegal value */
+ }
+ }
+ return(c);
+}
+
+void
+prs(s)
+register char *s;
+{
+ if (*s)
+ write(2, s, strlen(s));
+}
+
+void
+putc(c)
+char c;
+{
+ write(2, &c, sizeof c);
+}
+
+void
+prn(u)
+unsigned u;
+{
+ prs(itoa(u, 0));
+}
+
+void
+closef(i)
+register int i;
+{
+ if (i > 2)
+ close(i);
+}
+
+void
+closeall()
+{
+ register u;
+
+ for (u=NUFILE; u<NOFILE;)
+ close(u++);
+}
+
+/*
+ * remap fd into Shell's fd space
+ */
+int
+remap(fd)
+register int fd;
+{
+ register int i;
+ int map[NOFILE];
+
+ if (fd < e.iofd) {
+ for (i=0; i<NOFILE; i++)
+ map[i] = 0;
+ do {
+ map[fd] = 1;
+ fd = dup(fd);
+ } while (fd >= 0 && fd < e.iofd);
+ for (i=0; i<NOFILE; i++)
+ if (map[i])
+ close(i);
+ if (fd < 0)
+ err("too many files open in shell");
+ }
+ return(fd);
+}
+
+int
+openpipe(pv)
+register int *pv;
+{
+ register int i;
+
+ if ((i = pipe(pv)) < 0)
+ err("can't create pipe - try again");
+ return(i);
+}
+
+void
+closepipe(pv)
+register int *pv;
+{
+ if (pv != NULL) {
+ close(*pv++);
+ close(*pv);
+ }
+}
+
+/* -------- here.c -------- */
+/* #include "sh.h" */
+
+/*
+ * here documents
+ */
+
+struct here {
+ char *h_tag;
+ int h_dosub;
+ struct ioword *h_iop;
+ struct here *h_next;
+};
+
+static struct here *inhere; /* list of hear docs while parsing */
+static struct here *acthere; /* list of active here documents */
+
+void
+markhere(s, iop)
+register char *s;
+struct ioword *iop;
+{
+ register struct here *h, *lh;
+
+ h = (struct here *) space(sizeof(struct here));
+ if (h == 0)
+ return;
+ h->h_tag = evalstr(s, DOSUB);
+ if (h->h_tag == 0)
+ return;
+ h->h_iop = iop;
+ iop->io_name = 0;
+ h->h_next = NULL;
+ if (inhere == 0)
+ inhere = h;
+ else
+ for (lh = inhere; lh!=NULL; lh = lh->h_next)
+ if (lh->h_next == 0) {
+ lh->h_next = h;
+ break;
+ }
+ iop->io_flag |= IOHERE|IOXHERE;
+ for (s = h->h_tag; *s; s++)
+ if (*s & QUOTE) {
+ iop->io_flag &= ~ IOXHERE;
+ *s &= ~ QUOTE;
+ }
+ h->h_dosub = iop->io_flag & IOXHERE;
+}
+
+void
+gethere()
+{
+ register struct here *h, *hp;
+
+ /* Scan here files first leaving inhere list in place */
+ for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
+ readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');
+
+ /* Make inhere list active - keep list intact for scraphere */
+ if (hp != NULL) {
+ hp->h_next = acthere;
+ acthere = inhere;
+ inhere = NULL;
+ }
+}
+
+static void
+readhere(name, s, ec)
+char **name;
+register char *s;
+int ec;
+{
+ int tf;
+ char tname[30];
+ register c;
+ jmp_buf ev;
+ char line [LINELIM+1];
+ char *next;
+
+ tempname(tname);
+ *name = strsave(tname, areanum);
+ tf = creat(tname, 0600);
+ if (tf < 0)
+ return;
+ if (newenv(setjmp(errpt = ev)) != 0)
+ unlink(tname);
+ else {
+ pushio(e.iop->argp, e.iop->iofn);
+ e.iobase = e.iop;
+ for (;;) {
+ if (talking && e.iop <= iostack)
+ prs(cprompt->value);
+ next = line;
+ while ((c = getc(ec)) != '\n' && c) {
+ if (ec == '\'')
+ c &= ~ QUOTE;
+ if (next >= &line[LINELIM]) {
+ c = 0;
+ break;
+ }
+ *next++ = c;
+ }
+ *next = 0;
+ if (strcmp(s, line) == 0 || c == 0)
+ break;
+ *next++ = '\n';
+ write (tf, line, (int)(next-line));
+ }
+ if (c == 0) {
+ prs("here document `"); prs(s); err("' unclosed");
+ }
+ quitenv();
+ }
+ close(tf);
+}
+
+/*
+ * open here temp file.
+ * if unquoted here, expand here temp file into second temp file.
+ */
+int
+herein(hname, xdoll)
+char *hname;
+int xdoll;
+{
+ register hf, tf;
+
+ if (hname == 0)
+ return(-1);
+ hf = open(hname, 0);
+ if (hf < 0)
+ return (-1);
+ if (xdoll) {
+ char c;
+ char tname[30];
+ jmp_buf ev;
+
+ tempname(tname);
+ if ((tf = creat(tname, 0600)) < 0)
+ return (-1);
+ if (newenv(setjmp(errpt = ev)) == 0) {
+ PUSHIO(afile, hf, herechar);
+ setbase(e.iop);
+ while ((c = subgetc(0, 0)) != 0) {
+ c &= ~ QUOTE;
+ write(tf, &c, sizeof c);
+ }
+ quitenv();
+ } else
+ unlink(tname);
+ close(tf);
+ tf = open(tname, 0);
+ unlink(tname);
+ return (tf);
+ } else
+ return (hf);
+}
+
+void
+scraphere()
+{
+ register struct here *h;
+
+ for (h = inhere; h != NULL; h = h->h_next) {
+ if (h->h_iop && h->h_iop->io_name)
+ unlink(h->h_iop->io_name);
+ }
+ inhere = NULL;
+}
+
+/* unlink here temp files before a freearea(area) */
+void
+freehere(area)
+int area;
+{
+ register struct here *h, *hl;
+
+ hl = NULL;
+ for (h = acthere; h != NULL; h = h->h_next)
+ if (getarea((char *) h) >= area) {
+ if (h->h_iop->io_name != NULL)
+ unlink(h->h_iop->io_name);
+ if (hl == NULL)
+ acthere = h->h_next;
+ else
+ hl->h_next = h->h_next;
+ } else
+ hl = h;
+}
+
+void
+tempname(tname)
+char *tname;
+{
+ static int inc;
+ register char *cp, *lp;
+
+ for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)
+ ;
+ lp = putn(getpid()*1000 + inc++);
+ for (; (*cp = *lp++) != '\0'; cp++)
+ ;
+}
diff --git a/release/picobsd/tinyware/msh/sh6.c b/release/picobsd/tinyware/msh/sh6.c
new file mode 100644
index 0000000..bd3ba05
--- /dev/null
+++ b/release/picobsd/tinyware/msh/sh6.c
@@ -0,0 +1,9 @@
+#define Extern
+
+#include <sys/types.h>
+#include <signal.h>
+#define _NSIG NSIG
+#include <errno.h>
+#include <setjmp.h>
+#include "sh.h"
+
diff --git a/release/picobsd/tinyware/ns/Makefile b/release/picobsd/tinyware/ns/Makefile
new file mode 100644
index 0000000..bf8a270
--- /dev/null
+++ b/release/picobsd/tinyware/ns/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG= ns
+SRCS= ns.c
+
+CFLAGS+= -DBRIDGING
+MAN=
+
+.include <bsd.prog.mk>
diff --git a/release/picobsd/tinyware/ns/README b/release/picobsd/tinyware/ns/README
new file mode 100644
index 0000000..8d5f503
--- /dev/null
+++ b/release/picobsd/tinyware/ns/README
@@ -0,0 +1,43 @@
+Warsaw, 1998.07.20
+
+ Small replacement for netstat
+ -----------------------------
+
+This program implements some basic functionality subset of normal netstat -
+it can display the routing table and protocol statistics.
+
+Large part of the code dealing with retrieving the routing table via sysctl(3)
+was taken from code examples written by Richard Stevens to accompany his
+excellent book.
+
+Usage
+-----
+
+ ns [-rsi] [-p proto] [-w wait]
+
+where
+
+ -r print routing table (default)
+ -s print protocol statistics
+ -i print interface statistics
+ -p proto display only statistics related to this
+ protocol, where 'proto' is one of:
+ - ip
+ - tcp
+ - udp
+ - icmp
+ - bdg - bridging stats, if 'ns' was compiled with
+ bridging support (flag BRIDGING in Makefile)
+ -w wait continuous display, repeat every 'wait' seconds.
+
+Bugs
+----
+
+* 'ns' doesn't resolve IP addresses to names
+* well, real netstat provides _much_ more information... but this one needs
+ to be small, right? :-)
+
+Andrzej Bialecki
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/ns/ns.c b/release/picobsd/tinyware/ns/ns.c
new file mode 100644
index 0000000..a4b3b5e
--- /dev/null
+++ b/release/picobsd/tinyware/ns/ns.c
@@ -0,0 +1,831 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+
+/*
+ * Small replacement for netstat. Uses only sysctl(3) to get the info.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp_var.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <arpa/inet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <osreldate.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+char *progname;
+int iflag = 0;
+int lflag = 0; /* print cpu load info */
+int rflag = 0;
+int sflag = 0;
+int pflag = 0;
+int wflag = 0; /* repeat every wait seconds */
+int delta = 0 ;
+
+extern char *optarg;
+extern int optind;
+
+void print_load_stats(void);
+
+void
+usage()
+{
+ fprintf(stderr, "\n%s [-nrsil] [-p proto] [-w wait]\n", progname);
+ fprintf(stderr, " proto: {ip|tcp|udp|icmp}\n\n");
+}
+
+
+/*
+ * The following parts related to retrieving the routing table and
+ * interface information, were borrowed from R. Stevens' code examples
+ * accompanying his excellent book. Thanks!
+ */
+char *
+sock_ntop(const struct sockaddr *sa, size_t salen)
+{
+ char portstr[7];
+ static char str[128]; /* Unix domain is largest */
+
+ switch (sa->sa_family) {
+ case 255: {
+ int i = 0;
+ u_long mask;
+ u_int index = 1 << 31;
+ u_short new_mask = 0;
+
+ mask = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
+
+ while (mask & index) {
+ new_mask++;
+ index >>= 1;
+ }
+ sprintf(str, "/%hu", new_mask);
+ return (str);
+ }
+ case AF_UNSPEC:
+ case AF_INET: {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str))
+ == NULL)
+ return (NULL);
+ if (ntohs(sin->sin_port) != 0) {
+ snprintf(portstr, sizeof(portstr), ".%d",
+ ntohs(sin->sin_port));
+ strcat(str, portstr);
+ }
+ if (strcmp(str, "0.0.0.0") == 0)
+ sprintf(str, "default");
+ return (str);
+ }
+
+ case AF_UNIX: {
+ struct sockaddr_un *unp = (struct sockaddr_un *)sa;
+
+ /*
+ * OK to have no pathname bound to the socket:
+ * happens on every connect() unless client calls
+ * bind() first.
+ */
+ if (unp->sun_path[0] == 0)
+ strcpy(str, "(no pathname bound)");
+ else
+ snprintf(str, sizeof(str), "%s", unp->sun_path);
+ return (str);
+ }
+
+ case AF_LINK: {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
+
+ if (sdl->sdl_nlen > 0) {
+ bcopy(&sdl->sdl_data[0], str, sdl->sdl_nlen);
+ str[sdl->sdl_nlen] = '\0';
+ } else
+ snprintf(str, sizeof(str), "link#%d", sdl->sdl_index);
+ return (str);
+ }
+
+ default:
+ snprintf(str, sizeof(str),
+ "sock_ntop: unknown AF_xxx: %d, len %d", sa->sa_family,
+ salen);
+ return (str);
+ }
+ return (NULL);
+}
+
+char *
+Sock_ntop(const struct sockaddr *sa, size_t salen)
+{
+ char *ptr;
+
+ if ((ptr = sock_ntop(sa, salen)) == NULL)
+ err(1, "sock_ntop error"); /* inet_ntop() sets errno */
+ return (ptr);
+}
+
+
+#define ROUNDUP(a,size) (((a) & ((size)-1))?(1+((a)|((size)-1))):(a))
+
+#define NEXT_SA(ap) \
+ ap=(struct sockaddr *) \
+ ((caddr_t)ap+(ap->sa_len?ROUNDUP(ap->sa_len,sizeof(u_long)):\
+ sizeof(u_long)))
+
+void
+get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
+{
+ int i;
+
+ for (i = 0; i < RTAX_MAX; i++) {
+ if (addrs & (1 << i)) {
+ rti_info[i] = sa;
+ NEXT_SA(sa);
+ } else
+ rti_info[i] = NULL;
+ }
+}
+
+void
+get_flags(char *buf, int flags)
+{
+ if (flags & 0x1)
+ strcat(buf, "U");
+ if (flags & 0x2)
+ strcat(buf, "G");
+ if (flags & 0x4)
+ strcat(buf, "H");
+ if (flags & 0x8)
+ strcat(buf, "r");
+ if (flags & 0x10)
+ strcat(buf, "d");
+#ifdef NEVER
+ if (flags & 0x20)
+ strcat(buf, "mod,");
+#endif /*NEVER*/
+ if (flags & 0x100)
+ strcat(buf, "C");
+ if (flags & 0x400)
+ strcat(buf, "L");
+ if (flags & 0x800)
+ strcat(buf, "S");
+ if (flags & 0x10000)
+ strcat(buf, "c");
+ if (flags & 0x20000)
+ strcat(buf, "W");
+#ifdef NEVER
+ if (flags & 0x200000)
+ strcat(buf, ",LOC");
+#endif /*NEVER*/
+ if (flags & 0x400000)
+ strcat(buf, "b");
+#ifdef NEVER
+ if (flags & 0x800000)
+ strcat(buf, ",MCA");
+#endif /*NEVER*/
+}
+
+void
+print_routing(char *proto)
+{
+ int mib[6];
+ int i = 0;
+ int rt_len;
+ int if_len;
+ int if_num;
+ char *rt_buf;
+ char *if_buf;
+ char *next;
+ char *lim;
+ struct rt_msghdr *rtm;
+ struct if_msghdr *ifm;
+ struct if_msghdr **ifm_table;
+ struct ifa_msghdr *ifam;
+ struct sockaddr *sa;
+ struct sockaddr *sa1;
+ struct sockaddr *rti_info[RTAX_MAX];
+ struct sockaddr **if_table;
+ struct rt_metrics rm;
+ char fbuf[50];
+
+ /* keep a copy of statistics here for future use */
+ static unsigned *base_stats = NULL ;
+ static unsigned base_len = 0 ;
+
+ /* Get the routing table */
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = 0;
+ mib[4] = NET_RT_DUMP;
+ mib[5] = 0;
+
+ /*Estimate the size of table */
+ if (sysctl(mib, 6, NULL, &rt_len, NULL, 0) == -1) {
+ perror("sysctl size");
+ exit(-1);
+ }
+ if ((rt_buf = (char *)malloc(rt_len)) == NULL) {
+ perror("malloc");
+ exit(-1);
+ }
+
+ /* Now get it. */
+ if (sysctl(mib, 6, rt_buf, &rt_len, NULL, 0) == -1) {
+ perror("sysctl get");
+ exit(-1);
+ }
+
+ /* Get the interfaces table */
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = 0;
+ mib[4] = NET_RT_IFLIST;
+ mib[5] = 0;
+
+ /* Estimate the size of table */
+ if (sysctl(mib, 6, NULL, &if_len, NULL, 0) == -1) {
+ perror("sysctl size");
+ exit(-1);
+ }
+ if ((if_buf = (char *)malloc(if_len)) == NULL) {
+ perror("malloc");
+ exit(-1);
+ }
+
+ /* Now get it. */
+ if (sysctl(mib, 6, if_buf, &if_len, NULL, 0) == -1) {
+ perror("sysctl get");
+ exit(-1);
+ }
+ lim = if_buf + if_len;
+ i = 0;
+ for (next = if_buf, i = 0; next < lim; next += ifm->ifm_msglen) {
+ ifm = (struct if_msghdr *)next;
+ i++;
+ }
+ if_num = i;
+ if_table = (struct sockaddr **)calloc(i, sizeof(struct sockaddr));
+ ifm_table = (struct if_msghdr **)calloc(i, sizeof(struct if_msghdr));
+ if (iflag) {
+ printf("\nInterface table:\n");
+ printf("----------------\n");
+ printf("Name Mtu Network Address "
+ "Ipkts Ierrs Opkts Oerrs Coll\n");
+ }
+ /* scan the list and store base values */
+ i = 0 ;
+ for (next = if_buf; next < lim; next += ifm->ifm_msglen) {
+ ifm = (struct if_msghdr *)next;
+ i++ ;
+ }
+ if (base_stats == NULL || i != base_len) {
+ base_stats = calloc(i*5, sizeof(unsigned));
+ base_len = i ;
+ }
+ i = 0;
+ for (next = if_buf; next < lim; next += ifm->ifm_msglen) {
+ ifm = (struct if_msghdr *)next;
+ if_table[i] = (struct sockaddr *)(ifm + 1);
+ ifm_table[i] = ifm;
+
+ sa = if_table[i];
+ if (iflag && sa->sa_family == AF_LINK) {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
+ unsigned *bp = &base_stats[i*5];
+
+ printf("%-4s %-5d <Link> ",
+ sock_ntop(if_table[i], if_table[i]->sa_len),
+ ifm->ifm_data.ifi_mtu);
+ if (sdl->sdl_alen == 6) {
+ unsigned char *p =
+ sdl->sdl_data + sdl->sdl_nlen;
+ printf("%02x:%02x:%02x:%02x:%02x:%02x ",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+ } else
+ printf(" ");
+ printf("%9d%6d%9d%6d%6d\n",
+ ifm->ifm_data.ifi_ipackets - bp[0],
+ ifm->ifm_data.ifi_ierrors - bp[1],
+ ifm->ifm_data.ifi_opackets - bp[2],
+ ifm->ifm_data.ifi_oerrors - bp[3],
+ ifm->ifm_data.ifi_collisions -bp[4]);
+ if (delta > 0) {
+ bp[0] = ifm->ifm_data.ifi_ipackets ;
+ bp[1] = ifm->ifm_data.ifi_ierrors ;
+ bp[2] = ifm->ifm_data.ifi_opackets ;
+ bp[3] = ifm->ifm_data.ifi_oerrors ;
+ bp[4] = ifm->ifm_data.ifi_collisions ;
+ }
+ }
+ i++;
+ }
+ if (!rflag) {
+ free(rt_buf);
+ free(if_buf);
+ free(if_table);
+ free(ifm_table);
+ return;
+ }
+
+ /* Now dump the routing table */
+ printf("\nRouting table:\n");
+ printf("--------------\n");
+ printf
+ ("Destination Gateway Flags Netif Use\n");
+ lim = rt_buf + rt_len;
+ for (next = rt_buf; next < lim; next += rtm->rtm_msglen) {
+ rtm = (struct rt_msghdr *)next;
+ sa = (struct sockaddr *)(rtm + 1);
+ get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+ if ((sa = rti_info[RTAX_DST]) != NULL) {
+ sprintf(fbuf, "%s", sock_ntop(sa, sa->sa_len));
+ if (((sa1 = rti_info[RTAX_NETMASK]) != NULL)
+ && sa1->sa_family == 255) {
+ strcat(fbuf, sock_ntop(sa1, sa1->sa_len));
+ }
+ printf("%-19s", fbuf);
+ }
+ if ((sa = rti_info[RTAX_GATEWAY]) != NULL) {
+ printf("%-19s", sock_ntop(sa, sa->sa_len));
+ }
+ memset(fbuf, 0, sizeof(fbuf));
+ get_flags(fbuf, rtm->rtm_flags);
+ printf("%-10s", fbuf);
+ for (i = 0; i < if_num; i++) {
+ ifm = ifm_table[i];
+ if ((ifm->ifm_index == rtm->rtm_index) &&
+ (ifm->ifm_data.ifi_type > 0)) {
+ sa = if_table[i];
+ break;
+ }
+ }
+ if (ifm->ifm_type == RTM_IFINFO) {
+ get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
+ printf(" %s", Sock_ntop(sa, sa->sa_len));
+ } else if (ifm->ifm_type == RTM_NEWADDR) {
+ ifam =
+ (struct ifa_msghdr *)ifm_table[rtm->rtm_index - 1];
+ sa = (struct sockaddr *)(ifam + 1);
+ get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
+ printf(" %s", Sock_ntop(sa, sa->sa_len));
+ }
+ /* printf(" %u", rtm->rtm_use); */
+ printf("\n");
+ }
+ free(rt_buf);
+ free(if_buf);
+ free(if_table);
+ free(ifm_table);
+}
+
+void
+print_ip_stats(void)
+{
+ int mib[4];
+ int len;
+ struct ipstat s;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_INET;
+ mib[2] = IPPROTO_IP;
+#ifndef IPCTL_STATS
+ printf("sorry, ip stats not available\n");
+ return -1;
+#else
+ mib[3] = IPCTL_STATS;
+ len = sizeof(struct ipstat);
+ if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
+ perror("sysctl");
+ return;
+ }
+ printf("\nIP statistics:\n");
+ printf("--------------\n");
+ printf(" %10lu total packets received\n", s.ips_total);
+ printf("* Packets ok:\n");
+ printf(" %10lu fragments received\n", s.ips_fragments);
+ printf(" %10lu forwarded\n", s.ips_forward);
+#if __FreeBSD_version > 300001
+ printf(" %10lu fast forwarded\n", s.ips_fastforward);
+#endif
+ printf(" %10lu forwarded on same net (redirect)\n",
+ s.ips_redirectsent);
+ printf(" %10lu delivered to upper level\n", s.ips_delivered);
+ printf(" %10lu total ip packets generated here\n", s.ips_localout);
+ printf(" %10lu total packets reassembled ok\n", s.ips_reassembled);
+ printf(" %10lu total datagrams successfully fragmented\n",
+ s.ips_fragmented);
+ printf(" %10lu output fragments created\n", s.ips_ofragments);
+ printf(" %10lu total raw IP packets generated\n", s.ips_rawout);
+ printf("\n* Bad packets:\n");
+ printf(" %10lu bad checksum\n", s.ips_badsum);
+ printf(" %10lu too short\n", s.ips_tooshort);
+ printf(" %10lu not enough data (too small)\n", s.ips_toosmall);
+ printf(" %10lu more data than declared in header\n", s.ips_badhlen);
+ printf(" %10lu less data than declared in header\n", s.ips_badlen);
+ printf(" %10lu fragments dropped (dups, no mbuf)\n",
+ s.ips_fragdropped);
+ printf(" %10lu fragments timed out in reassembly\n",
+ s.ips_fragtimeout);
+ printf(" %10lu received for unreachable dest.\n", s.ips_cantforward);
+ printf(" %10lu unknown or unsupported protocol\n", s.ips_noproto);
+ printf(" %10lu lost due to no bufs etc.\n", s.ips_odropped);
+ printf(" %10lu couldn't fragment (DF set, etc.)\n", s.ips_cantfrag);
+ printf(" %10lu error in IP options processing\n", s.ips_badoptions);
+ printf(" %10lu dropped due to no route\n", s.ips_noroute);
+ printf(" %10lu bad IP version\n", s.ips_badvers);
+ printf(" %10lu too long (more than max IP size)\n", s.ips_toolong);
+#if __FreeBSD_version > 300001
+ printf(" %10lu multicast for unregistered groups\n", s.ips_notmember);
+#endif
+#endif
+}
+
+void
+print_tcp_stats(void)
+{
+ int mib[4];
+ int len;
+ struct tcpstat s;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_INET;
+ mib[2] = IPPROTO_TCP;
+#ifndef TCPCTL_STATS
+ printf("sorry, tcp stats not available\n");
+ return;
+#else
+ mib[3] = TCPCTL_STATS;
+ len = sizeof(struct tcpstat);
+ if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
+ perror("sysctl");
+ return;
+ }
+ printf("\nTCP statistics:\n");
+ printf("---------------\n");
+ printf("* Connections:\n");
+ printf(" %10lu initiated\n", s.tcps_connattempt);
+ printf(" %10lu accepted\n", s.tcps_accepts);
+ printf(" %10lu established\n", s.tcps_connects);
+ printf(" %10lu dropped\n", s.tcps_drops);
+ printf(" %10lu embryonic connections dropped\n", s.tcps_conndrops);
+ printf(" %10lu closed (includes dropped)\n", s.tcps_closed);
+ printf(" %10lu segments where we tried to get RTT\n",
+ s.tcps_segstimed);
+ printf(" %10lu times RTT successfully updated\n", s.tcps_rttupdated);
+ printf(" %10lu delayed ACKs sent\n", s.tcps_delack);
+ printf(" %10lu dropped in rxmt timeout\n", s.tcps_timeoutdrop);
+ printf(" %10lu retrasmit timeouts\n", s.tcps_rexmttimeo);
+ printf(" %10lu persist timeouts\n", s.tcps_persisttimeo);
+ printf(" %10lu keepalive timeouts\n", s.tcps_keeptimeo);
+ printf(" %10lu keepalive probes sent\n", s.tcps_keepprobe);
+ printf(" %10lu dropped in keepalive\n", s.tcps_keepdrops);
+
+ printf("* Packets sent:\n");
+ printf(" %10lu total packets sent\n", s.tcps_sndtotal);
+ printf(" %10lu data packets sent\n", s.tcps_sndpack);
+ printf(" %10lu data bytes sent\n", s.tcps_sndbyte);
+ printf(" %10lu data packets retransmitted\n", s.tcps_sndrexmitpack);
+ printf(" %10lu data bytes retransmitted\n", s.tcps_sndrexmitbyte);
+ printf(" %10lu ACK-only packets sent\n", s.tcps_sndacks);
+ printf(" %10lu window probes sent\n", s.tcps_sndprobe);
+ printf(" %10lu URG-only packets sent\n", s.tcps_sndurg);
+ printf(" %10lu window update-only packets sent\n", s.tcps_sndwinup);
+ printf(" %10lu control (SYN,FIN,RST) packets sent\n", s.tcps_sndctrl);
+ printf("* Packets received:\n");
+ printf(" %10lu total packets received\n", s.tcps_rcvtotal);
+ printf(" %10lu packets in sequence\n", s.tcps_rcvpack);
+ printf(" %10lu bytes in sequence\n", s.tcps_rcvbyte);
+ printf(" %10lu packets with bad checksum\n", s.tcps_rcvbadsum);
+ printf(" %10lu packets with bad offset\n", s.tcps_rcvbadoff);
+ printf(" %10lu packets too short\n", s.tcps_rcvshort);
+ printf(" %10lu duplicate-only packets\n", s.tcps_rcvduppack);
+ printf(" %10lu duplicate-only bytes\n", s.tcps_rcvdupbyte);
+ printf(" %10lu packets with some duplicate data\n",
+ s.tcps_rcvpartduppack);
+ printf(" %10lu duplicate bytes in partially dup. packets\n",
+ s.tcps_rcvpartdupbyte);
+ printf(" %10lu out-of-order packets\n", s.tcps_rcvoopack);
+ printf(" %10lu out-of-order bytes\n", s.tcps_rcvoobyte);
+ printf(" %10lu packets with data after window\n",
+ s.tcps_rcvpackafterwin);
+ printf(" %10lu bytes received after window\n",
+ s.tcps_rcvbyteafterwin);
+ printf(" %10lu packets received after 'close'\n",
+ s.tcps_rcvafterclose);
+ printf(" %10lu window probe packets\n", s.tcps_rcvwinprobe);
+ printf(" %10lu duplicate ACKs\n", s.tcps_rcvdupack);
+ printf(" %10lu ACKs for unsent data\n", s.tcps_rcvacktoomuch);
+ printf(" %10lu ACK packets\n", s.tcps_rcvackpack);
+ printf(" %10lu bytes ACKed by received ACKs\n", s.tcps_rcvackbyte);
+ printf(" %10lu window update packets\n", s.tcps_rcvwinupd);
+ printf(" %10lu segments dropped due to PAWS\n", s.tcps_pawsdrop);
+ printf(" %10lu times header predict ok for ACKs\n", s.tcps_predack);
+ printf(" %10lu times header predict ok for data packets\n",
+ s.tcps_preddat);
+ printf(" %10lu PCB cache misses\n", s.tcps_pcbcachemiss);
+ printf(" %10lu times cached RTT in route updated\n",
+ s.tcps_cachedrtt);
+ printf(" %10lu times cached RTTVAR updated\n", s.tcps_cachedrttvar);
+ printf(" %10lu times ssthresh updated\n", s.tcps_cachedssthresh);
+ printf(" %10lu times RTT initialized from route\n", s.tcps_usedrtt);
+ printf(" %10lu times RTTVAR initialized from route\n",
+ s.tcps_usedrttvar);
+ printf(" %10lu times ssthresh initialized from route\n",
+ s.tcps_usedssthresh);
+ printf(" %10lu timeout in persist state\n", s.tcps_persistdrop);
+ printf(" %10lu bogus SYN, e.g. premature ACK\n", s.tcps_badsyn);
+ printf(" %10lu resends due to MTU discovery\n", s.tcps_mturesent);
+ printf(" %10lu listen queue overflows\n", s.tcps_listendrop);
+#endif
+}
+
+void
+print_udp_stats(void)
+{
+ int mib[4];
+ int len;
+ struct udpstat s;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_INET;
+ mib[2] = IPPROTO_UDP;
+ mib[3] = UDPCTL_STATS;
+ len = sizeof(struct udpstat);
+ if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
+ perror("sysctl");
+ return;
+ }
+ printf("\nUDP statistics:\n");
+ printf("---------------\n");
+ printf("* Packets received:\n");
+ printf(" %10lu total input packets\n", s.udps_ipackets);
+ printf(" %10lu packets shorter than header (dropped)\n",
+ s.udps_hdrops);
+ printf(" %10lu bad checksum\n", s.udps_badsum);
+ printf(" %10lu data length larger than packet\n", s.udps_badlen);
+ printf(" %10lu no socket on specified port\n", s.udps_noport);
+ printf(" %10lu of above, arrived as broadcast\n", s.udps_noportbcast);
+ printf(" %10lu not delivered, input socket full\n", s.udps_fullsock);
+ printf(" %10lu packets missing PCB cache\n", s.udpps_pcbcachemiss);
+ printf(" %10lu packets not for hashed PCBs\n", s.udpps_pcbhashmiss);
+ printf("* Packets sent:\n");
+ printf(" %10lu total output packets\n", s.udps_opackets);
+#if __FreeBSD_version > 300001
+ printf(" %10lu output packets on fast path\n", s.udps_fastout);
+#endif
+}
+
+char *icmp_names[] = {
+ "echo reply",
+ "#1",
+ "#2",
+ "destination unreachable",
+ "source quench",
+ "routing redirect",
+ "#6",
+ "#7",
+ "echo",
+ "router advertisement",
+ "router solicitation",
+ "time exceeded",
+ "parameter problem",
+ "time stamp",
+ "time stamp reply",
+ "information request",
+ "information request reply",
+ "address mask request",
+ "address mask reply",
+};
+
+print_icmp_stats()
+{
+ int mib[4];
+ int len;
+ int i;
+ struct icmpstat s;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_INET;
+ mib[2] = IPPROTO_ICMP;
+ mib[3] = ICMPCTL_STATS;
+ len = sizeof(struct icmpstat);
+ if (sysctl(mib, 4, &s, &len, NULL, 0) < 0) {
+ perror("sysctl");
+ return (-1);
+ }
+ printf("\nICMP statistics:\n");
+ printf("----------------\n");
+ printf("* Output histogram:\n");
+ for (i = 0; i < (ICMP_MAXTYPE + 1); i++) {
+ if (s.icps_outhist[i] > 0)
+ printf("\t%10lu %s\n",
+ s.icps_outhist[i], icmp_names[i]);
+ }
+ printf("* Input histogram:\n");
+ for (i = 0; i < (ICMP_MAXTYPE + 1); i++) {
+ if (s.icps_inhist[i] > 0)
+ printf("\t%10lu %s\n",
+ s.icps_inhist[i], icmp_names[i]);
+ }
+ printf("* Other stats:\n");
+ printf(" %10lu calls to icmp_error\n", s.icps_error);
+ printf(" %10lu no error 'cuz old ip too short\n", s.icps_oldshort);
+ printf(" %10lu no error 'cuz old was icmp\n", s.icps_oldicmp);
+
+ printf(" %10lu icmp code out of range\n", s.icps_badcode);
+ printf(" %10lu packets shorter than min length\n", s.icps_tooshort);
+ printf(" %10lu bad checksum\n", s.icps_checksum);
+ printf(" %10lu calculated bound mismatch\n", s.icps_badlen);
+ printf(" %10lu number of responses\n", s.icps_reflect);
+ printf(" %10lu broad/multi-cast echo requests dropped\n",
+ s.icps_bmcastecho);
+ printf(" %10lu broad/multi-cast timestamp requests dropped\n",
+ s.icps_bmcasttstamp);
+}
+
+int
+stats(char *proto)
+{
+ if (!sflag)
+ return 0;
+ if (pflag) {
+ if (proto == NULL) {
+ fprintf(stderr, "Option '-p' requires paramter.\n");
+ usage();
+ exit(-1);
+ }
+ if (strcmp(proto, "ip") == 0)
+ print_ip_stats();
+ if (strcmp(proto, "icmp") == 0)
+ print_icmp_stats();
+ if (strcmp(proto, "udp") == 0)
+ print_udp_stats();
+ if (strcmp(proto, "tcp") == 0)
+ print_tcp_stats();
+ return (0);
+ }
+ print_ip_stats();
+ print_icmp_stats();
+ print_udp_stats();
+ print_tcp_stats();
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c;
+ char *proto = NULL;
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "dilnrsp:w:")) != -1) {
+ switch (c) {
+ case 'd': /* print deltas in stats every w seconds */
+ delta++ ;
+ break;
+ case 'w':
+ wflag = atoi(optarg);
+ break;
+ case 'n': /* ignored, just for compatibility with std netstat */
+ break;
+ case 'r':
+ rflag++;
+ break;
+ case 'i':
+ iflag++;
+ break;
+ case 'l':
+ lflag++;
+ break;
+ case 's':
+ sflag++;
+ rflag = 0;
+ break;
+ case 'p':
+ pflag++;
+ sflag++;
+ proto = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ exit(0);
+ break;
+ }
+ }
+ if (rflag == 0 && sflag == 0 && iflag == 0)
+ rflag = 1;
+ argc -= optind;
+
+ if (argc > 0) {
+ usage();
+ exit(-1);
+ }
+ if (wflag)
+ printf("\033[H\033[J");
+again:
+ if (wflag) {
+ struct timeval t;
+
+ gettimeofday(&t, NULL);
+ printf("\033[H%s", ctime(&t.tv_sec));
+ }
+ print_routing(proto);
+ print_load_stats();
+ stats(proto);
+ if (wflag) {
+ sleep(wflag);
+ goto again;
+ }
+ exit(0);
+}
+
+void
+print_load_stats(void)
+{
+ static u_int32_t cp_time[5];
+ u_int32_t new_cp_time[5];
+ int l;
+ int shz;
+ static int stathz ;
+
+ if (!lflag || !wflag)
+ return;
+ l = sizeof(new_cp_time) ;
+ bzero(new_cp_time, l);
+ if (sysctlbyname("kern.cp_time", new_cp_time, &l, NULL, 0) < 0) {
+ warn("sysctl: retrieving cp_time length");
+ return;
+ }
+ if (stathz == 0) {
+ struct clockinfo ci;
+
+ bzero (&ci, sizeof(ci));
+ l = sizeof(ci) ;
+ if (sysctlbyname("kern.clockrate", &ci, &l, NULL, 0) < 0) {
+ warn("sysctl: retrieving clockinfo length");
+ return;
+ }
+ stathz = ci.stathz ;
+ bcopy(new_cp_time, cp_time, sizeof(cp_time));
+ }
+ shz = stathz * wflag ;
+ if (shz == 0)
+ shz = 1;
+#define X(i) ( (double)(new_cp_time[i] - cp_time[i])*100/shz )
+ printf("\nUSER %5.2f%% NICE %5.2f%% SYS %5.2f%% "
+ "INTR %5.2f%% IDLE %5.2f%%\n",
+ X(0), X(1), X(2), X(3), X(4) );
+ bcopy(new_cp_time, cp_time, sizeof(cp_time));
+}
diff --git a/release/picobsd/tinyware/oinit/Makefile b/release/picobsd/tinyware/oinit/Makefile
new file mode 100644
index 0000000..072bbba
--- /dev/null
+++ b/release/picobsd/tinyware/oinit/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+#
+PROG= oinit
+
+SH_PATH?= /bin/sh
+SH_NAME?= -sh
+SH_ARG?= /etc/rc
+
+CFLAGS= -DSH_PATH=\"${SH_PATH}\" -DSH_NAME=\"${SH_NAME}\" \
+ -DSH_ARG=\"${SH_ARG}\"
+
+
+#CFLAGS+= -DUSE_HISTORY
+#CFLAGS+= -DOINIT_RC=\"/etc/oinit.rc\"
+
+#LDADD= -lutil -ledit -ltermcap
+LIBADD= util
+MAN=
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/oinit/README b/release/picobsd/tinyware/oinit/README
new file mode 100644
index 0000000..e34c404
--- /dev/null
+++ b/release/picobsd/tinyware/oinit/README
@@ -0,0 +1,123 @@
+Warsaw, 1998.07.07
+
+This README shortly describes the features of "oinit" - a very simplistic
+version of init(8) combined with a shell.
+
+Features
+--------
+
+* oinit is able to run system in multi- and single-user modes,
+* it can be started on system with DEVFS/SLICE (i.e. empty /dev),
+* provides minimalistic user interface, called "shell()",
+* it can run the system startup script (/etc/rc),
+* it can be compiled with -DOINIT_RC to use its own startup script
+ (*very* primitive, but doesn't require any real shell to run it!),
+* doesn't require the whole chain of init->getty->login->shell to be run,
+* it is extremely small, and is ideally suited for situations when
+ there is little memory.
+
+As an additional bonus you receive some obvious and some hidden bugs... :-))
+This code is at most alpha quality yet.
+
+
+How it works
+------------
+
+Unlike normal init(8), it forks itself on given number of vty's immediately
+providing shell() interface. Currently it doesn't require (and is unable to
+perform) any authentication, but this is easy to add if needed.
+
+Standard version of FreeBSD kernel looks for /sbin/init first, and then
+tries to execute it. If it fails, it tries to find:
+ /sbin/oinit
+ /sbin/init.bak
+ /stand/sysinstall
+
+So it is easy to make use of it even on standard system - just put it in
+/sbin/oinit and rename /sbin/init to something else, e.g. /sbin/init.bak.
+
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+!!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+Init (or oinit) plays crucial role in the system. If you plan to do any
+changes to your system's init, make sure you have a boot floppy with working
+version of statically compiled init(8) on it - you can very easily put your
+system in unusable state when fiddling with it.
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+Shell() interface
+-----------------
+
+It allows you to issue built-in and external commands. Built-in commands
+are listed below. For each command there is short help available, with
+example of usage.
+
+ cd change working directory
+ pwd print working directory
+ set set environment variable (no expansion)
+ unset unset environment variable
+ env print all environment variables
+ echo echo arguments on stdout
+ exit exit from shell (oinit will start a new one after some delay)
+ . source-in a file with commands
+ ? help
+
+Any other command is passed to execvp(3) as it is.
+
+EXCEPTION: if you end the command line with a '&', the command is started
+as daemon. This is NOT the same as in normal shell, where the '&' puts a
+process in background. Here the newly started process is totally dissociated
+from terminal.
+
+Prompt tells you:
+* your `pwd`
+* your PID
+* and that you are root ('#').
+
+WARNING: this pseudo-shell doesn't do any expansion whatsoever.
+
+To do list
+----------
+
+- oinit proper:
+ * fix signal handling and transitions,
+ * invent a one-file configuration database (combining as many files
+ from /etc as possible into one) able to properly handle inter-
+ dependencies in running various daemons,
+ * allow for interpreting of such database, and running various
+ programs ourselves (this would eventually allow to make /bin/sh
+ an option, not necessity),
+ * better hooks for incorporating other modules into oinit (see e.g.
+ the telnet() below),
+ * add optional authentication,
+
+- shell():
+ * more built-ins: perhaps 'kill' and 'ps',
+ * variable expansion,
+ * globbing,
+ * conditionals,
+ * history? (it depends on how much memory it needs).
+ * programmatic hooks for easy customisation of user interface (like
+ hierarchy of commands and contexts),
+ * ...
+
+- implement as a routine (like shell()) a small remote login daemon telnet(),
+ as a built-in module to oinit. It would implement the simplest options of
+ normal telnet, and would itself handle authentication, passing control to
+ shell() on success. The authentication routine would be the same as for
+ checking console access.
+
+And allow me for a moment of day-dreaming: I'd like to rewrite oinit one day
+to be a monolithic one-in-all application, non-forking but multithreaded... It
+would contain all the modules, such as shell(), telnet(), ifconfig() etc...
+started as threads, not separate processes.
+
+Credits
+-------
+
+The overall framework was taken from FreeBSD /sbin/init.
+
+Andrzej Bialecki
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/oinit/oinit.c b/release/picobsd/tinyware/oinit/oinit.c
new file mode 100644
index 0000000..7715f3e
--- /dev/null
+++ b/release/picobsd/tinyware/oinit/oinit.c
@@ -0,0 +1,947 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * A primitive version of init(8) with simplistic user interface
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/reboot.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <err.h>
+
+#ifdef USE_HISTORY
+#error "Not yet. But it's quite simple to add - patches are welcome!"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <paths.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <varargs.h>
+
+#define BUFSIZE 1024
+#define MAX_CONS 12
+
+#define NONE 0
+#define SINGLE 1
+#define MULTI 2
+#define DEATH 3
+
+#define FALSE 0
+#define TRUE 1
+
+char cwd[BUFSIZE];
+char vty[]="0123456789abcdef";
+char *progname;
+char *motd=NULL;
+int ncons=MAX_CONS;
+int Reboot=FALSE;
+int transition=MULTI;
+int prevtrans=SINGLE;
+jmp_buf machine;
+
+char *trans[]={ "NONE", "SINGLE", "MULTI", "DEATH" };
+
+extern char **environ;
+
+/* Struct for holding session state */
+struct sess {
+ char tty[16]; /* vty device path */
+ pid_t pid; /* pid of process running on it */
+ int (*func)(int argc, char **argv);
+ /* internal function to run on it (after forking) */
+} ttys[MAX_CONS];
+
+/* Struct for built-in command */
+struct command {
+ char *cmd; /* command name */
+ char *descr; /* command description */
+ char *usage; /* usage */
+ char *example; /* example of usage */
+ int (*func)(char *); /* callback function */
+};
+
+/* Prototypes */
+int cd(char *);
+int pwd(char *);
+int echo(char *);
+int xit(char *);
+int set(char *);
+int unset(char *);
+int env(char *);
+int help(char *);
+int sourcer(char *);
+void do_command(int shell, char *cmdline);
+void transition_handler(int);
+
+/* Table of built-in functions */
+struct command bltins[]={
+ {"cd","Change working directory","cd [dir]","cd /etc",cd},
+ {"pwd","Print current directory","pwd","pwd",pwd},
+ {"exit","Exit from shell()","exit","exit",xit},
+ {"set","Set environment variable","set [VAR=value]","set TERM=xterm",set},
+ {"unset","Unset environment variable","unset VAR","unset EDITOR",unset},
+ {"echo","Echo arguments on stdout","echo arg1 arg2 ...","echo Hello World!",echo},
+ {"env","Print all environment variables","env","env",env},
+ {".","Source-in a file with commands",". filename",". /etc/rc",sourcer},
+ {"?","Print this help :-)","? [command]","? set",help},
+ {NULL,NULL,NULL,NULL,NULL}
+};
+
+/*
+ * Built-in 'cd <path>' handler
+ */
+int
+cd(char *path)
+{
+ if(chdir(path)) return(-1);
+ getcwd(cwd,BUFSIZE);
+ return(0);
+}
+
+/*
+ * Built-in 'pwd' handler
+ */
+int
+pwd(char *dummy)
+{
+
+ if(getcwd(cwd,BUFSIZE)==NULL) return(-1);
+ printf("%s\n",cwd);
+ return(0);
+}
+
+/*
+ * Built-in 'exit' handler
+ */
+int
+xit(char *dummy)
+{
+ _exit(0);
+}
+
+/*
+ * Built-in 'echo' handler
+ */
+int
+echo(char *args)
+{
+ int i=0,j;
+ int len;
+ char c;
+ int s_quote=0,d_quote=0;
+ int sep=0,no_lf=0;
+
+ if(args==NULL) {
+ printf("\n");
+ return;
+ }
+ len=strlen(args);
+ if(len>=2) {
+ if(args[0]=='-' && args[1]=='n') {
+ no_lf++;
+ i=2;
+ while(i<len && (args[i]==' ' || args[i]=='\t')) i++;
+ }
+ }
+ while(i<len) {
+ c=args[i];
+ switch(c) {
+ case ' ':
+ case '\t':
+ if(s_quote||d_quote) {
+ putchar(c);
+ } else if(!sep) {
+ putchar(' ');
+ sep=1;
+ }
+ break;
+ case '\\':
+ i++;
+ c=args[i];
+ switch(c) {
+ case 'n':
+ putchar('\n');
+ break;
+ case 'b':
+ putchar('\b');
+ break;
+ case 't':
+ putchar('\t');
+ break;
+ case 'r':
+ putchar('\r');
+ break;
+ default:
+ putchar(c);
+ break;
+ }
+ break;
+ case '"':
+ if(!d_quote) {
+ d_quote=1;
+ for(j=i+1;j<len;j++) {
+ if(args[j]=='\\') {
+ j++;
+ continue;
+ }
+ if(args[j]=='"') {
+ d_quote=2;
+ break;
+ }
+ }
+ if(d_quote!=2) {
+ printf("\necho(): unmatched \"\n");
+ return;
+ }
+ } else d_quote=0;
+ break;
+ case '\'':
+ if(!s_quote) {
+ s_quote=1;
+ for(j=i+1;j<len;j++) {
+ if(args[j]=='\\') {
+ j++;
+ continue;
+ }
+ if(args[j]=='\'') {
+ s_quote=2;
+ break;
+ }
+ }
+ if(s_quote!=2) {
+ printf("\necho(): unmatched '\n");
+ return;
+ }
+ } else s_quote=0;
+ break;
+ case '`':
+ printf("echo(): backquote not implemented yet!\n");
+ break;
+ default:
+ sep=0;
+ putchar(c);
+ break;
+ }
+ i++;
+ }
+ if(!no_lf) putchar('\n');
+ fflush(stdout);
+}
+
+/*
+ * Built-in 'set VAR=value' handler
+ */
+int
+set(char *var)
+{
+ int res;
+
+ if(var==NULL) return(env(NULL));
+ res=putenv(var);
+ if(res) printf("set: %s\n",strerror(errno));
+ return(res);
+}
+
+/*
+ * Built-in 'env' handler
+ */
+int
+env(char *dummy)
+{
+ char **e;
+
+ e=environ;
+ while(*e!=NULL) {
+ printf("%s\n",*e++);
+ }
+ return(0);
+}
+
+/*
+ * Built-in 'unset VAR' handler
+ */
+int
+unset(char *var)
+{
+ if(var==NULL) {
+ printf("%s: parameter required.\n",progname);
+ return(-1);
+ }
+ return(unsetenv(var));
+}
+
+/*
+ * Built-in '?' handler
+ */
+int
+help(char *cmd)
+{
+ struct command *x;
+ int found=0;
+
+ if(cmd==NULL) {
+ printf("\nBuilt-in commands:\n");
+ printf("-------------------\n");
+ x=bltins;
+ while(x->cmd!=NULL) {
+ printf("%s\t%s\n",x->cmd,x->descr);
+ x++;
+ }
+ printf("\nEnter '? <cmd>' for details.\n\n");
+ return(0);
+ } else {
+ x=bltins;
+ while(x->cmd!=NULL) {
+ if(strcmp(x->cmd,cmd)==0) {
+ found++;
+ break;
+ }
+ x++;
+ }
+ if(found) {
+ printf("\n%s\t%s:\n",x->cmd,x->descr);
+ printf("\tUsage:\n\t\t%s\n",x->usage);
+ printf("\te.g:\n\t\t%s\n\n",x->example);
+ return(0);
+ } else {
+ printf("\n%s: no such command.\n\n",cmd);
+ return(-1);
+ }
+ }
+}
+
+/*
+ * Signal handler for shell()
+ */
+void
+shell_sig(int sig)
+{
+ switch(sig) {
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTERM:
+ /* ignore ? */
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * Built-in '.' handler (read-in and execute commands from file)
+ */
+int
+sourcer(char *fname)
+{
+ FILE *fd;
+ char buf[512],*tok,*arg,**av;
+ int ac,len,f,res,i;
+ pid_t pid;
+ char *sep=" \t";
+
+ fd=fopen(fname,"r");
+ if(fd==NULL) {
+ printf("Couldn't open file '%s'\n",fname);
+ return(-1);
+ }
+ while(!feof(fd)) {
+ memset(buf,0,512);
+ if(fgets(buf,512,fd)==NULL) continue;
+ if((*buf=='#') || (*buf=='\n')) continue;
+ len=strlen(buf);
+ buf[len-1]='\0';
+ if(strncmp(buf,"ncons",5)==0) {
+ tok=strtok(buf,sep);
+ tok=strtok(NULL,sep);
+ ncons=atoi(tok);
+ if((ncons<1)||(ncons>MAX_CONS)) {
+ syslog(LOG_EMERG,"%s: bad ncons value; defaulting to %d\n",fname,MAX_CONS);
+ ncons=MAX_CONS;
+ }
+ continue;
+ } else if(strncmp(buf,"motd",4)==0) {
+ tok=strtok(buf,sep);
+ motd=strdup(strtok(NULL,sep));
+ continue;
+ } else {
+ do_command(0,buf);
+ }
+ /* Next command, please. */
+ }
+ fclose(fd);
+ syslog(LOG_EMERG,"Done with %s",fname);
+}
+
+void
+do_command(int shell, char *cmdline)
+{
+ char *tok,*c,*sep=" \t";
+ char **av;
+ struct command *x;
+ int found,len;
+ int ac,i,f,res;
+ int bg=0;
+ pid_t pid;
+
+ len=strlen(cmdline);
+ if(cmdline[len-1]=='&') {
+ bg++;
+ cmdline[len-1]='\0';
+ len--;
+ } else bg=0;
+ tok=strtok(cmdline,sep);
+ x=bltins;
+ found=0;
+ while(x->cmd!=NULL) {
+ if(strcmp(x->cmd,tok)==0) {
+ found++;
+ break;
+ }
+ x++;
+ }
+ if(found) {
+ tok=cmdline+strlen(x->cmd)+1;
+ while(*tok && isblank(*tok) && (tok<(cmdline+len))) tok++;
+ if(*tok==NULL) tok=NULL;
+ x->func(tok);
+ return;
+ }
+ ac=0;
+ av=(char **)calloc(((len+1)/2+1),sizeof(char *));
+ av[ac++]=tok;
+ while((av[ac++]=strtok(NULL,sep))!=NULL)
+ continue;
+ switch((pid=fork())) {
+ case 0:
+ if(shell) {
+ signal(SIGINT,SIG_DFL);
+ signal(SIGQUIT,SIG_DFL);
+ signal(SIGTERM,SIG_DFL);
+ signal(SIGHUP,SIG_DFL);
+ } else {
+ close(0);
+ close(1);
+ close(2);
+ f=open(_PATH_CONSOLE,O_RDWR);
+ dup2(f,0);
+ dup2(f,1);
+ dup2(f,2);
+ if(f>2) close(f);
+ }
+ if(bg) {
+ if(daemon(0,0)) {
+ printf("do_command(%s): failed to run bg: %s\n",
+ av[0],strerror(errno));
+ _exit(100);
+ }
+ }
+ execvp(av[0],av);
+ /* Something went wrong... */
+ printf("do_command(%s): %s\n",av[0],strerror(errno));
+ _exit(100);
+ break;
+ case -1:
+ printf("do_command(): %s\n",strerror(errno));
+ break;
+ default:
+ while(waitpid(pid,&res,0)!=pid) continue;
+ if(WEXITSTATUS(res)) {
+ printf("do_command(%s): exit code=%d\n",
+ av[0],WEXITSTATUS(res));
+ }
+ break;
+ }
+ free(av);
+ return;
+}
+
+/*
+ * This is the user interface. This routine gets executed on each
+ * virtual console serviced by init.
+ *
+ * It works as normal shell does - for each external command it forks
+ * and execs, for each internal command just executes a function.
+ */
+
+int
+shell(int argc, char **argv)
+{
+ char buf[BUFSIZE];
+ char *prompt=" # ";
+ int fd;
+ int res;
+ pid_t mypid;
+
+ if(motd!=NULL) {
+ if((fd=open(motd,O_RDONLY))!=-1) {
+ do {
+ res=read(fd,buf,BUFSIZE);
+ res=write(1,buf,res);
+ } while(res>0);
+ close(fd);
+ }
+ }
+
+ printf("\n\n+=========================================================+\n");
+ printf("| Built-in shell() (enter '?' for short help on commands) |\n");
+ printf("+=========================================================+\n\n");
+ getcwd(cwd,BUFSIZE);
+ mypid=getpid();
+ signal(SIGINT,shell_sig);
+ signal(SIGQUIT,shell_sig);
+ signal(SIGTERM,shell_sig);
+ while(!feof(stdin)) {
+ memset(buf,0,BUFSIZE);
+ printf("(%d)%s%s",mypid,cwd,prompt);
+ fflush(stdout);
+ if(fgets(buf,BUFSIZE-1,stdin)==NULL) continue;
+ buf[strlen(buf)-1]='\0';
+ if(strlen(buf)==0) continue;
+ do_command(1,buf);
+ }
+ return(0);
+}
+
+/*
+ * Stub for executing some external program on a console. This is called
+ * from previously forked copy of our process, so that exec is ok.
+ */
+int
+external_cmd(int argc, char **argv)
+{
+ execvp(argv[0],argv);
+}
+
+/*
+ * Acquire vty and properly attach ourselves to it.
+ * Also, build basic environment for running user interface.
+ */
+
+int
+start_session(int vty, int argc, char **argv)
+{
+ int fd;
+ char *t;
+
+ close(0);
+ close(1);
+ close(2);
+ revoke(ttys[vty].tty);
+ fd=open(ttys[vty].tty,O_RDWR);
+ dup2(fd,0);
+ dup2(fd,1);
+ dup2(fd,2);
+ if(fd>2) close(fd);
+ login_tty(fd);
+ setpgid(0,getpid());
+ putenv("TERM=xterm");
+ putenv("HOME=/");
+ putenv("PATH=/stand:/bin:/usr/bin:/sbin:.");
+ signal(SIGHUP,SIG_DFL);
+ signal(SIGINT,SIG_DFL);
+ signal(SIGQUIT,SIG_DFL);
+ signal(SIGTERM,SIG_DFL);
+ chdir("/");
+ t=(char *)(rindex(ttys[vty].tty,'/')+1);
+ printf("\n\n\nStarting session on %s.\n",t);
+ ttys[vty].func(argc,argv);
+ _exit(0);
+}
+
+/*
+ * Execute system startup script /etc/rc
+ *
+ * (Of course if you don't like it - I don't - you can run anything you
+ * want here. Perhaps it would be useful just to read some config DB and
+ * do these things ourselves, avoiding forking lots of shells and scripts.)
+ */
+
+/* If OINIT_RC is defined, oinit will use it's own configuration file,
+ * /etc/oinit.rc. It's format is described below. Otherwise, it will use
+ * normal /etc/rc interpreted by Bourne shell.
+ */
+#ifndef OINIT_RC
+#ifndef SH_NAME
+#define SH_NAME "-sh"
+#endif
+#ifndef SH_PATH
+#define SH_PATH _PATH_BSHELL
+#endif
+#ifndef SH_ARG
+#define SH_ARG "/etc/rc"
+#endif
+void
+runcom()
+{
+ char *argv[3];
+ pid_t pid;
+ int st;
+ int fd;
+
+ if((pid=fork())==0) {
+ /* child */
+ close(0);
+ close(1);
+ close(2);
+ fd=open(_PATH_CONSOLE,O_RDWR);
+ dup2(fd,0);
+ dup2(fd,1);
+ dup2(fd,2);
+ if(fd>2) close(fd);
+ argv[0]=SH_NAME;
+ argv[1]=SH_ARG;
+ argv[2]=0;
+ execvp(SH_PATH,argv);
+ printf("runcom(): %s\n",strerror(errno));
+ _exit(1);
+ }
+ /* Wait for child to exit */
+ while(pid!=waitpid(pid,(int *)0,0)) continue;
+ return;
+}
+#else
+/* Alternative /etc/rc - default is /etc/oinit.rc. Its format is as follows:
+ * - each empty line or line beginning with a '#' is discarded
+ * - any other line must contain a keyword, or a (nonblocking) command to run.
+ *
+ * Thus far, the following keywords are defined:
+ * ncons <number> number of virtual consoles to open
+ * motd <pathname> full path to motd file
+ *
+ * Examples of commands to run:
+ *
+ * ifconfig lo0 inet 127.0.0.1 netmask 255.0.0.0
+ * ifconfig ed0 inet 148.81.168.10 netmask 255.255.255.0
+ * kbdcontrol -l /usr/share/syscons/my_map.kbd
+ */
+void
+runcom(char *fname)
+{
+ int fd;
+
+ close(0);
+ close(1);
+ close(2);
+ fd=open(_PATH_CONSOLE,O_RDWR);
+ dup2(fd,0);
+ dup2(fd,1);
+ dup2(fd,2);
+ if(fd>2) close(fd);
+ sourcer(fname);
+}
+#endif
+
+int
+run_multi()
+{
+ int i,j;
+ pid_t pid;
+ int found;
+
+ /* Run /etc/rc if not in single user */
+#ifndef OINIT_RC
+ if(prevtrans==SINGLE) runcom();
+#else
+ if(prevtrans==SINGLE) runcom(OINIT_RC);
+#endif
+ if(transition!=MULTI) return(-1);
+
+ syslog(LOG_EMERG,"*** Starting multi-user mode ***");
+
+ /* Fork shell interface for each console */
+ for(i=0;i<ncons;i++) {
+ if(ttys[i].pid==0) {
+ switch(pid=fork()) {
+ case 0:
+ start_session(i,0,NULL);
+ break;
+ case -1:
+ printf("%s: %s\n",progname,strerror(errno));
+ break;
+ default:
+ ttys[i].pid=pid;
+ break;
+ }
+ }
+ }
+ /* Initialize any other services we'll use - most probably this will
+ * be a 'telnet' service (some day...).
+ */
+ /* */
+
+ /* Emulate multi-user */
+ while(transition==MULTI) {
+ /* XXX Modify this to allow for checking for the input on
+ * XXX listening sockets, and forking a 'telnet' service.
+ */
+ /* */
+
+ /* Wait for any process to exit */
+ pid=waitpid(-1,(int *)0,0);
+ if(pid==-1) continue;
+ found=0;
+ j=-1;
+ /* search if it's one of our sessions */
+ for(i=0;i<ncons;i++) {
+ if(ttys[i].pid==pid) {
+ found++;
+ j=i;
+ ttys[j].pid=0;
+ break;
+ }
+ }
+ if(!found) {
+ /* Just collect the process's status */
+ continue;
+ } else {
+ /* restart shell() on a console, if it died */
+ if(transition!=MULTI) return(0);
+ switch(pid=fork()) {
+ case 0:
+ sleep(1);
+ start_session(j,0,NULL);
+ break;
+ case -1:
+ printf("%s: %s\n",progname,strerror(errno));
+ break;
+ default:
+ ttys[j].pid=pid;
+ break;
+ }
+ }
+ }
+}
+
+int clang;
+
+void
+kill_timer(int sig)
+{
+ clang=1;
+}
+
+kill_ttys()
+{
+}
+
+/*
+ * Start a shell on ttyv0 (i.e. the console).
+ */
+
+int
+run_single()
+{
+ int i;
+ pid_t pid,wpid;
+ static int sigs[2]={SIGTERM,SIGKILL};
+
+ syslog(LOG_EMERG,"*** Starting single-user mode ***");
+ /* Kill all existing sessions */
+ syslog(LOG_EMERG,"Killing all existing sessions...");
+ for(i=0;i<MAX_CONS;i++) {
+ kill(ttys[i].pid,SIGHUP);
+ ttys[i].pid=0;
+ }
+ for(i=0;i<2;i++) {
+ if(kill(-1,sigs[i])==-1 && errno==ESRCH) break;
+ clang=0;
+ alarm(10);
+ do {
+ pid=waitpid(-1,(int *)0,WUNTRACED);
+ if(errno==EINTR) continue;
+ else break;
+ } while (clang==0);
+ }
+ if(errno!=ECHILD) {
+ syslog(LOG_EMERG,"Some processes would not die; ps -axl advised");
+ }
+ /* Single-user */
+ switch(pid=fork()) {
+ case 0:
+ start_session(0,0,NULL);
+ break;
+ case -1:
+ printf("%s: %s\n",progname,strerror(errno));
+ printf("The system is seriously hosed. I'm dying...\n");
+ transition=DEATH;
+ return(-1);
+ break;
+ default:
+ do {
+ wpid=waitpid(pid,(int *)0,WUNTRACED);
+ } while(wpid!=pid && transition==SINGLE);
+ if(transition!=DEATH) {
+ prevtrans=transition;
+ transition=MULTI;
+ }
+ break;
+ }
+ return(0);
+}
+
+/*
+ * Transition handler - installed as signal handler.
+ */
+
+void
+transition_handler(int sig)
+{
+
+ switch(sig) {
+ case SIGHUP:
+ case SIGTERM:
+ prevtrans=transition;
+ transition=SINGLE;
+ syslog(LOG_EMERG,"*** Going from %s -> %s\n",trans[prevtrans],trans[transition]);
+ if(prevtrans!=transition) longjmp(machine,sig);
+ break;
+ case SIGINT:
+ case SIGQUIT:
+ prevtrans=transition;
+ transition=DEATH;
+ syslog(LOG_EMERG,"*** Going from %s -> %s\n",trans[prevtrans],trans[transition]);
+ if(prevtrans!=transition) longjmp(machine,sig);
+ break;
+ default:
+ syslog(LOG_EMERG,"pid=%d sig=%s (ignored)\n",getpid(),sys_siglist[sig]);
+ break;
+ }
+}
+
+/*
+ * Change system state appropriately to the signals
+ */
+
+int
+transition_machine()
+{
+ int i;
+
+ while(transition!=DEATH) {
+ switch(transition) {
+ case MULTI:
+ run_multi();
+ break;
+ case SINGLE:
+ run_single();
+ break;
+ }
+ }
+ syslog(LOG_EMERG,"Killing all existing sessions...");
+ /* Kill all sessions */
+ kill(-1,SIGKILL);
+ /* Be nice and wait for them */
+ while(waitpid(-1,(int *)0,WNOHANG|WUNTRACED)>0) continue;
+ unmount("/",0);
+ reboot(RB_AUTOBOOT);
+ /* NOTREACHED */
+}
+
+int
+main(int argc, char **argv)
+{
+ int devfs=0,c,i;
+
+ /* These are copied from real init(8) */
+ if(getuid()!=0)
+ errx(1,"%s",strerror(EPERM));
+ openlog("init",LOG_CONS|LOG_ODELAY,LOG_AUTH);
+ if(setsid()<0)
+ warn("initial setsid() failed");
+ if(setlogin("root")<0)
+ warn("setlogin() failed");
+
+ close(0);
+ close(1);
+ close(2);
+ chdir("/");
+
+ progname=rindex(argv[0],'/');
+ if(progname==NULL) {
+ progname=argv[0];
+ } else progname++;
+
+ transition=MULTI;
+
+ /* We must recognize the same options as real init does */
+ while((c=getopt(argc,argv,"dsf"))!=-1) {
+ switch(c) {
+ case 'd':
+ devfs=1;
+ break;
+ case 's':
+ transition=SINGLE;
+ break;
+ case 'f':
+ break;
+ default:
+ printf("%s: unrecognized flag '-%c'\n",progname,c);
+ break;
+ }
+ }
+ if(devfs)
+ mount("devfs",_PATH_DEV,MNT_NOEXEC|MNT_RDONLY,0);
+
+ /* Fill in the sess structures. */
+ /* XXX Really, should be filled based upon config file. */
+ for(i=0;i<MAX_CONS;i++) {
+ if(i==0) {
+ sprintf(ttys[i].tty,_PATH_CONSOLE);
+ } else {
+ sprintf(ttys[i].tty,"%sv%c",_PATH_TTY,vty[i]);
+ }
+ ttys[i].pid=0;
+ ttys[i].func=shell;
+ }
+
+ getcwd(cwd,BUFSIZE);
+
+ signal(SIGINT,transition_handler);
+ signal(SIGQUIT,transition_handler);
+ signal(SIGTERM,transition_handler);
+ signal(SIGHUP,transition_handler);
+ signal(SIGALRM,kill_timer);
+
+ setjmp(machine);
+ transition_machine(transition);
+ /* NOTREACHED */
+ exit(100);
+}
diff --git a/release/picobsd/tinyware/passwd/Makefile b/release/picobsd/tinyware/passwd/Makefile
new file mode 100644
index 0000000..806836c
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/Makefile
@@ -0,0 +1,68 @@
+# From: @(#)Makefile 8.3 (Berkeley) 4/2/94
+# $FreeBSD$
+
+# Only NO_PAM is used by PicoBSD and supported here
+
+
+PROG= passwd
+SRCS= local_passwd.c passwd.c pw_copy.c pw_util.c
+
+GENSRCS=yp.h yp_clnt.c yppasswd.h yppasswd_clnt.c \
+ yppasswd_private.h yppasswd_private_clnt.c yppasswd_private_xdr.c
+CFLAGS+=-Wall
+
+LIBADD= crypt util
+.PATH: ${.CURDIR}/../../../../usr.bin/chpass \
+# ${.CURDIR}/../../../../usr.sbin/vipw \
+# ${.CURDIR}/../../../../usr.bin/passwd
+
+CFLAGS+= -DLOGIN_CAP -DCRYPT -I. -I${.CURDIR} \
+# -I${.CURDIR}/../../../../usr.bin/passwd \
+# -I${.CURDIR}/../../../../usr.sbin/vipw \
+# -I${.CURDIR}/../../../../usr.bin/chpass \
+# -I${.CURDIR}/../../../../lib/libc/gen \
+# -Dyp_error=warnx -DLOGGING
+
+CLEANFILES= ${GENSRCS}
+
+RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -C
+RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x
+RPCSRC_PW= ${DESTDIR}/usr/include/rpcsvc/yppasswd.x
+RPCSRC_PRIV= ${.CURDIR}/../../usr.sbin/rpc.yppasswdd/yppasswd_private.x
+
+yp.h: ${RPCSRC}
+ ${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
+
+yp_clnt.c: ${RPCSRC} yp.h
+ ${RPCGEN} -l -o ${.TARGET} ${RPCSRC}
+
+yppasswd.h: ${RPCSRC_PW}
+ ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PW}
+
+yppasswd_clnt.c: ${RPCSRC_PW}
+ ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PW}
+
+yppasswd_private.h: ${RPCSRC_PRIV}
+ ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV}
+
+yppasswd_private_xdr.c: ${RPCSRC_PRIV}
+ ${RPCGEN} -c -o ${.TARGET} ${RPCSRC_PRIV}
+
+yppasswd_private_clnt.c: ${RPCSRC_PRIV}
+ ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PRIV}
+
+BINOWN= root
+BINMODE=4555
+LINKS=${BINDIR}/passwd ${BINDIR}/yppasswd
+MLINKS=passwd.1 yppasswd.1
+
+beforeinstall:
+.for i in passwd yppasswd
+ [ ! -e ${DESTDIR}${BINDIR}/$i ] || \
+ chflags noschg ${DESTDIR}${BINDIR}/$i || true
+.endfor
+
+afterinstall:
+ -chflags schg ${DESTDIR}${BINDIR}/passwd
+
+.include <bsd.prog.mk>
diff --git a/release/picobsd/tinyware/passwd/extern.h b/release/picobsd/tinyware/passwd/extern.h
new file mode 100644
index 0000000..eae768c
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/extern.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1994
+ * 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.
+ *
+ * From: @(#)extern.h 8.1 (Berkeley) 4/2/94
+ * $FreeBSD$
+ */
+
+int krb_passwd(char *, char *, char *, char *);
+int local_passwd(char *);
diff --git a/release/picobsd/tinyware/passwd/local_passwd.c b/release/picobsd/tinyware/passwd/local_passwd.c
new file mode 100644
index 0000000..33af88a
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/local_passwd.c
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * 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.
+ */
+
+#ifndef lint
+static const char sccsid[] = "@(#)local_passwd.c 8.3 (Berkeley) 4/2/94";
+#endif /* not lint */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <pw_util.h>
+#ifdef YP
+#include <pw_yp.h>
+#endif
+
+#ifdef LOGGING
+#include <syslog.h>
+#endif
+
+#ifdef LOGIN_CAP
+#ifdef AUTH_NONE /* multiple defs :-( */
+#undef AUTH_NONE
+#endif
+#include <login_cap.h>
+#endif
+
+#include "extern.h"
+
+static uid_t uid;
+int randinit;
+
+extern void
+pw_copy(int ffd, int tfd, struct passwd *pw, struct passwd *old_pw);
+
+char *tempname;
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void
+to64(s, v, n)
+ char *s;
+ long v;
+ int n;
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
+
+char *
+getnewpasswd(pw, nis)
+ struct passwd *pw;
+ int nis;
+{
+ int tries, min_length = 6;
+ int force_mix_case = 1;
+ char *p, *t;
+#ifdef LOGIN_CAP
+ login_cap_t * lc;
+#endif
+ char buf[_PASSWORD_LEN+1], salt[32];
+ struct timeval tv;
+
+ if (!nis)
+ (void)printf("Changing local password for %s.\n", pw->pw_name);
+
+ if (uid && pw->pw_passwd[0] &&
+ strcmp(crypt(getpass("Old password:"), pw->pw_passwd),
+ pw->pw_passwd)) {
+ errno = EACCES;
+ pw_error(NULL, 1, 1);
+ }
+
+#ifdef LOGIN_CAP
+ /*
+ * Determine minimum password length, next password change date,
+ * and whether or not to force mixed case passwords.
+ * Note that even for NIS passwords, login_cap is still used.
+ */
+ if ((lc = login_getpwclass(pw)) != NULL) {
+ time_t period;
+
+ /* minpasswordlen capablity */
+ min_length = (int)login_getcapnum(lc, "minpasswordlen",
+ min_length, min_length);
+ /* passwordtime capability */
+ period = login_getcaptime(lc, "passwordtime", 0, 0);
+ if (period > (time_t)0) {
+ pw->pw_change = time(NULL) + period;
+ }
+ /* mixpasswordcase capability */
+ force_mix_case = login_getcapbool(lc, "mixpasswordcase", 1);
+ }
+#endif
+
+ for (buf[0] = '\0', tries = 0;;) {
+ p = getpass("New password:");
+ if (!*p) {
+ (void)printf("Password unchanged.\n");
+ pw_error(NULL, 0, 0);
+ }
+ if (strlen(p) < min_length && (uid != 0 || ++tries < 2)) {
+ (void)printf("Please enter a password at least %d characters in length.\n", min_length);
+ continue;
+ }
+
+ if (force_mix_case) {
+ for (t = p; *t && islower(*t); ++t);
+ if (!*t && (uid != 0 || ++tries < 2)) {
+ (void)printf("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.\n");
+ continue;
+ }
+ }
+ (void)strcpy(buf, p);
+ if (!strcmp(buf, getpass("Retype new password:")))
+ break;
+ (void)printf("Mismatch; try again, EOF to quit.\n");
+ }
+ /* grab a random printable character that isn't a colon */
+ if (!randinit) {
+ randinit = 1;
+ srandomdev();
+ }
+#ifdef NEWSALT
+ salt[0] = _PASSWORD_EFMT1;
+ to64(&salt[1], (long)(29 * 25), 4);
+ to64(&salt[5], random(), 4);
+ salt[9] = '\0';
+#else
+ /* Make a good size salt for algorithms that can use it. */
+ gettimeofday(&tv,0);
+#ifdef LOGIN_CAP
+ if (login_setcryptfmt(lc, "md5", NULL) == NULL)
+ pw_error("cannot set password cipher", 1, 1);
+ login_close(lc);
+#else
+ (void)crypt_set_format("md5");
+#endif
+ /* Salt suitable for anything */
+ to64(&salt[0], random(), 3);
+ to64(&salt[3], tv.tv_usec, 3);
+ to64(&salt[6], tv.tv_sec, 2);
+ to64(&salt[8], random(), 5);
+ to64(&salt[13], random(), 5);
+ to64(&salt[17], random(), 5);
+ to64(&salt[22], random(), 5);
+ salt[27] = '\0';
+#endif
+ return (crypt(buf, salt));
+}
+
+int
+local_passwd(uname)
+ char *uname;
+{
+ struct passwd *pw;
+ int pfd, tfd;
+
+ if (!(pw = getpwnam(uname)))
+ errx(1, "unknown user %s", uname);
+
+#ifdef YP
+ /* Use the right password information. */
+ pw = (struct passwd *)&local_password;
+#endif
+ uid = getuid();
+ if (uid && uid != pw->pw_uid)
+ errx(1, "%s", strerror(EACCES));
+
+ pw_init();
+
+ /*
+ * Get the new password. Reset passwd change time to zero by
+ * default. If the user has a valid login class (or the default
+ * fallback exists), then the next password change date is set
+ * by getnewpasswd() according to the "passwordtime" capability
+ * if one has been specified.
+ */
+ pw->pw_change = 0;
+ pw->pw_passwd = getnewpasswd(pw, 0);
+
+ pfd = pw_lock();
+ tfd = pw_tmp();
+ pw_copy(pfd, tfd, pw, NULL);
+
+ if (!pw_mkdb(uname))
+ pw_error((char *)NULL, 0, 1);
+#ifdef LOGGING
+ syslog(LOG_DEBUG, "user %s changed their local password\n", uname);
+#endif
+ return (0);
+}
diff --git a/release/picobsd/tinyware/passwd/passwd.c b/release/picobsd/tinyware/passwd/passwd.c
new file mode 100644
index 0000000..42ebd8c
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/passwd.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1988, 1993, 1994
+ * 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.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1988, 1993, 1994\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)passwd.c 8.3 (Berkeley) 4/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#include <err.h>
+#include <errno.h>
+#include <libutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef YP
+#include <pwd.h>
+#include <pw_yp.h>
+#include <rpcsvc/yp.h>
+int __use_yp = 0;
+int yp_errno = YP_TRUE;
+extern int yp_passwd( char * );
+#endif
+
+#include "extern.h"
+
+static void usage(void);
+
+int use_local_passwd = 0;
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int ch;
+ char *uname;
+
+#ifdef YP
+#define OPTIONS "d:h:lysfo"
+#else
+#define OPTIONS "l"
+#endif
+
+#ifdef YP
+ int res = 0;
+
+ if (strstr(argv[0], "yppasswd")) __use_yp = 1;
+#endif
+
+ while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
+ switch (ch) {
+ case 'l': /* change local password file */
+ use_local_passwd = 1;
+ break;
+#ifdef YP
+ case 'y': /* Change NIS password */
+ __use_yp = 1;
+ break;
+ case 'd': /* Specify NIS domain. */
+#ifdef PARANOID
+ if (!getuid()) {
+#endif
+ yp_domain = optarg;
+ if (yp_server == NULL)
+ yp_server = "localhost";
+#ifdef PARANOID
+ } else {
+ warnx("only the super-user may use the -d flag");
+ }
+#endif
+ break;
+ case 'h': /* Specify NIS server. */
+#ifdef PARANOID
+ if (!getuid()) {
+#endif
+ yp_server = optarg;
+#ifdef PARANOID
+ } else {
+ warnx("only the super-user may use the -h flag");
+ }
+#endif
+ break;
+ case 'o':
+ force_old++;
+ break;
+#endif
+ default:
+ case '?':
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if ((uname = getlogin()) == NULL)
+ err(1, "getlogin");
+
+ switch(argc) {
+ case 0:
+ break;
+ case 1:
+ uname = argv[0];
+ break;
+ default:
+ usage();
+ }
+
+#ifdef YP
+ /*
+ * If NIS is turned on in the password database, use it, else punt.
+ */
+ res = use_yp(uname, 0, 0);
+ if (res == USER_YP_ONLY) {
+ if (!use_local_passwd) {
+ exit(yp_passwd(uname));
+ } else {
+ /*
+ * Reject -l flag if NIS is turned on and the user
+ * doesn't exist in the local password database.
+ */
+ errx(1, "unknown local user: %s", uname);
+ }
+ } else if (res == USER_LOCAL_ONLY) {
+ /*
+ * Reject -y flag if user only exists locally.
+ */
+ if (__use_yp)
+ errx(1, "unknown NIS user: %s", uname);
+ } else if (res == USER_YP_AND_LOCAL) {
+ if (!use_local_passwd && (yp_in_pw_file || __use_yp))
+ exit(yp_passwd(uname));
+ }
+#endif
+
+ exit(local_passwd(uname));
+}
+
+static void
+usage()
+{
+
+#ifdef YP
+ (void)fprintf(stderr,
+ "usage: passwd [-l] [-y] [-o] [-d domain [-h host]] [user]\n");
+#else
+ (void)fprintf(stderr, "usage: passwd [-l] user\n");
+#endif
+ exit(1);
+}
diff --git a/release/picobsd/tinyware/passwd/pw_copy.c b/release/picobsd/tinyware/passwd/pw_copy.c
new file mode 100644
index 0000000..753e1a6
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/pw_copy.c
@@ -0,0 +1,304 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * 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.
+ */
+
+#ifndef lint
+static const char sccsid[] = "@(#)pw_copy.c 8.4 (Berkeley) 4/2/94";
+#endif /* not lint */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * This module is used to copy the master password file, replacing a single
+ * record, by chpass(1) and passwd(1).
+ */
+
+#include <err.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#if 0
+#include <pw_scan.h>
+#endif
+extern int pw_big_ids_warning;
+extern int pw_scan(char *, struct passwd *);
+
+#include <pw_util.h>
+
+extern char *tempname;
+
+/* for use in pw_copy(). Compare a pw entry to a pw struct. */
+static int
+pw_equal(char *buf, struct passwd *pw)
+{
+ struct passwd buf_pw;
+ int len;
+
+ len = strlen (buf);
+ if (buf[len-1] == '\n')
+ buf[len-1] = '\0';
+ return (strcmp(pw->pw_name, buf_pw.pw_name) == 0
+ && pw->pw_uid == buf_pw.pw_uid
+ && pw->pw_gid == buf_pw.pw_gid
+ && strcmp(pw->pw_class, buf_pw.pw_class) == 0
+ && (long)pw->pw_change == (long)buf_pw.pw_change
+ && (long)pw->pw_expire == (long)buf_pw.pw_expire
+ && strcmp(pw->pw_gecos, buf_pw.pw_gecos) == 0
+ && strcmp(pw->pw_dir, buf_pw.pw_dir) == 0
+ && strcmp(pw->pw_shell, buf_pw.pw_shell) == 0);
+}
+
+void
+pw_copy(int ffd, int tfd, struct passwd *pw, struct passwd *old_pw)
+{
+ FILE *from, *to;
+ int done;
+ char *p, buf[8192];
+ char uidstr[20];
+ char gidstr[20];
+ char chgstr[20];
+ char expstr[20];
+
+ snprintf(uidstr, sizeof(uidstr), "%lu", (unsigned long)pw->pw_uid);
+ snprintf(gidstr, sizeof(gidstr), "%lu", (unsigned long)pw->pw_gid);
+ snprintf(chgstr, sizeof(chgstr), "%ld", (long)pw->pw_change);
+ snprintf(expstr, sizeof(expstr), "%ld", (long)pw->pw_expire);
+
+ if (!(from = fdopen(ffd, "r")))
+ pw_error(_PATH_MASTERPASSWD, 1, 1);
+ if (!(to = fdopen(tfd, "w")))
+ pw_error(tempname, 1, 1);
+
+ for (done = 0; fgets(buf, sizeof(buf), from);) {
+ if (!strchr(buf, '\n')) {
+ warnx("%s: line too long", _PATH_MASTERPASSWD);
+ pw_error(NULL, 0, 1);
+ }
+ if (done) {
+ (void)fprintf(to, "%s", buf);
+ if (ferror(to))
+ goto err;
+ continue;
+ }
+ for (p = buf; *p != '\n'; p++)
+ if (*p != ' ' && *p != '\t')
+ break;
+ if (*p == '#' || *p == '\n') {
+ (void)fprintf(to, "%s", buf);
+ if (ferror(to))
+ goto err;
+ continue;
+ }
+ if (!(p = strchr(buf, ':'))) {
+ warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
+ pw_error(NULL, 0, 1);
+ }
+ *p = '\0';
+ if (strcmp(buf, pw->pw_name)) {
+ *p = ':';
+ (void)fprintf(to, "%s", buf);
+ if (ferror(to))
+ goto err;
+ continue;
+ }
+ *p = ':';
+ if (old_pw && !pw_equal(buf, old_pw)) {
+ warnx("%s: entry for %s has changed",
+ _PATH_MASTERPASSWD, pw->pw_name);
+ pw_error(NULL, 0, 1);
+ }
+ (void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
+ pw->pw_name, pw->pw_passwd,
+ pw->pw_fields & _PWF_UID ? uidstr : "",
+ pw->pw_fields & _PWF_GID ? gidstr : "",
+ pw->pw_class,
+ pw->pw_fields & _PWF_CHANGE ? chgstr : "",
+ pw->pw_fields & _PWF_EXPIRE ? expstr : "",
+ pw->pw_gecos, pw->pw_dir, pw->pw_shell);
+ done = 1;
+ if (ferror(to))
+ goto err;
+ }
+ if (!done) {
+#ifdef YP
+ /* Ultra paranoid: shouldn't happen. */
+ if (getuid()) {
+ warnx("%s: not found in %s -- permission denied",
+ pw->pw_name, _PATH_MASTERPASSWD);
+ pw_error(NULL, 0, 1);
+ } else
+#endif /* YP */
+ (void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
+ pw->pw_name, pw->pw_passwd,
+ pw->pw_fields & _PWF_UID ? uidstr : "",
+ pw->pw_fields & _PWF_GID ? gidstr : "",
+ pw->pw_class,
+ pw->pw_fields & _PWF_CHANGE ? chgstr : "",
+ pw->pw_fields & _PWF_EXPIRE ? expstr : "",
+ pw->pw_gecos, pw->pw_dir, pw->pw_shell);
+ }
+
+ if (ferror(to))
+err: pw_error(NULL, 1, 1);
+ (void)fclose(to);
+}
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+/*
+ * Some software assumes that IDs are short. We should emit warnings
+ * for id's which can not be stored in a short, but we are more liberal
+ * by default, warning for IDs greater than USHRT_MAX.
+ *
+ * If pw_big_ids_warning is anything other than -1 on entry to pw_scan()
+ * it will be set based on the existence of PW_SCAN_BIG_IDS in the
+ * environment.
+ */
+int pw_big_ids_warning = -1;
+
+int
+pw_scan(bp, pw)
+ char *bp;
+ struct passwd *pw;
+{
+ uid_t id;
+ int root;
+ char *p, *sh;
+
+ if (pw_big_ids_warning == -1)
+ pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0;
+
+ pw->pw_fields = 0;
+ if (!(pw->pw_name = strsep(&bp, ":"))) /* login */
+ goto fmt;
+ root = !strcmp(pw->pw_name, "root");
+ if(pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0'))
+ pw->pw_fields |= _PWF_NAME;
+
+ if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */
+ goto fmt;
+ if(pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD;
+
+ if (!(p = strsep(&bp, ":"))) /* uid */
+ goto fmt;
+ if (p[0])
+ pw->pw_fields |= _PWF_UID;
+ else {
+ if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
+ warnx("no uid for user %s", pw->pw_name);
+ return (0);
+ }
+ }
+ id = strtoul(p, (char **)NULL, 10);
+ if (errno == ERANGE) {
+ warnx("%s > max uid value (%lu)", p, ULONG_MAX);
+ return (0);
+ }
+ if (root && id) {
+ warnx("root uid should be 0");
+ return (0);
+ }
+ if (pw_big_ids_warning && id > USHRT_MAX) {
+ warnx("%s > recommended max uid value (%u)", p, USHRT_MAX);
+ /*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
+ }
+ pw->pw_uid = id;
+
+ if (!(p = strsep(&bp, ":"))) /* gid */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_GID;
+ id = strtoul(p, (char **)NULL, 10);
+ if (errno == ERANGE) {
+ warnx("%s > max gid value (%u)", p, ULONG_MAX);
+ return (0);
+ }
+ if (pw_big_ids_warning && id > USHRT_MAX) {
+ warnx("%s > recommended max gid value (%u)", p, USHRT_MAX);
+ /* return (0); This should not be fatal! */
+ }
+ pw->pw_gid = id;
+
+ pw->pw_class = strsep(&bp, ":"); /* class */
+ if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS;
+
+ if (!(p = strsep(&bp, ":"))) /* change */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_CHANGE;
+ pw->pw_change = atol(p);
+
+ if (!(p = strsep(&bp, ":"))) /* expire */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_EXPIRE;
+ pw->pw_expire = atol(p);
+
+ if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */
+ goto fmt;
+ if(pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS;
+
+ if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */
+ goto fmt;
+ if(pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR;
+
+ if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */
+ goto fmt;
+
+ p = pw->pw_shell;
+ if (root && *p) /* empty == /bin/sh */
+ for (setusershell();;) {
+ if (!(sh = getusershell())) {
+ warnx("warning, unknown root shell");
+ break;
+ }
+ if (!strcmp(p, sh))
+ break;
+ }
+ if(p[0]) pw->pw_fields |= _PWF_SHELL;
+
+ if ((p = strsep(&bp, ":"))) { /* too many */
+fmt: warnx("corrupted entry");
+ return (0);
+ }
+ return (1);
+}
diff --git a/release/picobsd/tinyware/passwd/pw_util.c b/release/picobsd/tinyware/passwd/pw_util.c
new file mode 100644
index 0000000..1c163d2
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/pw_util.c
@@ -0,0 +1,258 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * 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.
+ */
+
+#ifndef lint
+#if 0
+static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
+#endif
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
+/*
+ * This file is used by all the "password" programs; vipw(8), chpass(1),
+ * and passwd(1).
+ */
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pw_util.h"
+
+extern char *tempname;
+static pid_t editpid = -1;
+static int lockfd;
+static char _default_editor[] = _PATH_VI;
+static char _default_mppath[] = _PATH_PWD;
+static char _default_masterpasswd[] = _PATH_MASTERPASSWD;
+char *mppath = _default_mppath;
+char *masterpasswd = _default_masterpasswd;
+
+void pw_cont(int);
+
+void
+pw_cont(int sig)
+{
+
+ if (editpid != -1)
+ kill(editpid, sig);
+}
+
+void
+pw_init(void)
+{
+ 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(SIGCONT, pw_cont);
+
+ /* Create with exact permissions. */
+ (void)umask(0);
+}
+
+int
+pw_lock(void)
+{
+ /*
+ * If the master password file doesn't exist, the system is hosed.
+ * Might as well try to build one. Set the close-on-exec bit so
+ * that users can't get at the encrypted passwords while editing.
+ * Open should allow flock'ing the file; see 4.4BSD. XXX
+ */
+ for (;;) {
+ struct stat st;
+
+ lockfd = open(masterpasswd, O_RDONLY, 0);
+ if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
+ err(1, "%s", masterpasswd);
+ if (flock(lockfd, LOCK_EX|LOCK_NB))
+ errx(1, "the password db file is busy");
+
+ /*
+ * If the password file was replaced while we were trying to
+ * get the lock, our hardlink count will be 0 and we have to
+ * close and retry.
+ */
+ if (fstat(lockfd, &st) < 0)
+ errx(1, "fstat() failed");
+ if (st.st_nlink != 0)
+ break;
+ close(lockfd);
+ lockfd = -1;
+ }
+ return (lockfd);
+}
+
+int
+pw_tmp(void)
+{
+ static char path[MAXPATHLEN];
+ int fd;
+ char *p;
+
+ strncpy(path, masterpasswd, MAXPATHLEN - 1);
+ path[MAXPATHLEN] = '\0';
+
+ if ((p = strrchr(path, '/')))
+ ++p;
+ else
+ p = path;
+ strcpy(p, "pw.XXXXXX");
+ if ((fd = mkstemp(path)) == -1)
+ err(1, "%s", path);
+ tempname = path;
+ return (fd);
+}
+
+int
+pw_mkdb(const char *username)
+{
+ int pstat;
+ pid_t pid;
+
+ (void)fflush(stderr);
+ if (!(pid = fork())) {
+ if(!username) {
+ warnx("rebuilding the database...");
+ execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
+ tempname, (char *)NULL);
+ } else {
+ warnx("updating the database...");
+ execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", mppath,
+ "-u", username, tempname, (char *)NULL);
+ }
+ pw_error(_PATH_PWD_MKDB, 1, 1);
+ }
+ pid = waitpid(pid, &pstat, 0);
+ if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
+ return (0);
+ warnx("done");
+ return (1);
+}
+
+void
+pw_edit(int notsetuid)
+{
+ int pstat;
+ char *p, *editor;
+
+ if (!(editor = getenv("EDITOR")))
+ editor = _default_editor;
+ if ((p = strrchr(editor, '/')))
+ ++p;
+ else
+ p = editor;
+
+ if (!(editpid = fork())) {
+ if (notsetuid) {
+ (void)setgid(getgid());
+ (void)setuid(getuid());
+ }
+ errno = 0;
+ execlp(editor, p, tempname, (char *)NULL);
+ _exit(errno);
+ }
+ for (;;) {
+ editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
+ errno = WEXITSTATUS(pstat);
+ if (editpid == -1)
+ pw_error(editor, 1, 1);
+ else if (WIFSTOPPED(pstat))
+ raise(WSTOPSIG(pstat));
+ else if (WIFEXITED(pstat) && errno == 0)
+ break;
+ else
+ pw_error(editor, 1, 1);
+ }
+ editpid = -1;
+}
+
+void
+pw_prompt(void)
+{
+ int c, first;
+
+ (void)printf("re-edit the password file? [y]: ");
+ (void)fflush(stdout);
+ first = c = getchar();
+ while (c != '\n' && c != EOF)
+ c = getchar();
+ if (first == 'n')
+ pw_error(NULL, 0, 0);
+}
+
+void
+pw_error(const char *name, int error, int eval)
+{
+ if (error) {
+ if (name != NULL)
+ warn("%s", name);
+ else
+ warn(NULL);
+ }
+ warnx("password information unchanged");
+ (void)unlink(tempname);
+ exit(eval);
+}
diff --git a/release/picobsd/tinyware/passwd/pw_util.h b/release/picobsd/tinyware/passwd/pw_util.h
new file mode 100644
index 0000000..1000a9a
--- /dev/null
+++ b/release/picobsd/tinyware/passwd/pw_util.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1994
+ * 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.
+ *
+ * @(#)pw_util.h 8.2 (Berkeley) 4/1/94
+ *
+ * $FreeBSD$
+ */
+
+void pw_edit(int);
+void pw_error(const char *, int, int);
+void pw_init(void);
+int pw_lock(void);
+int pw_mkdb(const char *);
+void pw_prompt(void);
+int pw_tmp(void);
diff --git a/release/picobsd/tinyware/simple_httpd/Makefile b/release/picobsd/tinyware/simple_httpd/Makefile
new file mode 100644
index 0000000..7b797ac
--- /dev/null
+++ b/release/picobsd/tinyware/simple_httpd/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+#
+PROG=simple_httpd
+SRCS= simple_httpd.c
+MAN=
+WARNS?=6
+
+.include <bsd.prog.mk>
diff --git a/release/picobsd/tinyware/simple_httpd/README b/release/picobsd/tinyware/simple_httpd/README
new file mode 100644
index 0000000..ade3be1
--- /dev/null
+++ b/release/picobsd/tinyware/simple_httpd/README
@@ -0,0 +1,167 @@
+Simple_httpd - A small and free Web server
+
+"Simple_httpd is like /usr/bin/mail is to mail clients, no frills."
+
+This HTTP server can be used in any FreeBSD/PicoBSD application.
+
+It has been tested under FreeBSD 2.2.x, 3.x and 4.x. It might work
+on other OS systems, but it's for FreeBSD primarily.
+
+The main advantage to Simple_httpd is that it is very small.
+The 25K binary can satisfy most needs in a small or embedded
+appplication. If you want a full featured server see
+/usr/ports/www/apache* or http://www.apache.org
+
+Simple_httpd is released under a BSD style copyright that unlike
+GPL is embedded developer friendly.
+
+The server is designed to be run in one of two modes. The standard
+mode is a httpd server running in the background serving up a directory
+of html,gif,cgi whatever. Your traditional www server.
+
+The "fetch" mode supports file transfer over httpd. This
+is best thought of as mate for fetch(1). This feature can be
+useful to transfer a file from one host to another.
+
+Simple_httpd has the ability to run CGI scripts. All CGI
+scripts must be located in ${DOCUMENT_ROOT}/cgi-bin. The
+server currently only sets 3 environment variables before calling
+the script.
+
+CGI Environment variables are below:
+
+SERVER_SOFTWARE = FreeBSD/PicoBSD
+REMOTE_HOST = client.canada_lower_taxes.com
+REMOTE_ADDR = 200.122.13.108
+
+In most target applications for this server the extra DNS traffic from
+the remote_addr lookup will likely be on the local lan anyway and not
+on the other side of the internet. You can turn it off yourself in
+the code if you want to speed the whole process up. Be sure to turn
+it off for the logfile also.
+
+How to use it?
+==============
+
+Compile with make, run as follows
+
+usage: simple_httpd [-vD]
+ [-d directory]
+ [-g grpid]
+ [-l logfile]
+ [-p port]
+or
+usage: simple_httpd [-p port] -f filename
+
+-v
+Run the server verbose. Show the program options that will be used for this
+process. Will only show information during startup, no messages will
+be displayed while serving requests. In other words you can still
+daemonize without fear of output on stdout.
+
+-D
+Do not daemonize. The server will not run in the background. It will
+stay attached to the tty. This is useful for debugging. In this
+mode no log file is created. Logging info is to stdout.
+
+This option is automatically selected if fetch option is selected.
+
+-d directory
+The html document directory, if nothing is provided the default is
+/httphome if UID is root, otherwise document root is ${HOME}/public_html
+
+-l logfile
+Set the logfile to use. Log messages will be written to /var/log/jhttpd.log
+if you are root and ${HOME}/jhttpd.log otherwise. If you don't want a
+log file try "-l /dev/null"
+
+-p port
+Set the port httpd server will listen to. Default is port 80 if
+you are root and 1080 if you are not.
+
+-f filename
+This is the only option needed to use the "fetch" feature. The file
+specified will be the ONLY file served to ANY GET request from a browser
+or fetch(1).
+
+Example
+=======
+
+Standard Mode:
+--------------
+If you have the FreeBSD handbook installed on your machine and would
+like to serve it up over http for a quick look you could do this
+
+simple_httpd -d /usr/share/doc/handbook -l /usr/tmp/jlog.txt -p 1088 -v
+
+Any browser would be able to look at the handbook with
+http://whatever_host/handbook.html:1088
+
+I'm using 1088 as the port since I already have apache running on port 80
+and port 1080 on my host.
+
+Please note, the handbook is not installed by default in FreeBSD 3.x
+It must be installed from the ports collection first if you want to
+try this.
+
+Another simple example is to browse your local ports collection:
+
+cd /usr/ports
+make readmes #wait about 1 hour!
+simple_httpd -p 1080 -v -d /usr/ports
+
+Then point your browser at http://whatever_host/README.html
+
+Fetch Mode:
+--------------
+This is designed to be used in conjunction with fetch(3). It allows
+for easy transfer of files from one host to another without messy
+authentication or pathnames required with ftp. The file to be
+served up must be readable by the user running simple_httpd.
+This is not a magic way to avoid permissions and read files.
+
+The daemon will only serve up ONE file. The file specified will
+be returned for every GET request regardless of what the browser
+asks for. This allows for on the fly naming.
+
+sender# simple_httpd -f /usr/tmp/big_file.tgz
+receiver# fetch http://sender.com/Industrial_Secrets.tgz
+
+big_file.tgz was transferred from one machine to another and renamed
+Industrial_Secrets.tgz at the same time.
+
+Tunneling over other TCP ports. Choose something that firewall
+will probably pass. See /etc/services.
+
+sender# simple_httpd -p 53 -f /usr/tmp/big_file.tgz
+receiver# fetch http://sender.com:53/Industrial_Secrets.tgz
+
+To Do
+=====
+
+Simple authentication would be very useful [understatment].
+/etc/passwd or PAM would be nice.
+
+I think a netmask option would be good. Most internet appliances
+probably want to restrict traffic to local ethernet anyway.
+ie: Allow anything from my class C.
+
+The server always has 1 zombie process hanging around when it
+runs as a daemon. Should fix so that it doesn't happen.
+
+Anything to make it faster!
+
+Man page
+
+If anyone has any improvements or ways to easily implement something
+please let me <wlloyd@slap.net> know. If you make some neat embedded
+device with PicoBSD I want to know too!
+
+Credits
+=======
+
+This program was originally contributed by Marc Nicholas <marc@netstor.com>
+
+Major rewrite by William Lloyd <wlloyd@slap.net>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/simple_httpd/simple_httpd.c b/release/picobsd/tinyware/simple_httpd/simple_httpd.c
new file mode 100644
index 0000000..58d4feb
--- /dev/null
+++ b/release/picobsd/tinyware/simple_httpd/simple_httpd.c
@@ -0,0 +1,501 @@
+/*-
+ * Simple_HTTPd v1.1 - a very small, barebones HTTP server
+ *
+ * Copyright (c) 1998-1999 Marc Nicholas <marc@netstor.com>
+ * All rights reserved.
+ *
+ * Major rewrite by William Lloyd <wlloyd@slap.net>
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+int http_port = 80;
+int daemonize = 1;
+int verbose = 0;
+int http_sock, con_sock;
+
+const char *fetch_mode = NULL;
+char homedir[100];
+char logfile[80];
+char *adate(void);
+void init_servconnection(void);
+void http_date(void);
+void http_output(const char *html);
+void http_request(void);
+void log_line(char *req);
+void wait_connection(void);
+
+struct hostent *hst;
+struct sockaddr_in source;
+
+/* HTTP basics */
+static char httpd_server_ident[] = "Server: FreeBSD/PicoBSD simple_httpd 1.1\r";
+
+static char http_200[] = "HTTP/1.0 200 OK\r";
+
+const char *default_mime_type = "application/octet-stream";
+
+const char *mime_type[][2] = {
+ { "txt", "text/plain" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "gif", "image/gif" },
+ { "jpg", "image/jpeg" },
+ { "mp3", "audio/mpeg" }
+};
+
+const int mime_type_max = sizeof(mime_type) / sizeof(mime_type[0]) - 1;
+
+/* Two parts, HTTP Header and then HTML */
+static const char *http_404[2] =
+ {"HTTP/1.0 404 Not found\r\n",
+"<HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY><H1>Error 404</H1>\
+Not found - file doesn't exist or you do not have permission.\n</BODY></HTML>\r\n"
+};
+
+static const char *http_405[2] =
+ {"HTTP/1.0 405 Method Not allowed\r\nAllow: GET,HEAD\r\n",
+"<HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY><H1>Error 405</H1>\
+This server only supports GET and HEAD requests.\n</BODY></HTML>\r\n"
+};
+
+/*
+ * Only called on initial invocation
+ */
+void
+init_servconnection(void)
+{
+ struct sockaddr_in server;
+
+ /* Create a socket */
+ http_sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (http_sock < 0) {
+ perror("socket");
+ exit(1);
+ }
+ server.sin_family = AF_INET;
+ server.sin_port = htons(http_port);
+ server.sin_addr.s_addr = INADDR_ANY;
+ if (bind(http_sock, (struct sockaddr *) & server, sizeof(server)) < 0) {
+ perror("bind socket");
+ exit(1);
+ }
+ if (verbose) printf("simple_httpd:%d\n",http_port);
+}
+
+/*
+ * Wait here until we see an incoming http request
+ */
+void
+wait_connection(void)
+{
+ socklen_t lg;
+
+ lg = sizeof(struct sockaddr_in);
+
+ con_sock = accept(http_sock, (struct sockaddr *) & source, &lg);
+ if (con_sock <= 0) {
+ perror("accept");
+ exit(1);
+ }
+}
+
+/*
+ * Print timestamp for HTTP HEAD and GET
+ */
+void
+http_date(void)
+{
+ time_t tl;
+ char buff[50];
+
+ tl = time(NULL);
+ strftime(buff, 50, "Date: %a, %d %h %Y %H:%M:%S %Z\r\n", gmtime(&tl));
+ write(con_sock, buff, strlen(buff));
+ /* return(buff); */
+}
+
+/*
+ * Send data to the open socket
+ */
+void
+http_output(const char *html)
+{
+ write(con_sock, html, strlen(html));
+ write(con_sock, "\r\n", 2);
+}
+
+
+/*
+ * Create and write the log information to file
+ * Log file format is one line per entry
+ */
+void
+log_line(char *req)
+{
+ char log_buff[256];
+ char msg[1024];
+ char env_host[80], env_addr[80];
+ long addr;
+ FILE *log;
+
+ strcpy(log_buff,inet_ntoa(source.sin_addr));
+ sprintf(env_addr, "REMOTE_ADDR=%s",log_buff);
+
+ addr=inet_addr(log_buff);
+
+ strcpy(msg,adate());
+ strcat(msg," ");
+ hst=gethostbyaddr((char*) &addr, 4, AF_INET);
+
+ /* If DNS hostname exists */
+ if (hst) {
+ strcat(msg,hst->h_name);
+ sprintf(env_host, "REMOTE_HOST=%s",hst->h_name);
+ }
+ strcat(msg," (");
+ strcat(msg,log_buff);
+ strcat(msg,") ");
+ strcat(msg,req);
+
+ if (daemonize) {
+ log=fopen(logfile,"a");
+ fprintf(log,"%s\n",msg);
+ fclose(log);
+ } else
+ printf("%s\n",msg);
+
+ /* This is for CGI scripts */
+ putenv(env_addr);
+ putenv(env_host);
+}
+
+/*
+ * We have a connection. Identify what type of request GET, HEAD, CGI, etc
+ * and do what needs to be done
+ */
+void
+http_request(void)
+{
+ int fd, lg, i;
+ int cmd = 0;
+ char *p, *par;
+ const char *filename, *c, *ext, *type;
+ struct stat file_status;
+ char req[1024];
+ char buff[8192];
+
+ lg = read(con_sock, req, 1024);
+
+ if ((p=strstr(req,"\n"))) *p=0;
+ if ((p=strstr(req,"\r"))) *p=0;
+
+ log_line(req);
+
+ c = strtok(req, " ");
+
+ /* Error msg if request is nothing */
+ if (c == NULL) {
+ http_output(http_404[0]);
+ http_output(http_404[1]);
+ goto end_request;
+ }
+
+ if (strncmp(c, "GET", 3) == 0) cmd = 1;
+ if (strncmp(c, "HEAD", 4) == 0) cmd = 2;
+
+ /* Do error msg for any other type of request */
+ if (cmd == 0) {
+ http_output(http_405[0]);
+ http_output(http_405[1]);
+ goto end_request;
+ }
+
+ filename = strtok(NULL, " ");
+
+ c = strtok(NULL, " ");
+ if (fetch_mode != NULL) filename=fetch_mode;
+ if (filename == NULL ||
+ strlen(filename)==1) filename="/index.html";
+
+ while (filename[0]== '/') filename++;
+
+ /* CGI handling. Untested */
+ if (!strncmp(filename,"cgi-bin/",8))
+ {
+ par=0;
+ if ((par=strstr(filename,"?")))
+ {
+ *par=0;
+ par++;
+ }
+ if (access(filename,X_OK)) goto conti;
+ stat (filename,&file_status);
+ if (setuid(file_status.st_uid)) return;
+ if (seteuid(file_status.st_uid)) return;
+ if (!fork())
+ {
+ close(1);
+ dup(con_sock);
+ /*printf("HTTP/1.0 200 OK\nContent-type: text/html\n\n\n");*/
+ printf("HTTP/1.0 200 OK\r\n");
+ /* Plug in environment variable, others in log_line */
+ setenv("SERVER_SOFTWARE", "FreeBSD/PicoBSD", 1);
+
+ execlp (filename,filename,par,(char *)0);
+ }
+ wait(&i);
+ return;
+ }
+ conti:
+ if (filename == NULL) {
+ http_output(http_405[0]);
+ http_output(http_405[1]);
+ goto end_request;
+ }
+ /* End of CGI handling */
+
+ /* Reject any request with '..' in it, bad hacker */
+ c = filename;
+ while (*c != '\0')
+ if (c[0] == '.' && c[1] == '.') {
+ http_output(http_404[0]);
+ http_output(http_404[1]);
+ goto end_request;
+ } else
+ c++;
+
+ /* Open filename */
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ http_output(http_404[0]);
+ http_output(http_404[1]);
+ goto end_request;
+ }
+
+ /* Get file status information */
+ if (fstat(fd, &file_status) < 0) {
+ http_output(http_404[0]);
+ http_output(http_404[1]);
+ goto end_request2;
+ }
+
+ /* Is it a regular file? */
+ if (!S_ISREG(file_status.st_mode)) {
+ http_output(http_404[0]);
+ http_output(http_404[1]);
+ goto end_request2;
+ }
+
+ /* Past this point we are serving either a GET or HEAD */
+ /* Print all the header info */
+ http_output(http_200);
+ http_output(httpd_server_ident);
+ http_date();
+
+ sprintf(buff, "Content-length: %jd\r\n", (intmax_t)file_status.st_size);
+ write(con_sock, buff, strlen(buff));
+
+ strcpy(buff, "Content-type: ");
+ type = default_mime_type;
+ if ((ext = strrchr(filename, '.')) != NULL) {
+ for (i = mime_type_max; i >= 0; i--)
+ if (strcmp(ext + 1, mime_type[i][0]) == 0) {
+ type = mime_type[i][1];
+ break;
+ }
+ }
+ strcat(buff, type);
+ http_output(buff);
+
+ strftime(buff, 50, "Last-Modified: %a, %d %h %Y %H:%M:%S %Z\r\n\r\n", gmtime(&file_status.st_mtime));
+ write(con_sock, buff, strlen(buff));
+
+ /* Send data only if GET request */
+ if (cmd == 1) {
+ while ((lg = read(fd, buff, 8192)) > 0)
+ write(con_sock, buff, lg);
+ }
+
+end_request2:
+ close(fd);
+end_request:
+ close(con_sock);
+
+}
+
+/*
+ * Simple httpd server for use in PicoBSD or other embedded application.
+ * Should satisfy simple httpd needs. For more demanding situations
+ * apache is probably a better (but much larger) choice.
+ */
+int
+main(int argc, char *argv[])
+{
+ int ch, ld;
+ pid_t httpd_group = 65534;
+ pid_t server_pid;
+
+ /* Default for html directory */
+ strcpy (homedir,getenv("HOME"));
+ if (!geteuid()) strcpy (homedir,"/httphome");
+ else strcat (homedir,"/httphome");
+
+ /* Defaults for log file */
+ if (geteuid()) {
+ strcpy(logfile,getenv("HOME"));
+ strcat(logfile,"/");
+ strcat(logfile,"jhttp.log");
+ } else
+ strcpy(logfile,"/var/log/jhttpd.log");
+
+ /* Parse command line arguments */
+ while ((ch = getopt(argc, argv, "d:f:g:l:p:vDh")) != -1)
+ switch (ch) {
+ case 'd':
+ strcpy(homedir,optarg);
+ break;
+ case 'f':
+ daemonize = 0;
+ verbose = 1;
+ fetch_mode = optarg;
+ break;
+ case 'g':
+ httpd_group = atoi(optarg);
+ break;
+ case 'l':
+ strcpy(logfile,optarg);
+ break;
+ case 'p':
+ http_port = atoi(optarg);
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'D':
+ daemonize = 0;
+ break;
+ case '?':
+ case 'h':
+ default:
+ printf("usage: simple_httpd [[-d directory][-g grpid][-l logfile][-p port][-vD]]\n");
+ exit(1);
+ /* NOTREACHED */
+ }
+
+ /* Not running as root and no port supplied, assume 1080 */
+ if ((http_port == 80) && geteuid()) {
+ http_port = 1080;
+ }
+
+ /* Do we really have rights in the html directory? */
+ if (fetch_mode == NULL) {
+ if (chdir(homedir)) {
+ perror("chdir");
+ puts(homedir);
+ exit(1);
+ }
+ }
+
+ /* Create log file if it doesn't exit */
+ if ((access(logfile,W_OK)) && daemonize) {
+ ld = open (logfile,O_WRONLY);
+ chmod (logfile,00600);
+ close(ld);
+ }
+
+ init_servconnection();
+
+ if (verbose) {
+ printf("Server started with options \n");
+ printf("port: %d\n",http_port);
+ if (fetch_mode == NULL) printf("html home: %s\n",homedir);
+ if (daemonize) printf("logfile: %s\n",logfile);
+ }
+
+ /* httpd is spawned */
+ if (daemonize) {
+ if ((server_pid = fork()) != 0) {
+ wait3(0,WNOHANG,0);
+ if (verbose) printf("pid: %d\n",server_pid);
+ exit(0);
+ }
+ wait3(0,WNOHANG,0);
+ }
+
+ if (fetch_mode == NULL)
+ setpgrp((pid_t)0, httpd_group);
+
+ /* How many connections do you want?
+ * Keep this lower than the available number of processes
+ */
+ if (listen(http_sock,15) < 0) exit(1);
+
+ label:
+ wait_connection();
+
+ if (fork()) {
+ wait3(0,WNOHANG,0);
+ close(con_sock);
+ goto label;
+ }
+
+ http_request();
+
+ wait3(0,WNOHANG,0);
+ exit(0);
+}
+
+
+char *
+adate(void)
+{
+ static char out[50];
+ time_t now;
+ struct tm *t;
+ time(&now);
+ t = localtime(&now);
+ sprintf(out, "%02d:%02d:%02d %02d/%02d/%02d",
+ t->tm_hour, t->tm_min, t->tm_sec,
+ t->tm_mday, t->tm_mon+1, t->tm_year );
+ return out;
+}
diff --git a/release/picobsd/tinyware/sps/Makefile b/release/picobsd/tinyware/sps/Makefile
new file mode 100644
index 0000000..a1bcf45
--- /dev/null
+++ b/release/picobsd/tinyware/sps/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+#
+PROG=sps
+SRCS= sps.c
+MAN=
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/sps/README b/release/picobsd/tinyware/sps/README
new file mode 100644
index 0000000..2357113
--- /dev/null
+++ b/release/picobsd/tinyware/sps/README
@@ -0,0 +1,11 @@
+This is a small 'ps' replacement, which uses information available via
+sysctl(3) interface (contrary to the 'aps', which requires you to mount
+procfs(5) to be able to get exactly the same info, so I think that 'sps'
+is superior solution).
+
+When I have some time, I'll add usual switches and other functions that normal
+'ps' has...
+
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/sps/sps.c b/release/picobsd/tinyware/sps/sps.c
new file mode 100644
index 0000000..f79d019
--- /dev/null
+++ b/release/picobsd/tinyware/sps/sps.c
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Small replacement for ps(1) - uses only sysctl(3) to retrieve info
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/stat.h>
+#include <sys/user.h>
+
+char p_stat[] = "?iRSTZWM";
+
+int
+main(int argc, char *argv[])
+{
+ int mib[4], i, num, len, j, plen;
+ char buf[MAXPATHLEN], vty[5], pst[5], wmesg[10];
+ struct kinfo_proc *ki;
+ char *t;
+ int ma, mi;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ALL;
+ if (sysctl(mib, 3, NULL, &len, NULL, 0) != 0) {
+ perror("sysctl sizing");
+ exit(1);
+ }
+ t = (char *)malloc(len);
+ if (sysctl(mib, 3, t, &len, NULL, 0) != 0) {
+ perror("sysctl info");
+ exit(1);
+ }
+ mib[2] = KERN_PROC_ARGS;
+ num = len / KINFO_PROC_SIZE;
+ i = 0;
+ printf("USERNAME PID PPID PRI NICE TTY STAT WCHAN COMMAND\n");
+ while(i < num) {
+ ki = (struct kinfo_proc *)(t + (num - i - 1) * KINFO_PROC_SIZE);
+ mib[3] = ki->ki_pid;
+ plen = MAXPATHLEN;
+ if (sysctl(mib, 4, buf, &plen, NULL, 0) != 0) {
+ perror("sysctl cmd info");
+ exit(1);
+ }
+ if (plen == 0) {
+ sprintf(buf, "(%s)", ki->ki_comm);
+ } else {
+ for (j = 0; j < plen - 1; j++) {
+ if (buf[j] == '\0') buf[j] = ' ';
+ }
+ }
+ if (strcmp(ki->ki_wmesg, "") == 0) {
+ sprintf(wmesg, "-");
+ } else {
+ strcpy(wmesg, ki->ki_wmesg);
+ }
+ ma = major(ki->ki_tdev);
+ mi = minor(ki->ki_tdev);
+ switch(ma) {
+ case 255:
+ strcpy(vty, "??");
+ break;
+ case 12:
+ if(mi != 255) {
+ sprintf(vty, "v%d", mi);
+ break;
+ }
+ /* FALLTHROUGH */
+ case 0:
+ strcpy(vty, "con");
+ break;
+ case 5:
+ sprintf(vty, "p%d", mi);
+ break;
+ }
+ sprintf(pst, "%c", p_stat[ki->ki_stat]);
+ printf("%8s %5u %5u %3d %4d %3s %-4s %-7s %s\n",
+ ki->ki_login,
+ ki->ki_pid,
+ ki->ki_ppid,
+ ki->ki_pri.pri_level, /* XXX check this */
+ ki->ki_nice,
+ vty,
+ pst,
+ wmesg,
+ buf);
+ i++;
+ }
+ free((void *)t);
+ exit(0);
+}
diff --git a/release/picobsd/tinyware/view/Makefile b/release/picobsd/tinyware/view/Makefile
new file mode 100644
index 0000000..b668613
--- /dev/null
+++ b/release/picobsd/tinyware/view/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG=view
+SRCS=view.c
+CFLAGS+=-I/usr/local/include
+LDADD+=-L/usr/local/lib -lpng -lvgl -lz -lm
+MAN=
+
+.include <bsd.prog.mk>
diff --git a/release/picobsd/tinyware/view/README b/release/picobsd/tinyware/view/README
new file mode 100644
index 0000000..df5f774
--- /dev/null
+++ b/release/picobsd/tinyware/view/README
@@ -0,0 +1,86 @@
+Warsaw, 1998.08.18
+
+ VIEW - small PNG viewer
+ -----------------------
+
+This program is intended to serve as a simple console viewer for PNG
+graphics. It also features some scripting abilities, which allow you to
+build simple presentation.
+
+In fact, using even this initial version I was able to build a nice
+presentation of PicoBSD abilities which I used in real-life situation (you
+can see for yourself one of the presentation's screens, fbsd.png).
+
+The audience was impressed :-), especially when I asked them politely what
+are requirements and cost to make that kind of presentation using M$
+products...
+
+Simple Viewing
+--------------
+
+Usage is as follows:
+
+ view [-g nnn.nnn] [-r x] filename.png
+
+where
+ -g nnn.nnn screen gamma (you can adjust how bright is the
+ picture)
+ -r x resolution:
+ 0 - 640x480x16
+ 1 - 640x200x256
+ 2 - 320x240x256
+
+Under right mouse button you can find a simple menu, which tells you also
+the hotkeys. You can shift, rotate and zoom the picture.
+
+Presentation
+------------
+
+Usage is as above, but the file you give as argument is a (unix) text file
+of the following format:
+
+ 1 VIEW SCRIPT
+ 2 5
+ 3 welcome.png
+ 4 /home/clipart/logo.png
+ 5 /home/present/title.png
+ 6 /home/present/outline.png
+ 7 /home/present/end.png
+
+(of course without the line numbering or the leading space!). The line number
+1 is magic, and must be present in order to recognize the file properly.
+
+The second line tells how many pictures consist the presentation. The
+following lines tell the file names containing the images themselves.
+
+See the example in file picobsd.vu.
+
+Command line arguments (gamma and resolution) are as above. You can also use
+the pop-up menu to adjust image parameters, as well as go forward or
+backward in the presentation.
+
+Bugs, caveats, missing features
+-------------------------------
+
+* there are some bugs in libvgl which require strange workarounds, and even
+ then it doesn't work quite right. See the source for the 'XXX' comments...
+
+* I didn't have time to add gamma adjustment to the pop-up menu. It's
+ simple, though, and I leave it as an exercise for the reader :-))
+
+* it would be great if someone would add GIF and jpeg support.
+
+* the error checking is probably weak. A bad PNG file or script file will
+ probably cause a coredump.
+
+* pop-up menu facilities need more abstraction to be usable in other cases.
+
+Anyway, as it is even now it's quite usable.
+
+Have fun!
+
+Andrzej Bialecki
+
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/view/fbsd.png b/release/picobsd/tinyware/view/fbsd.png
new file mode 100644
index 0000000..0c5d3ed
--- /dev/null
+++ b/release/picobsd/tinyware/view/fbsd.png
Binary files differ
diff --git a/release/picobsd/tinyware/view/picobsd.vu b/release/picobsd/tinyware/view/picobsd.vu
new file mode 100644
index 0000000..16a3630
--- /dev/null
+++ b/release/picobsd/tinyware/view/picobsd.vu
@@ -0,0 +1,9 @@
+VIEW SCRIPT
+7
+/png/logo.png
+/png/1.png
+/png/2.png
+/png/p1.png
+/png/p2.png
+/png/p3.png
+/png/p4.png
diff --git a/release/picobsd/tinyware/view/view.c b/release/picobsd/tinyware/view/view.c
new file mode 100644
index 0000000..2727ebe
--- /dev/null
+++ b/release/picobsd/tinyware/view/view.c
@@ -0,0 +1,619 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Small PNG viewer with scripting abilities
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/fbio.h>
+#include <sys/consio.h>
+#include <sys/mouse.h>
+#include <vgl.h>
+#include <png.h>
+
+#define NUMBER 8
+
+extern char *optarg;
+extern int optind;
+
+/* Prototypes */
+int kbd_action(int x, int y, char hotkey);
+
+struct action {
+ int zoom;
+ int rotate;
+ int Xshift,Yshift;
+};
+
+struct menu_item {
+ char *descr;
+ char hotkey;
+ int (*func)(int x, int y, char hotkey);
+};
+
+struct menu_item std_menu[]= {
+ {"q Quit",'q',kbd_action},
+ {"n Next",'n',kbd_action},
+ {"p Previous",'p',kbd_action},
+ {"Z Zoom in",'Z',kbd_action},
+ {"z Zoom out",'z',kbd_action},
+ {"r Rotate",'r',kbd_action},
+ {"R Refresh",'R',kbd_action},
+ {"l Left",'l',kbd_action},
+ {"h Right",'h',kbd_action},
+ {"j Up",'j',kbd_action},
+ {"k Down",'k',kbd_action},
+ {NULL,0,NULL}
+};
+
+char *progname;
+VGLBitmap pic,bkg;
+struct action a;
+byte pal_red[256];
+byte pal_green[256];
+byte pal_blue[256];
+byte pal_colors;
+double screen_gamma;
+int max_screen_colors=15;
+int quit,changed;
+char **pres;
+int nimg=0;
+int auto_chg=0;
+int cur_img=0;
+char act;
+FILE *log;
+
+void
+usage()
+{
+ fprintf(stderr,"\nVGL graphics viewer, 1.0 (c) Andrzej Bialecki.\n");
+ fprintf(stderr,"\nUsage:\n");
+ fprintf(stderr,"\t%s [-r n] [-g n.n] filename\n",progname);
+ fprintf(stderr,"\nwhere:\n");
+ fprintf(stderr,"\t-r n\tchoose resolution:\n");
+ fprintf(stderr,"\t\t0 - 640x480x16 (default)\n");
+ fprintf(stderr,"\t\t1 - 640x200x256\n");
+ fprintf(stderr,"\t\t2 - 320x240x256\n");
+ fprintf(stderr,"\t-g n.n\tset screen gamma (1.3 by default)\n");
+ fprintf(stderr,"\n");
+}
+
+int
+pop_up(char *title,int x, int y)
+{
+ VGLBitmap sav,clr;
+ int x1,y1,width,height,i,j;
+ int last_pos,cur_pos,max_item;
+ char buttons;
+ char *t;
+
+ sav.Type=VGLDisplay->Type;
+ clr.Type=VGLDisplay->Type;
+ width=0;
+ height=0;
+ max_item=0;
+ i=0;
+ while(std_menu[i].descr!=NULL) {
+ height++;
+ max_item++;
+ if(strlen(std_menu[i].descr)>width) width=strlen(std_menu[i].descr);
+ i++;
+ }
+ width=width*8+2;
+ height=height*9+4+8;
+ sav.Xsize=width;
+ sav.Ysize=height;
+ clr.Xsize=width;
+ clr.Ysize=height;
+ sav.Bitmap=(byte *)calloc(width*height,1);
+ clr.Bitmap=(byte *)calloc(width*height,1);
+ if(x>(VGLDisplay->Xsize-width)) x1=VGLDisplay->Xsize-width;
+ else x1=x;
+ if(y>(VGLDisplay->Ysize-height)) y1=VGLDisplay->Ysize-height;
+ else y1=y;
+ VGLMouseMode(VGL_MOUSEHIDE);
+ VGLBitmapCopy(VGLDisplay,x1,y1,&sav,0,0,width,height);
+ VGLFilledBox(VGLDisplay,x1,y1,x1+width-1,y1+height-1,pal_colors-1);
+ VGLBitmapString(VGLDisplay,x1+1,y1+1,title,0,pal_colors-1,0,0);
+ VGLLine(VGLDisplay,x1,y1+9,x1+width,y1+9,0);
+ i=0;
+ while(std_menu[i].descr!=NULL) {
+ VGLBitmapString(VGLDisplay,x1+1,y1+11+i*9,std_menu[i].descr,0,pal_colors-1,0,0);
+ i++;
+ }
+ last_pos=-1;
+ VGLMouseMode(VGL_MOUSESHOW);
+ do {
+ pause();
+ VGLMouseStatus(&x,&y,&buttons);
+ cur_pos=(y-y1-11)/9;
+ if((cur_pos<0)||(cur_pos>max_item-1)) {
+ if(last_pos==-1) last_pos=0;
+ VGLBitmapString(VGLDisplay,x1+1,y1+11+last_pos*9,std_menu[last_pos].descr,0,pal_colors-1,0,0);
+ last_pos=-1;
+ } else if(last_pos!=cur_pos) {
+ if(last_pos==-1) last_pos=0;
+ VGLBitmapString(VGLDisplay,x1+1,y1+11+last_pos*9,std_menu[last_pos].descr,0,pal_colors-1,0,0);
+ VGLBitmapString(VGLDisplay,x1+1,y1+11+cur_pos*9,std_menu[cur_pos].descr,pal_colors/2+1,pal_colors-1,0,0);
+ last_pos=cur_pos;
+ }
+ } while (buttons & MOUSE_BUTTON3DOWN);
+ VGLMouseMode(VGL_MOUSEHIDE);
+ /* XXX Screws up totally when r==3. Libvgl bug! */
+ VGLBitmapCopy(&clr,0,0,VGLDisplay,x1,y1,width,height);
+ VGLBitmapCopy(&sav,0,0,VGLDisplay,x1,y1,width,height);
+ VGLMouseMode(VGL_MOUSESHOW);
+ free(sav.Bitmap);
+ free(clr.Bitmap);
+ changed++;
+ if((cur_pos>=0) && (cur_pos<max_item)) {
+ std_menu[cur_pos].func(x,y,std_menu[cur_pos].hotkey);
+ }
+ changed++;
+ return(0);
+}
+
+void
+display( VGLBitmap *pic,
+ byte *red,
+ byte *green,
+ byte *blue,
+ struct action *e)
+{
+ VGLBitmap target;
+ int x,y,i=0,j=0;
+
+ VGLMouseMode(VGL_MOUSEHIDE);
+ VGLRestorePalette();
+ /* XXX Broken in r!=2. Libvgl bug. */
+ //VGLClear(VGLDisplay,0);
+ VGLBitmapCopy(&bkg,0,0,VGLDisplay,0,0,bkg.Xsize,bkg.Ysize);
+
+ if(e!=NULL) {
+ if(e->zoom!=1 || e->rotate) {
+ target.Bitmap=(byte *)calloc(pic->Xsize*pic->Ysize*e->zoom*e->zoom,1);
+ if(e->rotate) {
+ target.Xsize=pic->Ysize*e->zoom;
+ target.Ysize=pic->Xsize*e->zoom;
+ } else {
+ target.Xsize=pic->Xsize*e->zoom;
+ target.Ysize=pic->Ysize*e->zoom;
+ }
+ target.Type=pic->Type;
+ for(x=0;x<pic->Xsize;x++) {
+ for(y=0;y<pic->Ysize;y++) {
+ for(i=0;i<e->zoom;i++) {
+ for(j=0;j<e->zoom;j++) {
+ if(e->rotate) {
+ VGLSetXY(&target,target.Xsize-(e->zoom*y+i),e->zoom*x+j,VGLGetXY(pic,x,y));
+ } else {
+ VGLSetXY(&target,e->zoom*x+i,e->zoom*y+j,VGLGetXY(pic,x,y));
+ }
+ }
+ }
+ }
+ }
+ } else {
+ target.Bitmap=(byte *)calloc(pic->Xsize*pic->Ysize,sizeof(byte));
+ target.Xsize=pic->Xsize;
+ target.Ysize=pic->Ysize;
+ target.Type=pic->Type;
+ VGLBitmapCopy(pic,0,0,&target,0,0,pic->Xsize,pic->Ysize);
+ }
+ } else {
+ target.Bitmap=(byte *)calloc(pic->Xsize*pic->Ysize,sizeof(byte));
+ target.Xsize=pic->Xsize;
+ target.Ysize=pic->Ysize;
+ target.Type=pic->Type;
+ VGLBitmapCopy(pic,0,0,&target,0,0,pic->Xsize,pic->Ysize);
+ }
+ VGLSetPalette(red, green, blue);
+ if(e!=NULL) {
+ VGLBitmapCopy(&target,0,0,VGLDisplay,e->Xshift,e->Yshift,target.Xsize,target.Ysize);
+ } else {
+ VGLBitmapCopy(&target,0,0,VGLDisplay,0,0,target.Xsize,target.Ysize);
+ }
+ VGLMouseMode(VGL_MOUSESHOW);
+ free(target.Bitmap);
+}
+
+int
+png_load(char *filename)
+{
+ int i,j,k;
+ FILE *fd;
+ u_char header[NUMBER];
+ png_structp png_ptr;
+ png_infop info_ptr,end_info;
+ png_uint_32 width,height;
+ int bit_depth,color_type,interlace_type;
+ int compression_type,filter_type;
+ int channels,rowbytes;
+ double gamma;
+ png_colorp palette;
+ int num_palette;
+ png_bytep *row_pointers;
+ char c;
+ int res=0;
+
+ fd=fopen(filename,"rb");
+
+ if(fd==NULL) {
+ VGLEnd();
+ perror("fopen");
+ exit(1);
+ }
+ fread(header,1,NUMBER,fd);
+ if(!png_check_sig(header,NUMBER)) {
+ fprintf(stderr,"Not a PNG file.\n");
+ return(-1);
+ }
+ png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,(void *)NULL,
+ NULL,NULL);
+ info_ptr=png_create_info_struct(png_ptr);
+ end_info=png_create_info_struct(png_ptr);
+ if(!png_ptr || !info_ptr || !end_info) {
+ VGLEnd();
+ fprintf(stderr,"failed to allocate needed structs!\n");
+ png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
+ return(-1);
+ }
+ png_set_sig_bytes(png_ptr,NUMBER);
+ png_init_io(png_ptr,fd);
+ png_read_info(png_ptr,info_ptr);
+ png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,
+ &color_type,&interlace_type,&compression_type,&filter_type);
+ png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette);
+ channels=png_get_channels(png_ptr,info_ptr);
+ rowbytes=png_get_rowbytes(png_ptr,info_ptr);
+ if(bit_depth==16)
+ png_set_strip_16(png_ptr);
+ if(color_type & PNG_COLOR_MASK_ALPHA)
+ png_set_strip_alpha(png_ptr);
+ if(png_get_gAMA(png_ptr,info_ptr,&gamma))
+ png_set_gamma(png_ptr,screen_gamma,gamma);
+ else
+ png_set_gamma(png_ptr,screen_gamma,0.45);
+ if(res==0) {
+ /* Dither */
+ if(color_type & PNG_COLOR_MASK_COLOR) {
+ if(png_get_valid(png_ptr,info_ptr,PNG_INFO_PLTE)) {
+ png_uint_16p histogram;
+ png_get_hIST(png_ptr,info_ptr,&histogram);
+ png_set_dither(png_ptr,palette,num_palette,max_screen_colors,histogram,0);
+ } else {
+ png_color std_color_cube[16]={
+ {0x00,0x00,0x00},
+ {0x02,0x02,0x02},
+ {0x04,0x04,0x04},
+ {0x06,0x06,0x06},
+ {0x08,0x08,0x08},
+ {0x0a,0x0a,0x0a},
+ {0x0c,0x0c,0x0c},
+ {0x0e,0x0e,0x0e},
+ {0x10,0x10,0x10},
+ {0x12,0x12,0x12},
+ {0x14,0x14,0x14},
+ {0x16,0x16,0x16},
+ {0x18,0x18,0x18},
+ {0x1a,0x1a,0x1a},
+ {0x1d,0x1d,0x1d},
+ {0xff,0xff,0xff},
+ };
+ png_set_dither(png_ptr,std_color_cube,max_screen_colors,max_screen_colors,NULL,0);
+ }
+ }
+ }
+ png_set_packing(png_ptr);
+ if(png_get_valid(png_ptr,info_ptr,PNG_INFO_sBIT)) {
+ png_color_8p sig_bit;
+
+ png_get_sBIT(png_ptr,info_ptr,&sig_bit);
+ png_set_shift(png_ptr,sig_bit);
+ }
+ png_read_update_info(png_ptr,info_ptr);
+ png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,
+ &color_type,&interlace_type,&compression_type,&filter_type);
+ png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette);
+ channels=png_get_channels(png_ptr,info_ptr);
+ rowbytes=png_get_rowbytes(png_ptr,info_ptr);
+ row_pointers=malloc(height*sizeof(png_bytep));
+ for(i=0;i<height;i++) {
+ row_pointers[i]=malloc(rowbytes);
+ }
+ png_read_image(png_ptr,row_pointers);
+ png_read_end(png_ptr,end_info);
+ png_destroy_read_struct(&png_ptr,&info_ptr,&end_info);
+ fclose(fd);
+ /* Set palette */
+ if(res) k=2;
+ else k=2;
+ for(i=0;i<256;i++) {
+ pal_red[i]=255;
+ pal_green[i]=255;
+ pal_blue[i]=255;
+ }
+ for(i=0;i<num_palette;i++) {
+ pal_red[i]=(palette+i)->red>>k;
+ pal_green[i]=(palette+i)->green>>k;
+ pal_blue[i]=(palette+i)->blue>>k;
+ }
+ pal_colors=num_palette;
+ if(pic.Bitmap!=NULL) free(pic.Bitmap);
+ pic.Bitmap=(byte *)calloc(rowbytes*height,sizeof(byte));
+ pic.Type=MEMBUF;
+ pic.Xsize=rowbytes;
+ pic.Ysize=height;
+ for(i=0;i<rowbytes;i++) {
+ for(j=0;j<height;j++) {
+ VGLSetXY(&pic,
+ i,j,row_pointers[j][i]);
+ }
+ }
+ a.zoom=1;
+ a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2;
+ a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2;
+ a.rotate=0;
+ return(0);
+}
+
+void
+kbd_handler(int sig)
+{
+ u_char buf[10];
+ int res;
+
+ res=read(0,&buf,10);
+ changed++;
+ act=buf[res-1];
+}
+
+int
+kbd_action(int x, int y, char key)
+{
+ changed=0;
+ if(key!='n') auto_chg=0;
+ switch(key) {
+ case 'q':
+ quit=1;
+ break;
+ case 'Z':
+ a.zoom++;
+ changed++;
+ break;
+ case 'z':
+ a.zoom--;
+ if(a.zoom<1) a.zoom=1;
+ changed++;
+ break;
+ case 'l':
+ a.Xshift+=VGLDisplay->Xsize/5;
+ changed++;
+ break;
+ case 'h':
+ a.Xshift-=VGLDisplay->Xsize/5;
+ changed++;
+ break;
+ case 'k':
+ a.Yshift+=VGLDisplay->Ysize/5;
+ changed++;
+ break;
+ case 'j':
+ a.Yshift-=VGLDisplay->Ysize/5;
+ changed++;
+ break;
+ case 'R':
+ changed++;
+ break;
+ case 'r':
+ if(a.rotate) a.rotate=0;
+ else a.rotate=1;
+ changed++;
+ break;
+ case '\n':
+ case 'n':
+ if(nimg>0) {
+ if(cur_img<nimg-1) {
+ cur_img++;
+ } else {
+ cur_img=0;
+ }
+ png_load(pres[cur_img]);
+ changed++;
+ }
+ break;
+ case 'p':
+ if(nimg>0) {
+ if(cur_img>0) {
+ cur_img--;
+ } else {
+ cur_img=nimg-1;
+ }
+ png_load(pres[cur_img]);
+ changed++;
+ }
+ break;
+ }
+ act=0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i,j,k;
+ char c;
+ int res=0;
+ int x,y;
+ char buttons;
+ struct termios t_new,t_old;
+ FILE *fsc;
+
+ char buf[100];
+
+ progname=argv[0];
+ screen_gamma=1.5;
+#ifdef DEBUG
+ log=fopen("/png/view.log","w");
+#endif
+ while((c=getopt(argc,argv,"r:g:"))!=-1) {
+ switch(c) {
+ case 'r':
+ res=atoi(optarg);
+ if(res>0) max_screen_colors=256;
+ break;
+ case 'g':
+ screen_gamma=atof(optarg);
+ break;
+ case '?':
+ default:
+ usage();
+ exit(0);
+ }
+ }
+ switch(res) {
+ case 0:
+ VGLInit(SW_CG640x480);
+ break;
+ case 1:
+ VGLInit(SW_VGA_CG320);
+ break;
+ case 2:
+ VGLInit(SW_VGA_MODEX);
+ break;
+ default:
+ fprintf(stderr,"No such resolution!\n");
+ usage();
+ exit(-1);
+ }
+#ifdef DEBUG
+ fprintf(log,"VGL initialised\n");
+#endif
+ VGLSavePalette();
+ if(argc>optind) {
+ res=png_load(argv[optind]);
+ } else {
+ VGLEnd();
+ usage();
+ exit(0);
+ }
+ if(res) {
+ /* Hmm... Script? */
+ fsc=fopen(argv[optind],"r");
+#ifdef DEBUG
+ fprintf(log,"Trying script %s\n",argv[optind]);
+#endif
+ fgets(buf,99,fsc);
+ buf[strlen(buf)-1]='\0';
+ if(strncmp("VIEW SCRIPT",buf,11)!=NULL) {
+ VGLEnd();
+ usage();
+ }
+ if(strlen(buf)>12) {
+ auto_chg=atoi(buf+12);
+ }
+ fgets(buf,99,fsc);
+ buf[strlen(buf)-1]='\0';
+ nimg=atoi(buf);
+ if(nimg==0) {
+ VGLEnd();
+ usage();
+ }
+ pres=(char **)calloc(nimg,sizeof(char *));
+ for(i=0;i<nimg;i++) {
+ fgets(buf,99,fsc);
+ buf[strlen(buf)-1]='\0';
+ pres[i]=strdup(buf);
+ }
+ fclose(fsc);
+ cur_img=0;
+#ifdef DEBUG
+ fprintf(log,"Script with %d entries\n",nimg);
+#endif
+ png_load(pres[cur_img]);
+ }
+ VGLMouseInit(VGL_MOUSEHIDE);
+ /* Prepare the keyboard */
+ tcgetattr(0,&t_old);
+ memcpy(&t_new,&t_old,sizeof(struct termios));
+ cfmakeraw(&t_new);
+ tcsetattr(0,TCSAFLUSH,&t_new);
+ fcntl(0,F_SETFL,O_ASYNC);
+ /* XXX VGLClear doesn't work.. :-(( Prepare a blank background */
+ bkg.Bitmap=(byte *)calloc(VGLDisplay->Xsize*VGLDisplay->Ysize,1);
+ bkg.Xsize=VGLDisplay->Xsize;
+ bkg.Ysize=VGLDisplay->Ysize;
+ bkg.Type=VGLDisplay->Type;
+ signal(SIGIO,kbd_handler);
+ a.zoom=1;
+ a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2;
+ a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2;
+ a.rotate=0;
+ quit=0;
+ changed=0;
+ display(&pic,pal_red,pal_green,pal_blue,&a);
+ while(!quit) {
+ if(act) {
+#ifdef DEBUG
+ fprintf(log,"kbd_action(%c)\n",act);
+#endif
+ kbd_action(x,y,act);
+ }
+ if(quit) break;
+ if(changed) {
+#ifdef DEBUG
+ fprintf(log,"changed, redisplaying\n");
+#endif
+ display(&pic,pal_red,pal_green,pal_blue,&a);
+ changed=0;
+ }
+ if(auto_chg) {
+ sleep(auto_chg);
+ kbd_action(x,y,'n');
+ } else {
+ pause();
+ }
+ VGLMouseStatus(&x,&y,&buttons);
+ if(buttons & MOUSE_BUTTON3DOWN) {
+#ifdef DEBUG
+ fprintf(log,"pop_up called\n");
+#endif
+ pop_up("View",x,y);
+ }
+ }
+ VGLEnd();
+#ifdef DEBUG
+ fclose(log);
+#endif
+ exit(0);
+}
diff --git a/release/picobsd/tinyware/vm/Makefile b/release/picobsd/tinyware/vm/Makefile
new file mode 100644
index 0000000..193710e
--- /dev/null
+++ b/release/picobsd/tinyware/vm/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+#
+PROG=vm
+#CFLAGS+=
+SRCS= vm.c
+MAN=
+
+.include <bsd.prog.mk>
+
+
diff --git a/release/picobsd/tinyware/vm/README b/release/picobsd/tinyware/vm/README
new file mode 100644
index 0000000..c4a940c
--- /dev/null
+++ b/release/picobsd/tinyware/vm/README
@@ -0,0 +1,10 @@
+1998.02.12
+
+This is a small replacement for vmstat(8) program. It allows you to measure
+current memory utilisation. The same info is available via sysctl(8) program,
+but unfortunately this particular variable doesn't have its handler, and
+consequently it is not displayed in stock version of sysctl(8).
+
+<abial@freebsd.org>
+
+$FreeBSD$
diff --git a/release/picobsd/tinyware/vm/vm.c b/release/picobsd/tinyware/vm/vm.c
new file mode 100644
index 0000000..90bb8dd
--- /dev/null
+++ b/release/picobsd/tinyware/vm/vm.c
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 1998 Andrzej Bialecki
+ * 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.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+#include <vm/vm_param.h>
+
+#define pgtok(a) ((a) * (u_int) pagesize >> 10)
+
+int
+vm_i()
+{
+#define CNT 49
+ int cnt[CNT];
+ char names[CNT*16];
+ char *a, *namep[CNT*16];
+ int i,len;
+ long long inttotal=0;
+ long uptime=1;
+
+ len=sizeof(cnt);
+ i = sysctlbyname("hw.intrcnt", &cnt, &len, NULL, 0);
+ if (i != 0)
+ return i ;
+ len=sizeof(names);
+ i = sysctlbyname("hw.intrnames", &names, &len, NULL, 0);
+ if (i != 0)
+ return i ;
+
+ for( i=0, a = names ; i < CNT && a < names+sizeof(names) ; ) {
+ namep[i++] = a++;
+ while (a < names+sizeof(names) && *a)
+ a++ ;
+ a++ ; /* skip \0 */
+ }
+ printf("interrupt total rate\n");
+ inttotal = 0;
+ for (i=0; i< CNT ; i++)
+ if (cnt[i] >0) {
+ printf("%-12s %20lu %10lu\n", namep[i], cnt[i], cnt[i]/uptime);
+ inttotal += cnt[i];
+ }
+ printf("Total %20llu %10llu\n", inttotal,
+ inttotal / (u_int64_t) uptime);
+ return 0;
+}
+int
+main(int argc, char *argv[])
+{
+ int mib[2],i=0,len;
+ int pagesize, pagesize_len;
+ struct vmtotal v;
+
+ if (argc > 1 && !strcmp(argv[1], "-i")) {
+ if (vm_i())
+ fprintf(stderr, "vm -i stats not available via sysctl\n");
+ return 0 ;
+ }
+ pagesize_len = sizeof(int);
+ sysctlbyname("vm.stats.vm.v_page_size",&pagesize,&pagesize_len,NULL,0);
+
+ len=sizeof(struct vmtotal);
+ mib[0]=CTL_VM;
+ mib[1]=VM_METER;
+ for(;;) {
+ sysctl(mib,2,&v,&len,NULL,0);
+ if(i==0) {
+ printf(" procs kB virt mem real mem shared vm shared real free\n");
+ printf(" r w l s tot act tot act tot act tot act\n");
+ }
+ printf("%2hd%2hd%2hd%2hd",v.t_rq-1,v.t_dw+v.t_pw,v.t_sl,v.t_sw);
+ printf("%7d %7d %7d%7d",
+ pgtok(v.t_vm),pgtok(v.t_avm),
+ pgtok(v.t_rm),pgtok(v.t_arm));
+ printf("%7d%7d%7d%7d%7d\n",
+ pgtok(v.t_vmshr),pgtok(v.t_avmshr),
+ pgtok(v.t_rmshr),pgtok(v.t_armshr),
+ pgtok(v.t_free));
+ sleep(5);
+ i++;
+ if(i>22) i=0;
+ }
+ exit(0);
+
+}
diff --git a/release/pkg_repos/release-dvd.conf b/release/pkg_repos/release-dvd.conf
new file mode 100644
index 0000000..9541359
--- /dev/null
+++ b/release/pkg_repos/release-dvd.conf
@@ -0,0 +1,8 @@
+# $FreeBSD$
+release: {
+ url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
+ mirror_type: "srv",
+ signature_type: "fingerprints",
+ fingerprints: "/usr/share/keys/pkg",
+ enabled: yes
+}
diff --git a/release/powerpc/boot.tbxi b/release/powerpc/boot.tbxi
new file mode 100644
index 0000000..7089786
--- /dev/null
+++ b/release/powerpc/boot.tbxi
@@ -0,0 +1,15 @@
+<CHRP-BOOT>
+<LICENSE>
+$FreeBSD$
+</LICENSE>
+<COMPATIBLE>
+MacRISC MacRISC3 MacRISC4
+</COMPATIBLE>
+<DESCRIPTION>
+FreeBSD/PPC bootloader
+</DESCRIPTION>
+<BOOT-SCRIPT>
+" screen" output
+boot cd:,\boot\loader cd:0
+</BOOT-SCRIPT>
+</CHRP-BOOT>
diff --git a/release/powerpc/generate-hfs.sh b/release/powerpc/generate-hfs.sh
new file mode 100755
index 0000000..c445fea
--- /dev/null
+++ b/release/powerpc/generate-hfs.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+# This script generates the dummy HFS filesystem used for the PowerPC boot
+# blocks. It uses hfsutils (emulators/hfsutils) to generate a template
+# filesystem with the relevant interesting files. These are then found by
+# grep, and the offsets written to a Makefile snippet.
+#
+# Because of licensing concerns, and because it is overkill, we do not
+# distribute hfsutils as a build tool. If you need to regenerate the HFS
+# template (e.g. because the boot block or the CHRP script have grown),
+# you must install it from ports.
+
+# $FreeBSD$
+
+HFS_SIZE=400 #Size in 2048-byte blocks of the produced image
+LOADER_SIZE=300k
+
+# Generate 800K HFS image
+OUTPUT_FILE=hfs-boot
+
+dd if=/dev/zero of=$OUTPUT_FILE bs=2048 count=$HFS_SIZE
+hformat -l "FreeBSD Install" $OUTPUT_FILE
+hmount $OUTPUT_FILE
+
+# Create and bless a directory for the boot loader
+hmkdir ppc
+hattrib -b ppc
+hcd ppc
+
+# Make the CHRP boot script, which gets loader from the ISO9660 partition
+cat > bootinfo.txt << EOF
+<CHRP-BOOT>
+<DESCRIPTION>FreeBSD/powerpc bootloader</DESCRIPTION>
+<OS-NAME>FreeBSD</OS-NAME>
+<VERSION> $FreeBSD: head/sys/boot/powerpc/boot1.chrp/bootinfo.txt 184490 2008-10
+-31 00:52:31Z nwhitehorn $ </VERSION>
+
+<COMPATIBLE>
+MacRISC MacRISC3 MacRISC4
+</COMPATIBLE>
+<BOOT-SCRIPT>
+" screen" output
+boot &device;:,\ppc\loader &device;:0
+</BOOT-SCRIPT>
+</CHRP-BOOT>
+EOF
+echo 'Loader START' | dd of=loader.tmp cbs=$LOADER_SIZE count=1 conv=block
+
+hcopy bootinfo.txt :bootinfo.txt
+hcopy loader.tmp :loader
+hattrib -c chrp -t tbxi bootinfo.txt
+humount
+
+rm bootinfo.txt
+rm loader.tmp
+
+bzip2 $OUTPUT_FILE
+echo 'HFS boot filesystem created by generate-hfs.sh' > $OUTPUT_FILE.bz2.uu
+echo 'DO NOT EDIT' >> $OUTPUT_FILE.bz2.uu
+echo '$FreeBSD$' >> $OUTPUT_FILE.bz2.uu
+
+uuencode $OUTPUT_FILE.bz2 $OUTPUT_FILE.bz2 >> $OUTPUT_FILE.bz2.uu
+rm $OUTPUT_FILE.bz2
+
diff --git a/release/powerpc/hfs-boot.bz2.uu b/release/powerpc/hfs-boot.bz2.uu
new file mode 100644
index 0000000..2113a7b
--- /dev/null
+++ b/release/powerpc/hfs-boot.bz2.uu
@@ -0,0 +1,23 @@
+HFS boot filesystem created by generate-hfs.sh
+DO NOT EDIT
+$FreeBSD$
+begin 644 hfs-boot.bz2
+M0EIH.3%!62936=#$Y.(``"___?_O_G)7!_Y]OW??5#]U_^!`0`,@1`!!``!@
+M(0!`3,`"L"4.2U"2(H9%/:*>TFDVU3RGZID'J&C3U,@T-&@`/1!H>IZC1D#(
+M`D24TTRFC1D]*;$@!IZ@Q!IH-````#0&33":?J@<:&AH:`:`Q`T!D``&F@`:
+M`9````PDI1J>0Q,H/1J&@```!D-`````T-``#SZHHR(+Y*Y9J*Z:4KK=T]W@
+M4RV\LG/;0XDPC7^`9DO3/3&*].462T,NO#AA9C,O\0!)^Q@@S6";2`!);<W\
+MM\)T,GR:I$-V("3$9$B"&8,,*RS@L++(8KPP)-C!L0(22AH:=29JC18OSD@O
+M&&`F8@M#$H:5#;%`Q)(22DF(/IB46IH0H?):$7!BU_SU=DL`+E*J,;0?%AW6
+M#\-_#^NL++6(CI"!)*#8N/S2"7!C_QAB8[(ZW3G$\`G81HL8.H^M8?#(Z"JL
+M;J^PI=+>?8(B6BR1(-7Q*8?>>HPQSBQE>M$A9K6FFW<:#6[D931J%U.F8*`0
+MD(,M80A(0;]K'X'SI]G(C)Y).AK_/0)D(2$$]JB$]]F').M4RF8O%[IHK[0O
+MMQ?'>O[U8EM;>U<P%^7)&#;>",KY^*%FO9C05_435?.4*F[6AIL%&9C<9W&&
+M[ZMP(TG!'*4Z>@6TM)0BS.D._O,WR9OJ728V48I;DD=8QGBE7J-&L^?=0JEF
+MV2`B/)/D\)83IS@32(;!P,152U()0VGQH>2F$UC:M!D5`F#1W$\:KKDR[TQB
+MN;N<J=4-1'[HLG,!L^IJG53+[IORM_L7JB/:/<+:634`XD.R'",=M$A;C4E.
+M$RRHL2;B)D:_ZJVK$Z*40?H'TATSF5$$%L@<LB4`\2$P90.50PWE:'REG6\D
+ML%>5B1;P!7:AG#1BP2%-Q$7I6QE,Y?NHIK_LR+HA]22HW0.8(^G4/X`Z@!Z6
+8#PQ(0))/`A(0.'VUG_\7<D4X4)#0Q.3B
+`
+end
diff --git a/release/powerpc/make-memstick.sh b/release/powerpc/make-memstick.sh
new file mode 100755
index 0000000..4f6b69d
--- /dev/null
+++ b/release/powerpc/make-memstick.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# This script generates a "memstick image" (image that can be copied to a
+# USB memory stick) from a directory tree. Note that the script does not
+# clean up after itself very well for error conditions on purpose so the
+# problem can be diagnosed (full filesystem most likely but ...).
+#
+# Usage: make-memstick.sh <directory tree> <image filename>
+#
+# $FreeBSD$
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+BLOCKSIZE=10240
+
+if [ $# -ne 2 ]; then
+ echo "make-memstick.sh /path/to/directory /path/to/image/file"
+ exit 1
+fi
+
+tempfile="${2}.$$"
+
+if [ ! -d ${1} ]; then
+ echo "${1} must be a directory"
+ exit 1
+fi
+
+if [ -e ${2} ]; then
+ echo "won't overwrite ${2}"
+ exit 1
+fi
+
+echo '/dev/da0s3 / ufs ro,noatime 1 1' > ${1}/etc/fstab
+rm -f ${tempfile}
+makefs -B big ${tempfile} ${1}
+if [ $? -ne 0 ]; then
+ echo "makefs failed"
+ exit 1
+fi
+rm ${1}/etc/fstab
+
+mkimg -s apm -p freebsd-boot:=${1}/boot/boot1.hfs -p freebsd-ufs/FreeBSD_Install:=${tempfile} -o ${2}
+
+rm -f ${tempfile}
+
diff --git a/release/powerpc/mkisoimages.sh b/release/powerpc/mkisoimages.sh
new file mode 100644
index 0000000..c92072d
--- /dev/null
+++ b/release/powerpc/mkisoimages.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# Module: mkisoimages.sh
+# Author: Jordan K Hubbard
+# Date: 22 June 2001
+#
+# $FreeBSD$
+#
+# This script is used by release/Makefile to build the (optional) ISO images
+# for a FreeBSD release. It is considered architecture dependent since each
+# platform has a slightly unique way of making bootable CDs. This script
+# is also allowed to generate any number of images since that is more of
+# publishing decision than anything else.
+#
+# Usage:
+#
+# mkisoimages.sh [-b] image-label image-name base-bits-dir [extra-bits-dir]
+#
+# Where -b is passed if the ISO image should be made "bootable" by
+# whatever standards this architecture supports (may be unsupported),
+# image-label is the ISO image label, image-name is the filename of the
+# resulting ISO image, base-bits-dir contains the image contents and
+# extra-bits-dir, if provided, contains additional files to be merged
+# into base-bits-dir as part of making the image.
+
+if [ "x$1" = "x-b" ]; then
+ # Apple boot code
+ uudecode -o /tmp/hfs-boot-block.bz2 "`dirname "$0"`/hfs-boot.bz2.uu"
+ bzip2 -d /tmp/hfs-boot-block.bz2
+ OFFSET=$(hd /tmp/hfs-boot-block | grep 'Loader START' | cut -f 1 -d ' ')
+ OFFSET=0x$(echo 0x$OFFSET | awk '{printf("%x\n",$1/512);}')
+ dd if="$4/boot/loader" of=/tmp/hfs-boot-block seek=$OFFSET conv=notrunc
+
+ bootable="-o bootimage=macppc;/tmp/hfs-boot-block -o no-emul-boot"
+
+ # pSeries/PAPR boot code
+ mkdir -p "$4/ppc/chrp"
+ cp "$4/boot/loader" "$4/ppc/chrp"
+ cat > "$4/ppc/bootinfo.txt" << EOF
+<chrp-boot>
+<description>FreeBSD Install</description>
+<os-name>FreeBSD</os-name>
+<boot-script>boot &device;:,\ppc\chrp\loader</boot-script>
+</chrp-boot>
+EOF
+ bootable="$bootable -o chrp-boot"
+
+ # Playstation 3 boot code
+ echo "FreeBSD Install='/boot/loader.ps3'" > "$4/etc/kboot.conf"
+
+ shift
+else
+ bootable=""
+fi
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 [-b] image-label image-name base-bits-dir [extra-bits-dir]"
+ exit 1
+fi
+
+LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift
+NAME="$1"; shift
+
+publisher="The FreeBSD Project. http://www.FreeBSD.org/"
+echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$1/etc/fstab"
+makefs -t cd9660 $bootable -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME" "$@"
+rm "$1/etc/fstab"
+rm /tmp/hfs-boot-block
+rm -rf "$1/ppc"
diff --git a/release/rc.local b/release/rc.local
new file mode 100755
index 0000000..cb44227
--- /dev/null
+++ b/release/rc.local
@@ -0,0 +1,93 @@
+#!/bin/sh
+# $FreeBSD$
+
+: ${DIALOG_OK=0}
+: ${DIALOG_CANCEL=1}
+: ${DIALOG_HELP=2}
+: ${DIALOG_EXTRA=3}
+: ${DIALOG_ITEM_HELP=4}
+: ${DIALOG_ESC=255}
+
+MACHINE=`uname -m`
+
+# resolv.conf from DHCP ends up in here, so make sure the directory exists
+mkdir /tmp/bsdinstall_etc
+
+kbdcontrol -d >/dev/null 2>&1
+if [ $? -eq 0 ]; then
+ # Syscons: use xterm, start interesting things on other VTYs
+ if [ ${MACHINE} = "pc98" ]; then
+ TERM=cons25w
+ else
+ TERM=xterm
+ fi
+
+ # Don't send ESC on function-key 62/63 (left/right command key)
+ kbdcontrol -f 62 '' > /dev/null 2>&1
+ kbdcontrol -f 63 '' > /dev/null 2>&1
+
+ if [ -z "$EXTERNAL_VTY_STARTED" ]; then
+ # Init will clean these processes up if/when the system
+ # goes multiuser
+ touch /tmp/bsdinstall_log
+ tail -f /tmp/bsdinstall_log > /dev/ttyv2 &
+ /usr/libexec/getty autologin ttyv3 &
+ EXTERNAL_VTY_STARTED=1
+ fi
+else
+ # Serial or other console
+ echo
+ echo "Welcome to FreeBSD!"
+ echo
+ echo "Please choose the appropriate terminal type for your system."
+ echo "Common console types are:"
+ echo " ansi Standard ANSI terminal"
+ echo " vt100 VT100 or compatible terminal"
+ echo " xterm xterm terminal emulator (or compatible)"
+ echo " cons25w cons25w terminal"
+ echo
+ echo -n "Console type [vt100]: "
+ read TERM
+ TERM=${TERM:-vt100}
+fi
+export TERM
+
+if [ -f /etc/installerconfig ]; then
+ if bsdinstall script /etc/installerconfig; then
+ dialog --backtitle "FreeBSD Installer" --title "Complete" --no-cancel --ok-label "Reboot" --pause "Installation of FreeBSD complete! Rebooting in 10 seconds" 10 30 10
+ reboot
+ else
+ dialog --backtitle "FreeBSD Installer" --title "Error" --textbox /tmp/bsdinstall_log 0 0
+ fi
+ exit
+fi
+
+dialog --backtitle "FreeBSD Installer" --title "Welcome" --extra-button --extra-label "Shell" --ok-label "Install" --cancel-label "Live CD" --yesno "Welcome to FreeBSD! Would you like to begin an installation or use the live CD?" 0 0
+
+case $? in
+$DIALOG_OK) # Install
+ # If not netbooting, have the installer configure the network
+ dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
+ if [ ${dlv:=0} -eq 0 -a ! -f /etc/diskless ]; then
+ BSDINSTALL_CONFIGCURRENT=yes; export BSDINSTALL_CONFIGCURRENT
+ fi
+
+ trap true SIGINT # Ignore cntrl-C here
+ bsdinstall
+ if [ $? -eq 0 ]; then
+ dialog --backtitle "FreeBSD Installer" --title "Complete" --yes-label "Reboot" --no-label "Live CD" --yesno "Installation of FreeBSD complete! Would you like to reboot into the installed system now?" 0 0 && reboot
+ else
+ . /etc/rc.local
+ fi
+ ;;
+$DIALOG_CANCEL) # Live CD
+ exit 0
+ ;;
+$DIALOG_EXTRA) # Shell
+ clear
+ echo "When finished, type 'exit' to return to the installer."
+ /bin/sh
+ . /etc/rc.local
+ ;;
+esac
+
diff --git a/release/release.conf.sample b/release/release.conf.sample
new file mode 100644
index 0000000..9542df3
--- /dev/null
+++ b/release/release.conf.sample
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+## Redefine environment variables here to override prototypes
+## defined in release.sh.
+#load_chroot_env() { }
+#load_target_env() { }
+#buildenv_setup() { }
+
+## Set the directory within which the release will be built.
+CHROOTDIR="/scratch"
+
+## Set the svn host.
+SVNROOT="svn://svn.FreeBSD.org/"
+
+## Set the src/, ports/, and doc/ branches or tags.
+SRCBRANCH="base/head@rHEAD"
+DOCBRANCH="doc/head@rHEAD"
+PORTBRANCH="ports/head@rHEAD"
+
+## Run svn co --force for src checkout.
+#SRC_FORCE_CHECKOUT=yes
+
+## Sample configuration for using git instead of svn.
+#VCSCMD="/usr/local/bin/git clone --branch master"
+#SVNROOT=""
+#SRCBRANCH="https://github.com/freebsd/freebsd"
+#DOCBRANCH="https://github.com/freebsd/freebsd-doc"
+#PORTBRANCH="https://github.com/freebsd/freebsd-ports"
+
+## Set to override the default target architecture.
+#TARGET="amd64"
+#TARGET_ARCH="amd64"
+#KERNEL="GENERIC"
+## Multiple kernels may be set.
+#KERNEL="GENERIC XENHVM"
+
+## Set to specify a custom make.conf and/or src.conf
+#MAKE_CONF="/etc/local/make.conf"
+#SRC_CONF="/etc/local/src.conf"
+
+## Set to use make(1) flags.
+#MAKE_FLAGS="-s"
+
+## Set to use world- and kernel-specific make(1) flags.
+#WORLD_FLAGS="-j $(sysctl -n hw.ncpu)"
+#KERNEL_FLAGS="-j $(( $(( $(sysctl -n hw.ncpu) + 1 )) / 2 ))"
+
+## Set miscellaneous 'make release' settings.
+#NODOC=
+#NOPORTS=
+#WITH_DVD=
+#WITH_COMPRESSED_IMAGES=
+
+## Set to '1' to disable multi-threaded xz(1) compression.
+#XZ_THREADS=0
+
+## Set when building embedded images.
+#EMBEDDEDBUILD=
+
+## Set to skip the chroot environment buildworld/installworld/distribution
+## step if it is expected the build environment will exist via alternate
+## means.
+#CHROOTBUILD_SKIP=
+
+## Set to a non-empty value skip checkout or update of /usr/src in
+## the chroot. This is intended for use when /usr/src already exists.
+#SRC_UPDATE_SKIP=
+
+## Set to a non-empty value skip checkout or update of /usr/doc in
+## the chroot. This is intended for use when /usr/doc already exists.
+#DOC_UPDATE_SKIP=
+
+## Set to a non-empty value skip checkout or update of /usr/ports in
+## the chroot. This is intended for use when /usr/ports already exists.
+#PORTS_UPDATE_SKIP=
+
+## Set to pass additional flags to make(1) for the build chroot setup, such
+## as TARGET/TARGET_ARCH.
+#CHROOT_MAKEENV=
+
+## Set to a non-empty value to build virtual machine images as part of the
+## release build.
+#WITH_VMIMAGES=
+
+## Set to a non-empty value to compress virtual machine images with xz(1)
+## as part of the release build.
+#WITH_COMPRESSED_VMIMAGES=
+
+## If WITH_VMIMAGES is set to a non-empty value, this is the name of the
+## file to use for the installed userland/kernel.
+#VMBASE="vm"
+
+## If WITH_VMIMAGES is set to a non-empty value, this is the size of the
+## virtual machine disk filesystem. Valid size values are described in
+## the truncate(1) manual page.
+#VMSIZE="20G"
+
+## If WITH_VMIMAGES is set to a non-empty value, this is a list of disk
+## image formats to create. Valid values are listed in the mkimg(1)
+## manual page, as well as 'mkimg --formats' output.
+#VMFORMATS="vhdf vmdk qcow2 raw"
+
+## Set to a non-empty value to build virtual machine images for various
+## cloud providers as part of the release build.
+#WITH_CLOUDWARE=
+
+## If WITH_CLOUDWARE is set to a non-empty value, this is a list of providers
+## to create disk images.
+#CLOUDWARE="AZURE OPENSTACK"
diff --git a/release/release.sh b/release/release.sh
new file mode 100755
index 0000000..313a16c
--- /dev/null
+++ b/release/release.sh
@@ -0,0 +1,406 @@
+#!/bin/sh
+#-
+# Copyright (c) 2013-2015 The FreeBSD Foundation
+# Copyright (c) 2013 Glen Barber
+# Copyright (c) 2011 Nathan Whitehorn
+# All rights reserved.
+#
+# Portions of this software were developed by Glen Barber
+# under sponsorship from the FreeBSD Foundation.
+#
+# 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.
+#
+# release.sh: check out source trees, and build release components with
+# totally clean, fresh trees.
+# Based on release/generate-release.sh written by Nathan Whitehorn
+#
+# $FreeBSD$
+#
+
+export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"
+
+VERSION=2
+
+# Prototypes that can be redefined per-chroot or per-target.
+load_chroot_env() { }
+load_target_env() { }
+buildenv_setup() { }
+
+usage() {
+ echo "Usage: $0 [-c release.conf]"
+ exit 1
+}
+
+# env_setup(): Set up the default build environment variables, such as the
+# CHROOTDIR, VCSCMD, SVNROOT, etc. This is called before the release.conf
+# file is sourced, if '-c <release.conf>' is specified.
+env_setup() {
+ # The directory within which the release will be built.
+ CHROOTDIR="/scratch"
+ RELENGDIR="$(dirname $(realpath ${0}))"
+
+ # The default version control system command to obtain the sources.
+ for _dir in /usr/bin /usr/local/bin; do
+ for _svn in svn svnlite; do
+ [ -x "${_dir}/${_svn}" ] && VCSCMD="${_dir}/${_svn}"
+ [ ! -z "${VCSCMD}" ] && break 2
+ done
+ done
+ VCSCMD="${VCSCMD} checkout"
+
+ # The default svn checkout server, and svn branches for src/, doc/,
+ # and ports/.
+ SVNROOT="svn://svn.FreeBSD.org/"
+ SRCBRANCH="base/head@rHEAD"
+ DOCBRANCH="doc/head@rHEAD"
+ PORTBRANCH="ports/head@rHEAD"
+
+ # Set for embedded device builds.
+ EMBEDDEDBUILD=
+
+ # Sometimes one needs to checkout src with --force svn option.
+ # If custom kernel configs copied to src tree before checkout, e.g.
+ SRC_FORCE_CHECKOUT=
+
+ # The default make.conf and src.conf to use. Set to /dev/null
+ # by default to avoid polluting the chroot(8) environment with
+ # non-default settings.
+ MAKE_CONF="/dev/null"
+ SRC_CONF="/dev/null"
+
+ # The number of make(1) jobs, defaults to the number of CPUs available
+ # for buildworld, and half of number of CPUs available for buildkernel.
+ WORLD_FLAGS="-j$(sysctl -n hw.ncpu)"
+ KERNEL_FLAGS="-j$(( $(( $(sysctl -n hw.ncpu) + 1 )) / 2))"
+
+ MAKE_FLAGS="-s"
+
+ # The name of the kernel to build, defaults to GENERIC.
+ KERNEL="GENERIC"
+
+ # Set to non-empty value to disable checkout of doc/ and/or ports/.
+ # Disabling ports/ checkout also forces NODOC to be set.
+ NODOC=
+ NOPORTS=
+
+ # Set to non-empty value to build dvd1.iso as part of the release.
+ WITH_DVD=
+ WITH_COMPRESSED_IMAGES=
+
+ # Set to non-empty value to build virtual machine images as part of
+ # the release.
+ WITH_VMIMAGES=
+ WITH_COMPRESSED_VMIMAGES=
+ XZ_THREADS=0
+
+ # Set to non-empty value to build virtual machine images for various
+ # cloud providers as part of the release.
+ WITH_CLOUDWARE=
+
+ return 0
+} # env_setup()
+
+# env_check(): Perform sanity tests on the build environment, such as ensuring
+# files/directories exist, as well as adding backwards-compatibility hacks if
+# necessary. This is called unconditionally, and overrides the defaults set
+# in env_setup() if '-c <release.conf>' is specified.
+env_check() {
+ chroot_build_release_cmd="chroot_build_release"
+ # Fix for backwards-compatibility with release.conf that does not have
+ # the trailing '/'.
+ case ${SVNROOT} in
+ *svn*)
+ SVNROOT="${SVNROOT}/"
+ ;;
+ *)
+ ;;
+ esac
+
+ # Prefix the branches with the SVNROOT for the full checkout URL.
+ SRCBRANCH="${SVNROOT}${SRCBRANCH}"
+ DOCBRANCH="${SVNROOT}${DOCBRANCH}"
+ PORTBRANCH="${SVNROOT}${PORTBRANCH}"
+
+ if [ -n "${EMBEDDEDBUILD}" ]; then
+ WITH_DVD=
+ WITH_COMPRESSED_IMAGES=
+ NODOC=yes
+ case ${EMBEDDED_TARGET}:${EMBEDDED_TARGET_ARCH} in
+ arm:armv6)
+ chroot_build_release_cmd="chroot_arm_armv6_build_release"
+ ;;
+ *)
+ esac
+ fi
+
+ # If PORTS is set and NODOC is unset, force NODOC=yes because the ports
+ # tree is required to build the documentation set.
+ if [ -n "${NOPORTS}" ] && [ -z "${NODOC}" ]; then
+ echo "*** NOTICE: Setting NODOC=1 since ports tree is required"
+ echo " and NOPORTS is set."
+ NODOC=yes
+ fi
+
+ # If NOPORTS and/or NODOC are unset, they must not pass to make as
+ # variables. The release makefile verifies definedness of the
+ # NOPORTS/NODOC variables instead of their values.
+ DOCPORTS=
+ if [ -n "${NOPORTS}" ]; then
+ DOCPORTS="NOPORTS=yes "
+ fi
+ if [ -n "${NODOC}" ]; then
+ DOCPORTS="${DOCPORTS}NODOC=yes"
+ fi
+
+ # The aggregated build-time flags based upon variables defined within
+ # this file, unless overridden by release.conf. In most cases, these
+ # will not need to be changed.
+ CONF_FILES="__MAKE_CONF=${MAKE_CONF} SRCCONF=${SRC_CONF}"
+ if [ -n "${TARGET}" ] && [ -n "${TARGET_ARCH}" ]; then
+ ARCH_FLAGS="TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH}"
+ else
+ ARCH_FLAGS=
+ fi
+ # Force src checkout if configured
+ FORCE_SRC_KEY=
+ if [ -n "${SRC_FORCE_CHECKOUT}" ]; then
+ FORCE_SRC_KEY="--force"
+ fi
+
+ if [ -z "${CHROOTDIR}" ]; then
+ echo "Please set CHROOTDIR."
+ exit 1
+ fi
+
+ if [ $(id -u) -ne 0 ]; then
+ echo "Needs to be run as root."
+ exit 1
+ fi
+
+ CHROOT_MAKEENV="${CHROOT_MAKEENV} \
+ MAKEOBJDIRPREFIX=${CHROOTDIR}/tmp/obj"
+ CHROOT_WMAKEFLAGS="${MAKE_FLAGS} ${WORLD_FLAGS} ${CONF_FILES}"
+ CHROOT_IMAKEFLAGS="${CONF_FILES}"
+ CHROOT_DMAKEFLAGS="${CONF_FILES}"
+ RELEASE_WMAKEFLAGS="${MAKE_FLAGS} ${WORLD_FLAGS} ${ARCH_FLAGS} \
+ ${CONF_FILES}"
+ RELEASE_KMAKEFLAGS="${MAKE_FLAGS} ${KERNEL_FLAGS} \
+ KERNCONF=\"${KERNEL}\" ${ARCH_FLAGS} ${CONF_FILES}"
+ RELEASE_RMAKEFLAGS="${ARCH_FLAGS} \
+ KERNCONF=\"${KERNEL}\" ${CONF_FILES} ${DOCPORTS} \
+ WITH_DVD=${WITH_DVD} WITH_VMIMAGES=${WITH_VMIMAGES} \
+ WITH_CLOUDWARE=${WITH_CLOUDWARE} XZ_THREADS=${XZ_THREADS}"
+
+ return 0
+} # env_check()
+
+# chroot_setup(): Prepare the build chroot environment for the release build.
+chroot_setup() {
+ load_chroot_env
+ mkdir -p ${CHROOTDIR}/usr
+
+ if [ -z "${SRC_UPDATE_SKIP}" ]; then
+ ${VCSCMD} ${FORCE_SRC_KEY} ${SRCBRANCH} ${CHROOTDIR}/usr/src
+ fi
+ if [ -z "${NODOC}" ] && [ -z "${DOC_UPDATE_SKIP}" ]; then
+ ${VCSCMD} ${DOCBRANCH} ${CHROOTDIR}/usr/doc
+ fi
+ if [ -z "${NOPORTS}" ] && [ -z "${PORTS_UPDATE_SKIP}" ]; then
+ ${VCSCMD} ${PORTBRANCH} ${CHROOTDIR}/usr/ports
+ fi
+
+ if [ -z "${CHROOTBUILD_SKIP}" ]; then
+ cd ${CHROOTDIR}/usr/src
+ env ${CHROOT_MAKEENV} make ${CHROOT_WMAKEFLAGS} buildworld
+ env ${CHROOT_MAKEENV} make ${CHROOT_IMAKEFLAGS} installworld \
+ DESTDIR=${CHROOTDIR}
+ env ${CHROOT_MAKEENV} make ${CHROOT_DMAKEFLAGS} distribution \
+ DESTDIR=${CHROOTDIR}
+ fi
+
+ return 0
+} # chroot_setup()
+
+# extra_chroot_setup(): Prepare anything additional within the build
+# necessary for the release build.
+extra_chroot_setup() {
+ mkdir -p ${CHROOTDIR}/dev
+ mount -t devfs devfs ${CHROOTDIR}/dev
+ [ -e /etc/resolv.conf ] && cp /etc/resolv.conf \
+ ${CHROOTDIR}/etc/resolv.conf
+ # Run ldconfig(8) in the chroot directory so /var/run/ld-elf*.so.hints
+ # is created. This is needed by ports-mgmt/pkg.
+ eval chroot ${CHROOTDIR} /etc/rc.d/ldconfig forcerestart
+
+ # If MAKE_CONF and/or SRC_CONF are set and not character devices
+ # (/dev/null), copy them to the chroot.
+ if [ -e ${MAKE_CONF} ] && [ ! -c ${MAKE_CONF} ]; then
+ mkdir -p ${CHROOTDIR}/$(dirname ${MAKE_CONF})
+ cp ${MAKE_CONF} ${CHROOTDIR}/${MAKE_CONF}
+ fi
+ if [ -e ${SRC_CONF} ] && [ ! -c ${SRC_CONF} ]; then
+ mkdir -p ${CHROOTDIR}/$(dirname ${SRC_CONF})
+ cp ${SRC_CONF} ${CHROOTDIR}/${SRC_CONF}
+ fi
+
+ if [ -d ${CHROOTDIR}/usr/ports ]; then
+ # Trick the ports 'run-autotools-fixup' target to do the right
+ # thing.
+ _OSVERSION=$(chroot ${CHROOTDIR} /usr/bin/uname -U)
+ REVISION=$(chroot ${CHROOTDIR} make -C /usr/src/release -V REVISION)
+ BRANCH=$(chroot ${CHROOTDIR} make -C /usr/src/release -V BRANCH)
+ UNAME_r=${REVISION}-${BRANCH}
+ if [ -d ${CHROOTDIR}/usr/doc ] && [ -z "${NODOC}" ]; then
+ PBUILD_FLAGS="OSVERSION=${_OSVERSION} BATCH=yes"
+ PBUILD_FLAGS="${PBUILD_FLAGS} UNAME_r=${UNAME_r}"
+ PBUILD_FLAGS="${PBUILD_FLAGS} OSREL=${REVISION}"
+ chroot ${CHROOTDIR} make -C /usr/ports/textproc/docproj \
+ ${PBUILD_FLAGS} OPTIONS_UNSET="FOP IGOR" \
+ install clean distclean
+ fi
+ fi
+
+ if [ ! -z "${EMBEDDEDPORTS}" ]; then
+ for _PORT in ${EMBEDDEDPORTS}; do
+ eval chroot ${CHROOTDIR} make -C /usr/ports/${_PORT} \
+ BATCH=1 FORCE_PKG_REGISTER=1 install clean distclean
+ done
+ fi
+
+ buildenv_setup
+
+ return 0
+} # extra_chroot_setup()
+
+# chroot_build_target(): Build the userland and kernel for the build target.
+chroot_build_target() {
+ load_target_env
+ if [ ! -z "${EMBEDDEDBUILD}" ]; then
+ RELEASE_WMAKEFLAGS="${RELEASE_WMAKEFLAGS} \
+ TARGET=${EMBEDDED_TARGET} \
+ TARGET_ARCH=${EMBEDDED_TARGET_ARCH}"
+ RELEASE_KMAKEFLAGS="${RELEASE_KMAKEFLAGS} \
+ TARGET=${EMBEDDED_TARGET} \
+ TARGET_ARCH=${EMBEDDED_TARGET_ARCH}"
+ fi
+ eval chroot ${CHROOTDIR} make -C /usr/src ${RELEASE_WMAKEFLAGS} buildworld
+ eval chroot ${CHROOTDIR} make -C /usr/src ${RELEASE_KMAKEFLAGS} buildkernel
+
+ return 0
+} # chroot_build_target
+
+# chroot_build_release(): Invoke the 'make release' target.
+chroot_build_release() {
+ load_target_env
+ if [ ! -z "${WITH_VMIMAGES}" ]; then
+ if [ -z "${VMFORMATS}" ]; then
+ VMFORMATS="$(eval chroot ${CHROOTDIR} \
+ make -C /usr/src/release -V VMFORMATS)"
+ fi
+ if [ -z "${VMSIZE}" ]; then
+ VMSIZE="$(eval chroot ${CHROOTDIR} \
+ make -C /usr/src/release -V VMSIZE)"
+ fi
+ RELEASE_RMAKEFLAGS="${RELEASE_RMAKEFLAGS} \
+ VMFORMATS=\"${VMFORMATS}\" VMSIZE=${VMSIZE}"
+ fi
+ eval chroot ${CHROOTDIR} make -C /usr/src/release \
+ ${RELEASE_RMAKEFLAGS} release
+ eval chroot ${CHROOTDIR} make -C /usr/src/release \
+ ${RELEASE_RMAKEFLAGS} install DESTDIR=/R \
+ WITH_COMPRESSED_IMAGES=${WITH_COMPRESSED_IMAGES} \
+ WITH_COMPRESSED_VMIMAGES=${WITH_COMPRESSED_VMIMAGES}
+
+ return 0
+} # chroot_build_release()
+
+# chroot_arm_armv6_build_release(): Create arm/armv6 SD card image.
+chroot_arm_armv6_build_release() {
+ load_target_env
+ eval chroot ${CHROOTDIR} make -C /usr/src/release obj
+ if [ -e "${RELENGDIR}/tools/${EMBEDDED_TARGET}.subr" ]; then
+ . "${RELENGDIR}/tools/${EMBEDDED_TARGET}.subr"
+ fi
+ [ ! -z "${RELEASECONF}" ] && . "${RELEASECONF}"
+ WORLDDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V WORLDDIR)"
+ OBJDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V .OBJDIR)"
+ DESTDIR="${OBJDIR}/${KERNEL}"
+ IMGBASE="${CHROOTDIR}/${OBJDIR}/${KERNEL}.img"
+ OSRELEASE="$(eval chroot ${CHROOTDIR} make -C /usr/src/release \
+ TARGET=${EMBEDDED_TARGET} TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \
+ -V OSRELEASE)"
+ chroot ${CHROOTDIR} mkdir -p ${DESTDIR}
+ chroot ${CHROOTDIR} truncate -s ${IMAGE_SIZE} ${IMGBASE##${CHROOTDIR}}
+ export mddev=$(chroot ${CHROOTDIR} \
+ mdconfig -f ${IMGBASE##${CHROOTDIR}} ${MD_ARGS})
+ arm_create_disk
+ arm_install_base
+ arm_install_uboot
+ mdconfig -d -u ${mddev}
+ chroot ${CHROOTDIR} rmdir ${DESTDIR}
+ mv ${IMGBASE} ${CHROOTDIR}/${OBJDIR}/${OSRELEASE}-${KERNEL}.img
+ chroot ${CHROOTDIR} mkdir -p /R
+ chroot ${CHROOTDIR} cp -p ${OBJDIR}/${OSRELEASE}-${KERNEL}.img \
+ /R/${OSRELEASE}-${KERNEL}.img
+ chroot ${CHROOTDIR} xz -T ${XZ_THREADS} /R/${OSRELEASE}-${KERNEL}.img
+ cd ${CHROOTDIR}/R && sha512 ${OSRELEASE}* \
+ > CHECKSUM.SHA512
+ cd ${CHROOTDIR}/R && sha256 ${OSRELEASE}* \
+ > CHECKSUM.SHA256
+
+ return 0
+} # chroot_arm_armv6_build_release()
+
+# main(): Start here.
+main() {
+ set -e # Everything must succeed
+ env_setup
+ while getopts c: opt; do
+ case ${opt} in
+ c)
+ RELEASECONF="${OPTARG}"
+ ;;
+ \?)
+ usage
+ ;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+ if [ ! -z "${RELEASECONF}" ]; then
+ if [ -e "${RELEASECONF}" ]; then
+ . ${RELEASECONF}
+ else
+ echo "Nonexistent configuration file: ${RELEASECONF}"
+ echo "Using default build environment."
+ fi
+ fi
+ env_check
+ trap "umount ${CHROOTDIR}/dev" EXIT # Clean up devfs mount on exit
+ chroot_setup
+ extra_chroot_setup
+ chroot_build_target
+ ${chroot_build_release_cmd}
+
+ return 0
+} # main()
+
+main "${@}"
diff --git a/release/scripts/FreeBSD_install_cdrom.conf b/release/scripts/FreeBSD_install_cdrom.conf
new file mode 100644
index 0000000..7a6d787
--- /dev/null
+++ b/release/scripts/FreeBSD_install_cdrom.conf
@@ -0,0 +1,16 @@
+#
+# $FreeBSD$
+#
+# The pkg(8) repository configuration file for the installation DVD.
+#
+
+FreeBSD_install_cdrom: {
+ url: "file:///dist/packages/${ABI}",
+ mirror_type: "none",
+ enabled: yes
+}
+
+FreeBSD: {
+ enabled: no
+}
+
diff --git a/release/scripts/atlas-upload.sh b/release/scripts/atlas-upload.sh
new file mode 100755
index 0000000..bf1dbf1
--- /dev/null
+++ b/release/scripts/atlas-upload.sh
@@ -0,0 +1,159 @@
+#!/bin/sh
+#-
+# 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.
+#
+# Upload a Vagrant image to Hashicorp's Atlas service
+#
+# $FreeBSD$
+#
+
+ATLAS_API_URL=''
+ATLAS_UPLOAD_URL='https://binstore.hashicorp.com'
+DESCRIPTION="FreeBSD Snapshot Build"
+
+usage() {
+ echo "${0} usage:"
+ echo "-b box-name -d 'box description' -f box-to-upload -k api-key -p provider -u user -v version"
+ return 1
+}
+
+main () {
+ while getopts "b:d:f:k:p:u:v:" arg; do
+ case "${arg}" in
+ b)
+ BOX="${OPTARG}"
+ ;;
+ d)
+ DESCRIPTION="${OPTARG}"
+ ;;
+ f)
+ FILE="${OPTARG}"
+ ;;
+ k)
+ KEY="${OPTARG}"
+ ;;
+ p)
+ PROVIDER="${OPTARG}"
+ ;;
+ u)
+ USERNAME="${OPTARG}"
+ ;;
+ v)
+ VERSION="${OPTARG}"
+ ;;
+ *)
+ ;;
+ esac
+ done
+
+ if [ -z "${BOX}" -o \
+ -z "${FILE}" -o \
+ -z "${KEY}" -o \
+ -z "${PROVIDER}" -o \
+ -z "${USERNAME}" -o \
+ -z "${VERSION}" ];
+ then
+ usage || exit 0
+ fi
+
+ # Check to see if the box exists or create it
+ BOXRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}?access_token=${KEY}")
+ if [ $? != 0 ]; then
+ echo "Failed to connect to the API"
+ exit 2;
+ fi
+ echo $BOXRESULT | grep "\"name\":\"${BOX}\"" > /dev/null
+ if [ $? != 0 ]; then
+ echo "Creating box: ${BOX}"
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/boxes -X POST -d "box[name]=${BOX}" -d "access_token=${KEY}" > /dev/null
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX} -X PUT -d "box[is_private]=false" -d "access_token=${KEY}" > /dev/null
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX} -X PUT -d "box[description]='${DESCRIPTION}'" -d "access_token=${KEY}" > /dev/null
+ else
+ echo "Box already exists"
+ fi
+
+ # Check to see if the version exists or create it
+ VERSIONRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}?access_token=${KEY}")
+ if [ $? != 0 ]; then
+ echo "Failed to connect to the API"
+ exit 2;
+ fi
+ echo $VERSIONRESULT | grep "\"version\":\"${VERSION}\"" > /dev/null
+ if [ $? != 0 ]; then
+ echo "Creating version: ${VERSION}"
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/versions -X POST -d "version[version]=${VERSION}" -d "access_token=${KEY}" > /dev/null
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION} -X PUT -d "version[description]=${DESCRIPTION}" -d "access_token=${KEY}" > /dev/null
+ VERSIONRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}?access_token=${KEY}")
+ echo $VERSIONRESULT | grep "\"version\":\"${VERSION}\"" > /dev/null
+ if [ $? != 0 ]; then
+ echo "Failed to create version"
+ exit 2
+ fi
+ else
+ echo "Version already exists"
+ fi
+
+ # Check to see if the provider exists or create it
+ PROVIDERRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}?access_token=${KEY}")
+ if [ $? != 0 ]; then
+ echo "Failed to connect to the API"
+ exit 2;
+ fi
+ echo $PROVIDERRESULT | grep "\"name\":\"${PROVIDER}\"" > /dev/null
+ if [ $? != 0 ]; then
+ echo "Creating provider: ${PROVIDER}"
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/providers -X POST -d "provider[name]=${PROVIDER}" -d "access_token=${KEY}" > /dev/null
+ else
+ echo "Provider already exists"
+ fi
+
+ # Request an upload token
+ TOKENRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}/upload?access_token=${KEY}")
+ if [ $? != 0 ]; then
+ echo "Failed to get the token from the API"
+ exit 2;
+ fi
+ echo ${TOKENRESULT} | grep "\"token\":" > /dev/null
+ if [ $? != 0 ]; then
+ echo "No token found from the API"
+ exit 2
+ else
+ TOKEN=$(echo $TOKENRESULT | sed -e 's/.*token":"//' -e 's/".*//')
+ echo "Uploading to Atlas"
+ UPLOADRESULT=$(/usr/local/bin/curl -s -X PUT --upload-file ${FILE} ${ATLAS_UPLOAD_URL}/${TOKEN})
+
+ # Validate the Upload
+ echo "Validating"
+ VALIDRESULT=$(/usr/local/bin/curl -s "https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/provider/${PROVIDER}?access_token=${KEY}")
+ HOSTED_TOKEN=$(echo $VALIDRESULT | sed -e 's/.*hosted_token":"//' -e 's/".*//')
+ if [ ! -z ${HOSTED_TOKEN} -a ! -z ${TOKEN} -a ${HOSTED_TOKEN} != ${TOKEN} ]; then
+ echo "Upload failed, try again."
+ exit 2
+ fi
+
+ # Release the version
+ echo "Releasing ${VERSION} of ${BOX} in Atlas"
+ /usr/local/bin/curl -s https://atlas.hashicorp.com/api/v1/box/${USERNAME}/${BOX}/version/${VERSION}/release -X PUT -d "access_token=${KEY}" > /dev/null
+ fi
+}
+
+main "$@"
diff --git a/release/scripts/box.ovf b/release/scripts/box.ovf
new file mode 100644
index 0000000..571e36f
--- /dev/null
+++ b/release/scripts/box.ovf
@@ -0,0 +1,226 @@
+<?xml version="1.0"?>
+<Envelope ovf:version="1.0" xml:lang="en-US" xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:vbox="http://www.virtualbox.org/ovf/machine">
+ <References>
+ <File ovf:href="vagrant.vmdk" ovf:id="file1"/>
+ </References>
+ <DiskSection>
+ <Info>List of the virtual disks used in the package</Info>
+ <Disk ovf:capacity="10632560640" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" vbox:uuid="e349f8b6-c400-4e7a-9825-598becab2f94"/>
+ </DiskSection>
+ <NetworkSection>
+ <Info>Logical networks used in the package</Info>
+ <Network ovf:name="NAT">
+ <Description>Logical network used by this appliance.</Description>
+ </Network>
+ </NetworkSection>
+ <VirtualSystem ovf:id="freebsd">
+ <Info>A virtual machine</Info>
+ <OperatingSystemSection ovf:id="78">
+ <Info>The kind of installed guest operating system</Info>
+ <Description>FreeBSD_64</Description>
+ <vbox:OSType ovf:required="false">FreeBSD_64</vbox:OSType>
+ </OperatingSystemSection>
+ <VirtualHardwareSection>
+ <Info>Virtual hardware requirements for a virtual machine</Info>
+ <System>
+ <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+ <vssd:InstanceID>0</vssd:InstanceID>
+ <vssd:VirtualSystemIdentifier>freebsd</vssd:VirtualSystemIdentifier>
+ <vssd:VirtualSystemType>virtualbox-2.2</vssd:VirtualSystemType>
+ </System>
+ <Item>
+ <rasd:Caption>1 virtual CPU</rasd:Caption>
+ <rasd:Description>Number of virtual CPUs</rasd:Description>
+ <rasd:ElementName>1 virtual CPU</rasd:ElementName>
+ <rasd:InstanceID>1</rasd:InstanceID>
+ <rasd:ResourceType>3</rasd:ResourceType>
+ <rasd:VirtualQuantity>1</rasd:VirtualQuantity>
+ </Item>
+ <Item>
+ <rasd:AllocationUnits>MegaBytes</rasd:AllocationUnits>
+ <rasd:Caption>512 MB of memory</rasd:Caption>
+ <rasd:Description>Memory Size</rasd:Description>
+ <rasd:ElementName>512 MB of memory</rasd:ElementName>
+ <rasd:InstanceID>2</rasd:InstanceID>
+ <rasd:ResourceType>4</rasd:ResourceType>
+ <rasd:VirtualQuantity>512</rasd:VirtualQuantity>
+ </Item>
+ <Item>
+ <rasd:Address>0</rasd:Address>
+ <rasd:Caption>ideController0</rasd:Caption>
+ <rasd:Description>IDE Controller</rasd:Description>
+ <rasd:ElementName>ideController0</rasd:ElementName>
+ <rasd:InstanceID>3</rasd:InstanceID>
+ <rasd:ResourceSubType>PIIX4</rasd:ResourceSubType>
+ <rasd:ResourceType>5</rasd:ResourceType>
+ </Item>
+ <Item>
+ <rasd:Address>1</rasd:Address>
+ <rasd:Caption>ideController1</rasd:Caption>
+ <rasd:Description>IDE Controller</rasd:Description>
+ <rasd:ElementName>ideController1</rasd:ElementName>
+ <rasd:InstanceID>4</rasd:InstanceID>
+ <rasd:ResourceSubType>PIIX4</rasd:ResourceSubType>
+ <rasd:ResourceType>5</rasd:ResourceType>
+ </Item>
+ <Item>
+ <rasd:AddressOnParent>0</rasd:AddressOnParent>
+ <rasd:Caption>disk1</rasd:Caption>
+ <rasd:Description>Disk Image</rasd:Description>
+ <rasd:ElementName>disk1</rasd:ElementName>
+ <rasd:HostResource>/disk/vmdisk1</rasd:HostResource>
+ <rasd:InstanceID>5</rasd:InstanceID>
+ <rasd:Parent>3</rasd:Parent>
+ <rasd:ResourceType>17</rasd:ResourceType>
+ </Item>
+ <Item>
+ <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+ <rasd:Caption>Ethernet adapter on 'NAT'</rasd:Caption>
+ <rasd:Connection>NAT</rasd:Connection>
+ <rasd:ElementName>Ethernet adapter on 'NAT'</rasd:ElementName>
+ <rasd:InstanceID>6</rasd:InstanceID>
+ <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
+ <rasd:ResourceType>10</rasd:ResourceType>
+ </Item>
+ </VirtualHardwareSection>
+ <vbox:Machine ovf:required="false" version="1.12-macosx" uuid="{8b837be7-fa96-48fc-b119-e90cfa144456}" name="freebsd" OSType="FreeBSD_64" snapshotFolder="Snapshots" lastStateChange="2014-03-13T13:50:05Z">
+ <ovf:Info>Complete VirtualBox machine configuration in VirtualBox format</ovf:Info>
+ <ExtraData>
+ <ExtraDataItem name="GUI/LastGuestSizeHint" value="720,400"/>
+ <ExtraDataItem name="GUI/LastNormalWindowPosition" value="400,183,720,421"/>
+ </ExtraData>
+ <Hardware version="2">
+ <CPU count="1" hotplug="false">
+ <HardwareVirtEx enabled="true"/>
+ <HardwareVirtExNestedPaging enabled="true"/>
+ <HardwareVirtExVPID enabled="true"/>
+ <HardwareVirtExUX enabled="true"/>
+ <PAE enabled="true"/>
+ <HardwareVirtExLargePages enabled="true"/>
+ <HardwareVirtForce enabled="false"/>
+ </CPU>
+ <Memory RAMSize="512" PageFusion="false"/>
+ <HID Pointing="PS2Mouse" Keyboard="PS2Keyboard"/>
+ <HPET enabled="false"/>
+ <Chipset type="PIIX3"/>
+ <Boot>
+ <Order position="1" device="HardDisk"/>
+ <Order position="2" device="DVD"/>
+ <Order position="3" device="None"/>
+ <Order position="4" device="None"/>
+ </Boot>
+ <Display VRAMSize="8" monitorCount="1" accelerate3D="false" accelerate2DVideo="false"/>
+ <VideoCapture/>
+ <RemoteDisplay enabled="false" authType="Null"/>
+ <BIOS>
+ <ACPI enabled="true"/>
+ <IOAPIC enabled="true"/>
+ <Logo fadeIn="true" fadeOut="true" displayTime="0"/>
+ <BootMenu mode="MessageAndMenu"/>
+ <TimeOffset value="0"/>
+ <PXEDebug enabled="false"/>
+ </BIOS>
+ <USBController enabled="false" enabledEhci="false"/>
+ <Network>
+ <Adapter slot="0" enabled="true" MACAddress="080027D14C66" cable="true" speed="0" type="82540EM">
+ <DisabledModes/>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </Adapter>
+ <Adapter slot="1" enabled="false" MACAddress="080027058FF2" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ <Adapter slot="2" enabled="false" MACAddress="08002763A181" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ <Adapter slot="3" enabled="false" MACAddress="0800279C6D17" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ <Adapter slot="4" enabled="false" MACAddress="08002760C885" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ <Adapter slot="5" enabled="false" MACAddress="0800279ECE95" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ <Adapter slot="6" enabled="false" MACAddress="08002730E8BE" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ <Adapter slot="7" enabled="false" MACAddress="080027AD8EF8" cable="true" speed="0" type="82540EM">
+ <DisabledModes>
+ <NAT>
+ <DNS pass-domain="true" use-proxy="false" use-host-resolver="false"/>
+ <Alias logging="false" proxy-only="false" use-same-ports="false"/>
+ </NAT>
+ </DisabledModes>
+ </Adapter>
+ </Network>
+ <UART>
+ <Port slot="0" enabled="false" IOBase="0x3f8" IRQ="4" hostMode="Disconnected"/>
+ <Port slot="1" enabled="false" IOBase="0x2f8" IRQ="3" hostMode="Disconnected"/>
+ </UART>
+ <LPT>
+ <Port slot="0" enabled="false" IOBase="0x378" IRQ="7"/>
+ <Port slot="1" enabled="false" IOBase="0x378" IRQ="7"/>
+ </LPT>
+ <AudioAdapter controller="AC97" driver="CoreAudio" enabled="false"/>
+ <RTC localOrUTC="local"/>
+ <SharedFolders/>
+ <Clipboard mode="Disabled"/>
+ <DragAndDrop mode="Disabled"/>
+ <IO>
+ <IoCache enabled="true" size="5"/>
+ <BandwidthGroups/>
+ </IO>
+ <HostPci>
+ <Devices/>
+ </HostPci>
+ <EmulatedUSB>
+ <CardReader enabled="false"/>
+ </EmulatedUSB>
+ <Guest memoryBalloonSize="0"/>
+ <GuestProperties>
+ <GuestProperty name="/VirtualBox/HostInfo/GUI/LanguageID" value="en_US" timestamp="1394718154090069000" flags=""/>
+ </GuestProperties>
+ </Hardware>
+ <StorageControllers>
+ <StorageController name="IDE Controller" type="PIIX4" PortCount="2" useHostIOCache="true" Bootable="true">
+ <AttachedDevice type="HardDisk" port="0" device="0">
+ <Image uuid="{e349f8b6-c400-4e7a-9825-598becab2f94}"/>
+ </AttachedDevice>
+ </StorageController>
+ </StorageControllers>
+ </vbox:Machine>
+ </VirtualSystem>
+</Envelope>
diff --git a/release/scripts/list-new-changesets.py b/release/scripts/list-new-changesets.py
new file mode 100755
index 0000000..ffb4f48
--- /dev/null
+++ b/release/scripts/list-new-changesets.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014, Craig Rodrigues <rodrigc@FreeBSD.org>
+# 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 unmodified, 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 ``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 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.
+#
+# $FreeBSD$
+
+# Display SVN log entries for changesets which have files which were
+# Added or Deleted.
+# This script takes arguments which would normally be
+# passed to the "svn log" command.
+#
+# Examples:
+#
+# (1) Display all new changesets in stable/10 branch:
+#
+# list-new-changesets.py --stop-on-copy \
+# svn://svn.freebsd.org/base/stable/10
+#
+# (2) Display all new changesets between r254153 and r261794 in
+# stable/9 branch:
+#
+# list-new-changesets.py -r254153:261794 \
+# svn://svn.freebsd.org/base/stable/9
+
+from __future__ import print_function
+import os
+import subprocess
+import sys
+import xml.etree.ElementTree
+
+def print_logentry(logentry):
+ """Print an SVN log entry.
+
+ Take an SVN log entry formatted in XML, and print it out in
+ plain text.
+ """
+ rev = logentry.attrib['revision']
+ author = logentry.find('author').text
+ date = logentry.find('date').text
+ msg = logentry.find('msg').text
+
+ print("-" * 71)
+ print("%s | %s | %s" % (rev, author, date))
+ print("Changed paths:")
+ for paths in logentry.findall('paths'):
+ for path in paths.findall('path'):
+ print(" %s %s" % (path.attrib['action'], path.text))
+
+ print()
+ print(msg.encode('utf-8'))
+
+def main(args):
+ """Main function.
+
+ Take command-line arguments which would be passed to 'svn log'.
+ Prepend '-v --xml' to get verbose XML formatted output.
+ Only display entries which have Added or Deleted files.
+ """
+ cmd = ["svn", "log", "-v", "--xml"]
+ cmd += args[1:]
+
+ print(" ".join(cmd))
+
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (out, err) = proc.communicate()
+
+ if proc.returncode != 0:
+ print(err)
+ sys.exit(proc.returncode)
+
+ displayed_entries = 0
+ root = xml.etree.ElementTree.fromstring(out)
+
+ for logentry in root.findall('logentry'):
+ show_logentry = False
+
+ for paths in logentry.findall('paths'):
+ for path in paths.findall('path'):
+ if path.attrib['action'] == 'A':
+ show_logentry = True
+ elif path.attrib['action'] == 'D':
+ show_logentry = True
+
+ if show_logentry == True :
+ print_logentry(logentry)
+ displayed_entries += 1
+
+ if displayed_entries == 0:
+ print("No changesets with Added or Deleted files")
+
+ if displayed_entries > 0:
+ print("-" * 71)
+
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/release/scripts/make-manifest.sh b/release/scripts/make-manifest.sh
new file mode 100755
index 0000000..b21e8f5
--- /dev/null
+++ b/release/scripts/make-manifest.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# make-manifest.sh: create checksums and package descriptions for the installer
+#
+# Usage: make-manifest.sh foo1.txz foo2.txz ...
+#
+# The output file looks like this (tab-delimited):
+# foo1.txz SHA256-checksum Number-of-files foo1 Description Install-by-default
+#
+# $FreeBSD$
+
+desc_base="Base system (MANDATORY)"
+desc_kernel="Kernel (MANDATORY)"
+desc_doc="Additional documentation"
+doc_default=off
+desc_lib32="32-bit compatibility libraries"
+desc_ports="Ports tree"
+desc_src="System source code"
+desc_tests="Test suite"
+src_default=off
+tests_default=off
+
+for i in $*; do
+ echo "`basename $i` `sha256 -q $i` `tar tvf $i | wc -l | tr -d ' '` `basename $i .txz` \"`eval echo \\\$desc_$(basename $i .txz)`\" `eval echo \\\${$(basename $i .txz)_default:-on}`"
+done
+
diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh
new file mode 100755
index 0000000..fd84216
--- /dev/null
+++ b/release/scripts/mk-vmimage.sh
@@ -0,0 +1,122 @@
+#!/bin/sh
+#-
+# Copyright (c) 2014, 2015 The FreeBSD Foundation
+# All rights reserved.
+#
+# This software was developed by Glen Barber under sponsorship
+# from the FreeBSD Foundation.
+#
+# 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.
+#
+# mk-vmimage.sh: Create virtual machine disk images in various formats.
+#
+# $FreeBSD$
+#
+
+usage() {
+ echo "${0} usage:"
+ echo "${@}"
+ return 1
+}
+
+main() {
+ local arg
+ VMCONFIG="/dev/null"
+ while getopts "C:c:d:f:i:o:s:S:" arg; do
+ case "${arg}" in
+ C)
+ VMBUILDCONF="${OPTARG}"
+ ;;
+ c)
+ VMCONFIG="${OPTARG}"
+ ;;
+ d)
+ DESTDIR="${OPTARG}"
+ ;;
+ f)
+ VMFORMAT="${OPTARG}"
+ ;;
+ i)
+ VMBASE="${OPTARG}"
+ ;;
+ o)
+ VMIMAGE="${OPTARG}"
+ ;;
+ s)
+ VMSIZE="${OPTARG}"
+ ;;
+ S)
+ WORLDDIR="${OPTARG}"
+ ;;
+ *)
+ ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1))
+
+ if [ -z "${VMBASE}" -o \
+ -z "${WORLDDIR}" -o \
+ -z "${DESTDIR}" -o \
+ -z "${VMSIZE}" -o \
+ -z "${VMIMAGE}" ];
+ then
+ usage || exit 0
+ fi
+
+ if [ -z "${VMBUILDCONF}" ] || [ ! -e "${VMBUILDCONF}" ]; then
+ echo "Must provide the path to vmimage.subr."
+ return 1
+ fi
+
+ . "${VMBUILDCONF}"
+
+ if [ ! -z "${VMCONFIG}" ] && [ ! -c "${VMCONFIG}" ]; then
+ . "${VMCONFIG}"
+ fi
+
+ case ${TARGET}:${TARGET_ARCH} in
+ arm64:aarch64)
+ ROOTLABEL="ufs"
+ NOSWAP=1
+ ;;
+ *)
+ ROOTLABEL="gpt"
+ ;;
+ esac
+
+ vm_create_base
+ vm_install_base
+ vm_extra_install_base
+ vm_extra_install_packages
+ vm_extra_install_ports
+ vm_extra_enable_services
+ vm_extra_pre_umount
+ vm_extra_pkg_rmcache
+ cleanup
+ vm_copy_base
+ vm_create_disk || return 0
+ vm_extra_create_disk
+
+ return 0
+}
+
+main "$@"
diff --git a/release/scripts/mm-mtree.sh b/release/scripts/mm-mtree.sh
new file mode 100755
index 0000000..4499c10
--- /dev/null
+++ b/release/scripts/mm-mtree.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+
+# mergemaster mtree database generator
+
+# This script is intended to be used as part of the release building
+# process to generate the /var/db/mergemaster.mtree file relevant to
+# the source tree used to create the release so that users can make
+# use of mergemaster's -U option to update their files after updating
+# to -stable.
+
+# Copyright 2009 Douglas Barton
+# dougb@FreeBSD.org
+
+# $FreeBSD$
+
+PATH=/bin:/usr/bin:/usr/sbin
+
+display_usage () {
+ VERSION_NUMBER=`grep "[$]FreeBSD:" $0 | cut -d ' ' -f 4`
+ echo "${0##*/} version ${VERSION_NUMBER}"
+ echo "Usage: ${0##*/} [-m /path] [-t /path] [-A arch] [-F <make args>] [-D /path]"
+ echo "Options:"
+ echo " -m /path/directory Specify location of source to do the make in"
+ echo " -t /path/directory Specify temp root directory"
+ echo " -A architecture Alternative architecture name to pass to make"
+ echo " -F <arguments for make> Specify what to put on the make command line"
+ echo ' -D /path/directory Specify the destination directory to install files to'
+ echo ''
+}
+
+# Set the default path for the temporary root environment
+#
+TEMPROOT=`TMPDIR=/var/tmp mktemp -d -t temproot`
+
+# Assign the location of the mtree database
+#
+MTREEDB=${MTREEDB:-/var/db}
+MTREEFILE="${MTREEDB}/mergemaster.mtree"
+
+# Check the command line options
+#
+while getopts "m:t:A:F:D:h" COMMAND_LINE_ARGUMENT ; do
+ case "${COMMAND_LINE_ARGUMENT}" in
+ m)
+ SOURCEDIR=${OPTARG}
+ ;;
+ t)
+ TEMPROOT=${OPTARG}
+ ;;
+ A)
+ ARCHSTRING='TARGET_ARCH='${OPTARG}
+ ;;
+ F)
+ MM_MAKE_ARGS="${OPTARG}"
+ ;;
+ D)
+ DESTDIR=${OPTARG}
+ ;;
+ h)
+ display_usage
+ exit 0
+ ;;
+ *)
+ echo ''
+ display_usage
+ exit 1
+ ;;
+ esac
+done
+
+# Assign the source directory
+#
+SOURCEDIR=${SOURCEDIR:-/usr/src}
+if [ ! -f ${SOURCEDIR}/Makefile.inc1 -a \
+ -f ${SOURCEDIR}/../Makefile.inc1 ]; then
+ echo " *** The source directory you specified (${SOURCEDIR})"
+ echo " will be reset to ${SOURCEDIR}/.."
+ echo ''
+ sleep 3
+ SOURCEDIR=${SOURCEDIR}/..
+fi
+
+# Setup make to use system files from SOURCEDIR
+objp=${MAKEOBJDIRPREFIX}
+[ -z "${objp}" ] && objp=/usr/obj
+legacydir=${objp}${SOURCEDIR}/tmp/legacy
+legacypath=${legacydir}/usr/sbin:${legacydir}/usr/bin:${legacydir}/bin
+MM_MAKE_ARGS="${MM_MAKE_ARGS} PATH=${legacypath}:${PATH}"
+MM_MAKE="make ${ARCHSTRING} ${MM_MAKE_ARGS} -m ${SOURCEDIR}/share/mk"
+
+delete_temproot () {
+ rm -rf "${TEMPROOT}" 2>/dev/null
+ chflags -R 0 "${TEMPROOT}" 2>/dev/null
+ rm -rf "${TEMPROOT}" || exit 1
+}
+
+[ -d "${TEMPROOT}" ] && delete_temproot
+
+echo "*** Creating the temporary root environment in ${TEMPROOT}"
+
+if mkdir -p "${TEMPROOT}"; then
+ echo " *** ${TEMPROOT} ready for use"
+fi
+
+if [ ! -d "${TEMPROOT}" ]; then
+ echo ''
+ echo " *** FATAL ERROR: Cannot create ${TEMPROOT}"
+ echo ''
+ exit 1
+fi
+
+echo " *** Creating and populating directory structure in ${TEMPROOT}"
+echo ''
+
+{ cd ${SOURCEDIR} || { echo "*** Cannot cd to ${SOURCEDIR}" ; exit 1;}
+ case "${DESTDIR}" in
+ '') ;;
+ *)
+ ${MM_MAKE} DESTDIR=${DESTDIR} distrib-dirs
+ ;;
+ esac
+ od=${TEMPROOT}/usr/obj
+ ${MM_MAKE} DESTDIR=${TEMPROOT} distrib-dirs &&
+ MAKEOBJDIRPREFIX=$od ${MM_MAKE} _obj SUBDIR_OVERRIDE=etc &&
+ MAKEOBJDIRPREFIX=$od ${MM_MAKE} everything SUBDIR_OVERRIDE=etc &&
+ MAKEOBJDIRPREFIX=$od ${MM_MAKE} DESTDIR=${TEMPROOT} distribution;} ||
+ { echo '';
+ echo " *** FATAL ERROR: Cannot 'cd' to ${SOURCEDIR} and install files to";
+ echo " the temproot environment";
+ echo '';
+ exit 1;}
+
+# We really don't want to have to deal with files like login.conf.db, pwd.db,
+# or spwd.db. Instead, we want to compare the text versions, and run *_mkdb.
+# Prompt the user to do so below, as needed.
+#
+rm -f ${TEMPROOT}/etc/*.db ${TEMPROOT}/etc/passwd
+
+# We only need to compare things like freebsd.cf once
+find ${TEMPROOT}/usr/obj -type f -delete 2>/dev/null
+
+# Delete stuff we do not need to keep the mtree database small,
+# and to make the actual comparison faster.
+find ${TEMPROOT}/usr -type l -delete 2>/dev/null
+find ${TEMPROOT} -type f -size 0 -delete 2>/dev/null
+find -d ${TEMPROOT} -type d -empty -delete 2>/dev/null
+
+# Build the mtree database in a temporary location.
+MTREENEW=`mktemp -t mergemaster.mtree`
+mtree -ci -p ${TEMPROOT} -k size,md5digest > ${MTREENEW} 2>/dev/null
+
+if [ -s "${MTREENEW}" ]; then
+ echo "*** Saving mtree database for future upgrades"
+ test -e "${DESTDIR}${MTREEFILE}" && unlink ${DESTDIR}${MTREEFILE}
+ mv ${MTREENEW} ${DESTDIR}${MTREEFILE}
+fi
+
+delete_temproot
+
+exit 0
diff --git a/release/scripts/pkg-stage.sh b/release/scripts/pkg-stage.sh
new file mode 100755
index 0000000..095f996
--- /dev/null
+++ b/release/scripts/pkg-stage.sh
@@ -0,0 +1,90 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+set -e
+
+export ASSUME_ALWAYS_YES="YES"
+export PKG_DBDIR="/tmp/pkg"
+export PERMISSIVE="YES"
+export REPO_AUTOUPDATE="NO"
+export PKGCMD="/usr/sbin/pkg -d"
+
+_DVD_PACKAGES="archivers/unzip
+devel/subversion
+devel/subversion-static
+emulators/linux_base-f10
+misc/freebsd-doc-all
+net/mpd5
+net/rsync
+ports-mgmt/pkg
+ports-mgmt/portmaster
+shells/bash
+shells/zsh
+security/sudo
+sysutils/screen
+www/firefox
+www/links
+x11-drivers/xf86-video-vmware
+x11/gnome3
+x11/kde4
+x11/xorg"
+
+# If NOPORTS is set for the release, do not attempt to build pkg(8).
+if [ ! -f /usr/ports/Makefile ]; then
+ echo "*** /usr/ports is missing! ***"
+ echo "*** Skipping pkg-stage.sh ***"
+ echo "*** Unset NOPORTS to fix this ***"
+ exit 0
+fi
+
+if [ ! -x /usr/local/sbin/pkg ]; then
+ /etc/rc.d/ldconfig restart
+ /usr/bin/make -C /usr/ports/ports-mgmt/pkg install clean
+fi
+
+export DVD_DIR="dvd/packages"
+export PKG_ABI=$(pkg config ABI)
+export PKG_ALTABI=$(pkg config ALTABI 2>/dev/null)
+export PKG_REPODIR="${DVD_DIR}/${PKG_ABI}"
+
+/bin/mkdir -p ${PKG_REPODIR}
+if [ ! -z "${PKG_ALTABI}" ]; then
+ (cd ${DVD_DIR} && ln -s ${PKG_ABI} ${PKG_ALTABI})
+fi
+
+# Ensure the ports listed in _DVD_PACKAGES exist to sanitize the
+# final list.
+for _P in ${_DVD_PACKAGES}; do
+ if [ -d "/usr/ports/${_P}" ]; then
+ DVD_PACKAGES="${DVD_PACKAGES} ${_P}"
+ else
+ echo "*** Skipping nonexistent port: ${_P}"
+ fi
+done
+
+# Make sure the package list is not empty.
+if [ -z "${DVD_PACKAGES}" ]; then
+ echo "*** The package list is empty."
+ echo "*** Something is very wrong."
+ # Exit '0' so the rest of the build process continues
+ # so other issues (if any) can be addressed as well.
+ exit 0
+fi
+
+# Print pkg(8) information to make debugging easier.
+${PKGCMD} -vv
+${PKGCMD} update -f
+${PKGCMD} fetch -o ${PKG_REPODIR} -d ${DVD_PACKAGES}
+
+# Create the 'Latest/pkg.txz' symlink so 'pkg bootstrap' works
+# using the on-disc packages.
+mkdir -p ${PKG_REPODIR}/Latest
+(cd ${PKG_REPODIR}/Latest && \
+ ln -s ../All/$(${PKGCMD} rquery %n-%v pkg).txz pkg.txz)
+
+${PKGCMD} repo ${PKG_REPODIR}
+
+# Always exit '0', even if pkg(8) complains about conflicts.
+exit 0
diff --git a/release/scripts/relnotes-search.sh b/release/scripts/relnotes-search.sh
new file mode 100755
index 0000000..895f399
--- /dev/null
+++ b/release/scripts/relnotes-search.sh
@@ -0,0 +1,133 @@
+#!/bin/sh
+#-
+# Copyright (c) 2014 The FreeBSD Foundation
+# All rights reserved.
+#
+# This software were developed by Glen Barber
+# under sponsorship from the FreeBSD Foundation.
+#
+# 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.
+#
+# $FreeBSD$
+#
+
+set -C
+
+PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"
+export PATH
+
+usage() {
+ echo "Usage:"
+ echo -n "$(basename ${0}) [-rNNNNNN]"
+ echo " [-l /path/for/output] /path/to/branch"
+ echo " -r: The oldest commit to include in the search"
+ echo ""
+ exit 1
+}
+
+main() {
+ while getopts "l:r:" arg ; do
+ case ${arg} in
+ l)
+ # Disallow '-rNNNNNN' argument for oldest
+ # revision # from becoming the log file
+ # accidentally.
+ where="${OPTARG##-r*}"
+ [ -z "${where}" ] && usage
+ if [ -e "${where}" ]; then
+ echo "Log file already exists:"
+ echo " (${where})"
+ return 2
+ fi
+ ;;
+ r)
+ rev="${OPTARG##-r}"
+ c=$(echo -n ${rev} | tr -d '0-9' | wc -c)
+ if [ ${c} -ne 0 ]; then
+ echo "Revision number must be numeric."
+ return 2
+ fi
+ # Since the last specified revision is
+ # specified, mangle the variable to
+ # make svn syntax happy.
+ rev="-r${rev}:rHEAD"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1 ))
+
+ # This assumes a local working copy, which svn search
+ # allows exactly one repository path (although the root
+ # can still be the path).
+ [ "$#" -ne 1 ] && usage
+
+ # If no log file, write to stdout.
+ [ -z "${where}" ] && where=/dev/stdout
+
+ svn=
+ # Where is svn?
+ for s in /usr/bin /usr/local/bin; do
+ if [ -x ${s}/svn ]; then
+ svn=${s}/svn
+ break
+ fi
+ if [ -x ${s}/svnlite ]; then
+ svn=${s}/svnlite
+ break
+ fi
+ done
+ # Did we find svn?
+ if [ -z "${svn}" ]; then
+ echo "svn(1) binary not found."
+ return 2
+ fi
+ # Is more than one path specified? (This should never
+ # be triggered, because the argument count is checked
+ # above, but better safe than sorry.)
+ if [ $# -gt 1 ]; then
+ echo "Cannot specify more than one working path."
+ return 2
+ fi
+ # Does the directory exist?
+ if [ ! -d "${1}" ]; then
+ echo "Specified path (${1}) is not a directory."
+ return 2
+ fi
+ # Is it a subversion repository checkout?
+ ${svn} info ${1} >/dev/null 2>&1
+ if [ "$?" -ne 0 ]; then
+ echo "Cannot determine svn repository information for ${1}"
+ return 2
+ fi
+
+ # All tests passed. Let's see what can possibly go wrong
+ # from here. The search string specified should match this
+ # in PCRE speak: ':[\t ]*'
+ ${svn} log ${rev} --search 'Relnotes:*[A-Za-z0-9]*' ${1} > ${where}
+ return $?
+}
+
+main "${@}"
+exit $?
diff --git a/release/sparc64/mkisoimages.sh b/release/sparc64/mkisoimages.sh
new file mode 100644
index 0000000..337db40
--- /dev/null
+++ b/release/sparc64/mkisoimages.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+#
+# Module: mkisoimages.sh
+# Author: Jordan K Hubbard
+# Date: 22 June 2001
+#
+# $FreeBSD$
+#
+# This script is used by release/Makefile to build the (optional) ISO images
+# for a FreeBSD release. It is considered architecture dependent since each
+# platform has a slightly unique way of making bootable CDs. This script
+# is also allowed to generate any number of images since that is more of
+# publishing decision than anything else.
+#
+# Usage:
+#
+# mkisoimages.sh [-b] image-label image-name base-bits-dir [extra-bits-dir]
+#
+# Where -b is passed if the ISO image should be made "bootable" by
+# whatever standards this architecture supports (may be unsupported),
+# image-label is the ISO image label, image-name is the filename of the
+# resulting ISO image, base-bits-dir contains the image contents and
+# extra-bits-dir, if provided, contains additional files to be merged
+# into base-bits-dir as part of making the image.
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 [-b] image-label image-name base-bits-dir [extra-bits-dir]" > /dev/stderr
+ exit 1
+fi
+
+case "$1" in
+-b) BOPT="$1"; shift ;;
+esac
+LABEL=`echo "$1" | tr '[:lower:]' '[:upper:]'`; shift
+NAME="$1"; shift
+BASEBITSDIR="$1"
+
+# Create an ISO image
+publisher="The FreeBSD Project. http://www.FreeBSD.org/"
+echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > "$BASEBITSDIR/etc/fstab"
+makefs -t cd9660 -o rockridge -o label="$LABEL" -o publisher="$publisher" "$NAME.tmp" "$@"
+rm "$BASEBITSDIR/etc/fstab"
+
+if [ "x$BOPT" != "x-b" ]; then
+ mv "$NAME.tmp" "$NAME"
+ exit 0
+fi
+
+TMPIMGDIR=`mktemp -d /tmp/bootfs.XXXXXXXX` || exit 1
+BOOTFSDIR="$TMPIMGDIR/bootfs"
+BOOTFSIMG="$TMPIMGDIR/bootfs.img"
+
+# Create a boot filesystem
+mkdir -p "$BOOTFSDIR/boot"
+cp -p "$BASEBITSDIR/boot/loader" "$BOOTFSDIR/boot"
+makefs -t ffs -B be -M 512k "$BOOTFSIMG" "$BOOTFSDIR"
+dd if="$BASEBITSDIR/boot/boot1" of="$BOOTFSIMG" bs=512 conv=notrunc,sync
+
+# Create a boot ISO image
+: ${CYLSIZE:=640}
+ISOSIZE=$(stat -f %z "$NAME.tmp")
+ISOBLKS=$((($ISOSIZE + 511) / 512))
+ISOCYLS=$((($ISOBLKS + ($CYLSIZE - 1)) / $CYLSIZE))
+
+BOOTFSSIZE=$(stat -f %z "$BOOTFSIMG")
+BOOTFSBLKS=$((($BOOTFSSIZE + 511) / 512))
+BOOTFSCYLS=$((($BOOTFSBLKS + ($CYLSIZE - 1)) / $CYLSIZE))
+
+ENDCYL=$(($ISOCYLS + $BOOTFSCYLS))
+NSECTS=$(($ENDCYL * 1 * $CYLSIZE))
+
+dd if="$NAME.tmp" of="$NAME" bs="${CYLSIZE}b" conv=notrunc,sync
+dd if="$BOOTFSIMG" of="$NAME" bs="${CYLSIZE}b" seek=$ISOCYLS conv=notrunc,sync
+# The number of alternative cylinders is always 2.
+dd if=/dev/zero of="$NAME" bs="${CYLSIZE}b" seek=$ENDCYL count=2 conv=notrunc,sync
+rm -rf "$NAME.tmp" "$TMPIMGDIR"
+
+# Write VTOC8 label to boot ISO image
+MD=`mdconfig -a -t vnode -S 512 -y 1 -x "$CYLSIZE" -f "$NAME"`
+gpart create -s VTOC8 $MD
+# !4: usr, for ISO image part
+gpart add -i 1 -s "$(($ISOCYLS * $CYLSIZE * 512))b" -t \!4 $MD
+# !2: root, for bootfs part.
+gpart add -i 6 -s "$(($BOOTFSCYLS * $CYLSIZE * 512))b" -t \!2 $MD
+mdconfig -d -u ${MD#md}
diff --git a/release/tools/arm.subr b/release/tools/arm.subr
new file mode 100644
index 0000000..2adadd2
--- /dev/null
+++ b/release/tools/arm.subr
@@ -0,0 +1,137 @@
+#!/bin/sh
+#-
+# Copyright (c) 2015 The FreeBSD Foundation
+# All rights reserved.
+#
+# Portions of this software were developed by Glen Barber
+# under sponsorship from the FreeBSD Foundation.
+#
+# 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.
+#
+# Common subroutines used to build arm/armv6 images.
+#
+# $FreeBSD$
+#
+
+cleanup() {
+ if [ -c "${DESTDIR}/dev/null" ]; then
+ umount_loop ${DESTDIR}/dev 2>/dev/null
+ fi
+ umount_loop ${DESTDIR}
+ if [ ! -z "${mddev}" ]; then
+ mdconfig -d -u ${mddev}
+ fi
+
+ return 0
+}
+
+umount_loop() {
+ DIR=$1
+ i=0
+ sync
+ while ! umount ${DIR}; do
+ i=$(( $i + 1 ))
+ if [ $i -ge 10 ]; then
+ # This should never happen. But, it has happened.
+ echo "Cannot umount(8) ${DIR}"
+ echo "Something has gone horribly wrong."
+ return 1
+ fi
+ sleep 1
+ done
+
+ return 0
+}
+
+arm_create_disk() {
+ # Create the target raw file and temporary work directory.
+ chroot ${CHROOTDIR} gpart create -s ${PART_SCHEME} ${mddev}
+ chroot ${CHROOTDIR} gpart add -t '!12' -a 63 -s ${FAT_SIZE} ${mddev}
+ chroot ${CHROOTDIR} gpart set -a active -i 1 ${mddev}
+ chroot ${CHROOTDIR} newfs_msdos -L msdosboot -F ${FAT_TYPE} /dev/${mddev}s1
+ chroot ${CHROOTDIR} gpart add -t freebsd ${mddev}
+ chroot ${CHROOTDIR} gpart create -s bsd ${mddev}s2
+ chroot ${CHROOTDIR} gpart add -t freebsd-ufs -a 64k /dev/${mddev}s2
+ chroot ${CHROOTDIR} newfs -U -L rootfs /dev/${mddev}s2a
+ chroot ${CHROOTDIR} tunefs -N enable /dev/${mddev}s2a
+
+ return 0
+}
+
+arm_create_user() {
+ # Create a default user account 'freebsd' with the password 'freebsd',
+ # and set the default password for the 'root' user to 'root'.
+ chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \
+ groupadd freebsd -g 1001
+ chroot ${CHROOTDIR} mkdir -p ${DESTDIR}/home/freebsd
+ chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \
+ useradd freebsd \
+ -m -M 0755 -w yes -n freebsd -u 1001 -g 1001 -G 0 \
+ -c 'FreeBSD User' -d '/home/freebsd' -s '/bin/csh'
+ chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \
+ usermod root -w yes
+
+ return 0
+}
+
+arm_install_base() {
+ chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${DESTDIR}
+ eval chroot ${CHROOTDIR} make -C ${WORLDDIR} \
+ TARGET=${EMBEDDED_TARGET} \
+ TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \
+ DESTDIR=${DESTDIR} KERNCONF=${KERNEL} \
+ installworld installkernel distribution
+ chroot ${CHROOTDIR} mkdir -p ${DESTDIR}/boot/msdos
+
+ arm_create_user
+
+ echo '# Custom /etc/fstab for FreeBSD embedded images' \
+ > ${CHROOTDIR}/${DESTDIR}/etc/fstab
+ echo "/dev/ufs/rootfs / ufs rw 1 1" \
+ >> ${CHROOTDIR}/${DESTDIR}/etc/fstab
+ echo "/dev/msdosfs/MSDOSBOOT /boot/msdos msdosfs rw,noatime 0 0" \
+ >> ${CHROOTDIR}/${DESTDIR}/etc/fstab
+ echo "tmpfs /tmp tmpfs rw,mode=1777,size=30m 0 0" \
+ >> ${CHROOTDIR}/${DESTDIR}/etc/fstab
+
+ local hostname
+ hostname="$(echo ${KERNEL} | tr '[:upper:]' '[:lower:]')"
+ echo "hostname=\"${hostname}\"" > ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'ifconfig_DEFAULT="DHCP"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'sshd_enable="YES"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'sendmail_enable="NONE"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'sendmail_submit_enable="NO"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'sendmail_outbound_enable="NO"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'sendmail_msp_queue_enable="NO"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+ echo 'growfs_enable="YES"' >> ${CHROOTDIR}/${DESTDIR}/etc/rc.conf
+
+ sync
+ umount_loop ${CHROOTDIR}/${DESTDIR}
+
+ return 0
+}
+
+arm_install_uboot() {
+ # Override in the arm/KERNEL.conf file.
+
+ return 0
+}
diff --git a/release/tools/azure.conf b/release/tools/azure.conf
new file mode 100644
index 0000000..6007698
--- /dev/null
+++ b/release/tools/azure.conf
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# Set to a list of packages to install.
+# Example:
+#export VM_EXTRA_PACKAGES="www/apache24"
+export VM_EXTRA_PACKAGES="sysutils/azure-agent"
+
+# Set to a list of third-party software to enable in rc.conf(5).
+# Example:
+#export VM_RC_LIST="apache24"
+export VM_RC_LIST=
+
+vm_extra_pre_umount() {
+ chroot ${DESTDIR} ln -s /usr/local/sbin/waagent /usr/sbin/waagent
+ chroot ${DESTDIR} /usr/local/sbin/waagent -verbose -install
+ yes | chroot ${DESTDIR} /usr/local/sbin/waagent -deprovision
+ echo 'sshd_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'ifconfig_hn0="SYNCDHCP"' >> ${DESTDIR}/etc/rc.conf
+ echo 'waagent_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'console="comconsole vidconsole"' >> ${DESTDIR}/boot/loader.conf
+ echo 'comconsole_speed="115200"' >> ${DESTDIR}/boot/loader.conf
+
+ rm -f ${DESTDIR}/etc/resolv.conf
+
+ return 0
+}
diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf
new file mode 100644
index 0000000..557e602
--- /dev/null
+++ b/release/tools/ec2.conf
@@ -0,0 +1,88 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# Packages to install into the image we're creating. This is a deliberately
+# minimalist set, providing only the packages necessary to bootstrap further
+# package installation as specified via EC2 user-data.
+export VM_EXTRA_PACKAGES="ec2-scripts firstboot-freebsd-update firstboot-pkgs"
+
+# Set to a list of third-party software to enable in rc.conf(5).
+export VM_RC_LIST="ec2_configinit ec2_fetchkey ec2_ephemeralswap ec2_loghostkey firstboot_freebsd_update firstboot_pkgs"
+
+# Build with a 1.5 GB UFS partition; the growfs rc.d script will expand
+# the partition to fill the root disk after the EC2 instance is launched.
+# Note that if this is set to <N>G, we will end up with an <N+1> GB disk
+# image since VMSIZE is the size of the UFS partition, not the disk which
+# it resides within.
+export VMSIZE=1536M
+
+# No swap space; the ec2_ephemeralswap rc.d script will allocate swap
+# space on EC2 ephemeral disks. (If they exist -- the T2 low-cost instances
+# and the C4 compute-optimized instances don't have ephemeral disks. But
+# it would be silly to bloat the image and increase costs for every instance
+# just for those two families, especially since instances ranging in size
+# from 1 GB of RAM to 60 GB of RAM would need different sizes of swap space
+# anyway.)
+export NOSWAP=YES
+
+vm_extra_pre_umount() {
+ # The firstboot_pkgs rc.d script will download the repository
+ # catalogue and install or update pkg when the instance first
+ # launches, so these files would just be replaced anyway; removing
+ # them from the image allows it to boot faster.
+ env ASSUME_ALWAYS_YES=yes pkg -c ${DESTDIR} delete -f -y pkg
+ rm ${DESTDIR}/var/db/pkg/repo-*.sqlite
+
+ # The size of the EC2 root disk can be configured at instance launch
+ # time; expand our filesystem to fill the disk.
+ echo 'growfs_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+
+ # EC2 instances use DHCP to get their network configuration.
+ echo 'ifconfig_DEFAULT="SYNCDHCP"' >> ${DESTDIR}/etc/rc.conf
+
+ # Unless the system has been configured via EC2 user-data, the user
+ # will need to SSH in to do anything.
+ echo 'sshd_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+
+ # The AWS CLI tools are generally useful, and small enough that they
+ # will download quickly; but users will often override this setting
+ # via EC2 user-data.
+ echo 'firstboot_pkgs_list="awscli"' >> ${DESTDIR}/etc/rc.conf
+
+ # The EC2 console is output-only, so while printing a backtrace can
+ # be useful, there's no point dropping into a debugger or waiting
+ # for a keypress.
+ echo 'debug.trace_on_panic=1' >> ${DESTDIR}/etc/sysctl.conf
+ echo 'debug.debugger_on_panic=0' >> ${DESTDIR}/etc/sysctl.conf
+ echo 'kern.panic_reboot_wait_time=0' >> ${DESTDIR}/etc/sysctl.conf
+
+ # The console is not interactive, so we might as well boot quickly.
+ echo 'autoboot_delay="-1"' >> ${DESTDIR}/boot/loader.conf
+ echo 'beastie_disable="YES"' >> ${DESTDIR}/boot/loader.conf
+
+ # The EC2 console is an emulated serial port.
+ echo 'console="comconsole"' >> ${DESTDIR}/boot/loader.conf
+
+ # Some older EC2 hardware used a version of Xen with a bug in its
+ # emulated serial port. It is not clear if EC2 still has any such
+ # nodes, but apply the workaround just in case.
+ echo 'hw.broken_txfifo="1"' >> ${DESTDIR}/boot/loader.conf
+
+ # Some EC2 instances suffer a significant (~40%) reduction in
+ # throughput when using blkif indirect segment I/Os. Disable this
+ # by default for now.
+ echo 'hw.xbd.xbd_enable_indirect="0"' >> ${DESTDIR}/boot/loader.conf
+
+ # The first time the AMI boots, the installed "first boot" scripts
+ # should be allowed to run:
+ # * ec2_configinit (download and process EC2 user-data)
+ # * ec2_fetchkey (arrange for SSH using the EC2-provided public key)
+ # * growfs (expand the filesystem to fill the provided disk)
+ # * firstboot_freebsd_update (install critical updates)
+ # * firstboot_pkgs (install packages)
+ touch ${DESTDIR}/firstboot
+
+ return 0
+}
diff --git a/release/tools/gce.conf b/release/tools/gce.conf
new file mode 100644
index 0000000..082ac0d
--- /dev/null
+++ b/release/tools/gce.conf
@@ -0,0 +1,93 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# Set to a list of packages to install.
+export VM_EXTRA_PACKAGES="firstboot-freebsd-update firstboot-pkgs \
+ google-cloud-sdk google-daemon panicmail sudo firstboot-growfs \
+ google-startup-scripts"
+
+# Set to a list of third-party software to enable in rc.conf(5).
+export VM_RC_LIST="google_accounts_manager ntpd sshd firstboot_growfs \
+ firstboot_pkgs firstboot_freebsd_update google_startup"
+
+vm_extra_install_base() {
+ echo 'search google.internal' > ${DESTDIR}/etc/resolv.conf
+ echo 'nameserver 169.254.169.254' >> ${DESTDIR}/etc/resolv.conf
+ echo 'nameserver 8.8.8.8' >> ${DESTDIR}/etc/resolv.conf
+}
+
+vm_extra_pre_umount() {
+ cat << EOF >> ${DESTDIR}/etc/rc.conf
+dumpdev="AUTO"
+ifconfig_DEFAULT="SYNCDHCP mtu 1460"
+ntpd_sync_on_start="YES"
+# need to fill in something here
+#firstboot_pkgs_list=""
+panicmail_autosubmit="YES"
+EOF
+
+ cat << EOF >> ${DESTDIR}/boot/loader.conf
+autoboot_delay="-1"
+beastie_disable="YES"
+loader_logo="none"
+hw.memtest.tests="0"
+console="comconsole,vidconsole"
+hw.vtnet.mq_disable=1
+kern.timecounter.hardware=ACPI-safe
+aesni_load="YES"
+nvme_load="YES"
+EOF
+
+ echo '169.254.169.254 metadata.google.internal metadata' > \
+ ${DESTDIR}/etc/hosts
+
+ # overwrite ntp.conf
+ cat << EOF > ${DESTDIR}/etc/ntp.conf
+server metadata.google.internal iburst
+
+restrict default kod nomodify notrap nopeer noquery
+restrict -6 default kod nomodify notrap nopeer noquery
+
+restrict 127.0.0.1
+restrict -6 ::1
+restrict 127.127.1.0
+EOF
+
+ cat << EOF >> ${DESTDIR}/etc/syslog.conf
+*.err;kern.warning;auth.notice;mail.crit /dev/console
+EOF
+
+ cat << EOF >> ${DESTDIR}/etc/ssh/sshd_config
+ChallengeResponseAuthentication no
+X11Forwarding no
+AcceptEnv LANG
+Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
+AllowAgentForwarding no
+ClientAliveInterval 420
+EOF
+
+ cat << EOF >> ${DESTDIR}/etc/crontab
+0 3 * * * root /usr/sbin/freebsd-update cron
+EOF
+
+ cat << EOF >> ${DESTDIR}/etc/sysctl.conf
+net.inet.icmp.drop_redirect=1
+net.inet.ip.redirect=0
+net.inet.tcp.blackhole=2
+net.inet.udp.blackhole=1
+kern.ipc.somaxconn=1024
+debug.trace_on_panic=1
+debug.debugger_on_panic=0
+EOF
+
+ ## XXX: Verify this is needed. I do not see this requirement
+ ## in the docs, and it impairs the ability to boot-test a copy
+ ## of the image prior to packaging for upload to GCE.
+ #sed -E -i '' 's/^([^#].*[[:space:]])on/\1off/' ${DESTDIR}/etc/ttys
+
+ touch ${DESTDIR}/firstboot
+
+ return 0
+}
diff --git a/release/tools/openstack.conf b/release/tools/openstack.conf
new file mode 100644
index 0000000..5d188bb
--- /dev/null
+++ b/release/tools/openstack.conf
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# Set to a list of packages to install.
+export VM_EXTRA_PACKAGES="net/cloud-init devel/py-pbr devel/py-iso8601 \
+ net/py-eventlet net/py-netaddr comms/py-serial devel/py-six \
+ devel/py-babel net/py-oauth net/py-netifaces"
+
+# Set to a list of third-party software to enable in rc.conf(5).
+export VM_RC_LIST="cloudinit"
+
+vm_extra_pre_umount() {
+ echo 'sshd_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'ifconfig_DEFAULT="SYNCDHCP"' >> ${DESTDIR}/etc/rc.conf
+
+ # Openstack wants sudo(8) usable by default without a password.
+ echo 'ALL ALL=(ALL) NOPASSWD:ALL' >> \
+ ${DESTDIR}/usr/local/etc/sudoers.d/cloud-init
+
+ rm -f ${DESTDIR}/etc/resolv.conf
+
+ return 0
+}
diff --git a/release/tools/vagrant-virtualbox.conf b/release/tools/vagrant-virtualbox.conf
new file mode 100644
index 0000000..ff14674
--- /dev/null
+++ b/release/tools/vagrant-virtualbox.conf
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+. ${WORLDDIR}/release/tools/vagrant.conf
+
+export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} virtualbox-ose-additions"
+
+vm_extra_pre_umount () {
+ # VirtualBox first boot pkgs
+ echo 'firstboot_pkgs_list="sudo rsync virtualbox-ose-additions"' >> ${DESTDIR}/etc/rc.conf
+ echo 'vboxguest_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'vboxservice_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+
+ # Setup the Vagrant common items
+ vagrant_common
+}
diff --git a/release/tools/vagrant-vmware.conf b/release/tools/vagrant-vmware.conf
new file mode 100644
index 0000000..330892b
--- /dev/null
+++ b/release/tools/vagrant-vmware.conf
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+. ${WORLDDIR}/release/tools/vagrant.conf
+
+export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} open-vm-tools-nox11"
+
+vm_extra_pre_umount () {
+ # VMWare first boot pkgs
+ echo 'firstboot_pkgs_list="sudo rsync open-vm-tools-nox11"' >> ${DESTDIR}/etc/rc.conf
+
+ echo 'vmware_guest_vmblock_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'vmware_guest_vmhgfs_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'vmware_guest_vmmemctl_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'vmware_guest_vmxnet_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ echo 'vmware_guestd_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+
+ # Setup the Vagrant common items
+ vagrant_common
+}
diff --git a/release/tools/vagrant.conf b/release/tools/vagrant.conf
new file mode 100644
index 0000000..5617b96
--- /dev/null
+++ b/release/tools/vagrant.conf
@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# Packages to install into the image we're creating. This is a deliberately
+# minimalist set, providing only the packages necessary to bootstrap.
+export VM_EXTRA_PACKAGES="firstboot-freebsd-update firstboot-pkgs"
+
+# Set to a list of third-party software to enable in rc.conf(5).
+export VM_RC_LIST="firstboot_freebsd_update firstboot_pkgs"
+
+vagrant_common () {
+ # The firstboot_pkgs rc.d script will download the repository
+ # catalogue and install or update pkg when the instance first
+ # launches, so these files would just be replaced anyway; removing
+ # them from the image allows it to boot faster.
+ env ASSUME_ALWAYS_YES=yes pkg -c ${DESTDIR} clean -y -a
+ env ASSUME_ALWAYS_YES=yes pkg -c ${DESTDIR} delete -f -y pkg
+ rm ${DESTDIR}/var/db/pkg/repo-*.sqlite
+
+ # Vagrant instances use DHCP to get their network configuration.
+ echo 'ifconfig_DEFAULT="SYNCDHCP"' >> ${DESTDIR}/etc/rc.conf
+
+ # Enable sshd by default
+ echo 'sshd_enable="YES"' >> ${DESTDIR}/etc/rc.conf
+ # Disable DNS lookups by default to make SSH connect quickly
+ echo 'UseDNS no' >> ${DESTDIR}/etc/ssh/sshd_config
+
+ # Disable sendmail
+ echo 'sendmail_enable="NO"' >> ${DESTDIR}/etc/rc.conf
+ echo 'sendmail_submit_enable="NO"' >> ${DESTDIR}/etc/rc.conf
+ echo 'sendmail_outbound_enable="NO"' >> ${DESTDIR}/etc/rc.conf
+ echo 'sendmail_msp_queue_enable="NO"' >> ${DESTDIR}/etc/rc.conf
+
+ # Create the vagrant user with a password of vagrant
+ /usr/sbin/pw -R ${DESTDIR} \
+ groupadd vagrant -g 1001
+ chroot ${DESTDIR} mkdir -p /home/vagrant
+ /usr/sbin/pw -R ${DESTDIR} \
+ useradd vagrant \
+ -m -M 0755 -w yes -n vagrant -u 1001 -g 1001 -G 0 \
+ -c 'Vagrant User' -d '/home/vagrant' -s '/bin/csh'
+
+ # Change root's password to vagrant
+ echo 'vagrant' | /usr/sbin/pw -R ${DESTDIR} \
+ usermod root -h 0
+
+ # Configure sudo to allow the vagrant user
+ echo 'vagrant ALL=(ALL) NOPASSWD: ALL' >> ${DESTDIR}/usr/local/etc/sudoers
+
+ # Configure the vagrant ssh key
+ mkdir ${DESTDIR}/home/vagrant/.ssh
+ chmod 700 ${DESTDIR}/home/vagrant/.ssh
+ echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key" > ${DESTDIR}/home/vagrant/.ssh/authorized_keys
+ chown -R 1001 ${DESTDIR}/home/vagrant/.ssh
+ chmod 600 ${DESTDIR}/home/vagrant/.ssh/authorized_keys
+
+ # Reboot quickly, Don't wait at the panic screen
+ echo 'debug.trace_on_panic=1' >> ${DESTDIR}/etc/sysctl.conf
+ echo 'debug.debugger_on_panic=0' >> ${DESTDIR}/etc/sysctl.conf
+ echo 'kern.panic_reboot_wait_time=0' >> ${DESTDIR}/etc/sysctl.conf
+
+ # The console is not interactive, so we might as well boot quickly.
+ echo 'autoboot_delay="-1"' >> ${DESTDIR}/boot/loader.conf
+
+ # The first time the VM boots, the installed "first boot" scripts
+ # should be allowed to run:
+ # * growfs (expand the filesystem to fill the provided disk)
+ # * firstboot_freebsd_update (install critical updates)
+ # * firstboot_pkgs (install packages)
+ touch ${DESTDIR}/firstboot
+
+ return 0
+}
diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr
new file mode 100644
index 0000000..b5a8bf7
--- /dev/null
+++ b/release/tools/vmimage.subr
@@ -0,0 +1,234 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+#
+# Common functions for virtual machine image build scripts.
+#
+
+export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
+trap "cleanup" INT QUIT TRAP ABRT TERM
+
+write_partition_layout() {
+ if [ -z "${NOSWAP}" ]; then
+ SWAPOPT="-p freebsd-swap/swapfs::1G"
+ fi
+
+ _OBJDIR="$(make -C ${WORLDDIR} -V .OBJDIR)"
+ if [ -d "${_OBJDIR%%/usr/src}/${TARGET}.${TARGET_ARCH}" ]; then
+ BOOTFILES="/${_OBJDIR%%/usr/src}/${TARGET}.${TARGET_ARCH}/usr/src/sys/boot"
+ else
+ BOOTFILES="/${_OBJDIR}/sys/boot"
+ fi
+
+ case "${TARGET}:${TARGET_ARCH}" in
+ amd64:amd64 | i386:i386)
+ mkimg -s gpt -f ${VMFORMAT} \
+ -b ${BOOTFILES}/i386/pmbr/pmbr \
+ -p freebsd-boot/bootfs:=${BOOTFILES}/i386/gptboot/gptboot \
+ ${SWAPOPT} \
+ -p freebsd-ufs/rootfs:=${VMBASE} \
+ -o ${VMIMAGE}
+ ;;
+ arm64:aarch64)
+ mkimg -s mbr -f ${VMFORMAT} \
+ -p efi:=${BOOTFILES}/efi/boot1/boot1.efifat \
+ -p freebsd:=${VMBASE} \
+ -o ${VMIMAGE}
+ ;;
+ powerpc:powerpc*)
+ mkimg -s apm -f ${VMFORMAT} \
+ -p apple-boot/bootfs:=${BOOTFILES}/powerpc/boot1.chrp/boot1.hfs \
+ ${SWAPOPT} \
+ -p freebsd-ufs/rootfs:=${VMBASE} \
+ -o ${VMIMAGE}
+ ;;
+ *)
+ # ENOTSUPP
+ return 1
+ ;;
+ esac
+
+ return 0
+}
+
+err() {
+ printf "${@}\n"
+ cleanup
+ return 1
+}
+
+cleanup() {
+ if [ -c "${DESTDIR}/dev/null" ]; then
+ umount_loop ${DESTDIR}/dev 2>/dev/null
+ fi
+ umount_loop ${DESTDIR}
+ if [ ! -z "${mddev}" ]; then
+ mdconfig -d -u ${mddev}
+ fi
+
+ return 0
+}
+
+vm_create_base() {
+ # Creates the UFS root filesystem for the virtual machine disk,
+ # written to the formatted disk image with mkimg(1).
+
+ mkdir -p ${DESTDIR}
+ truncate -s ${VMSIZE} ${VMBASE}
+ mddev=$(mdconfig -f ${VMBASE})
+ newfs -L rootfs /dev/${mddev}
+ mount /dev/${mddev} ${DESTDIR}
+
+ return 0
+}
+
+vm_copy_base() {
+ # Creates a new UFS root filesystem and copies the contents of the
+ # current root filesystem into it. This produces a "clean" disk
+ # image without any remnants of files which were created temporarily
+ # during image-creation and have since been deleted (e.g., downloaded
+ # package archives).
+
+ mkdir -p ${DESTDIR}/old
+ mdold=$(mdconfig -f ${VMBASE})
+ mount /dev/${mdold} ${DESTDIR}/old
+
+ truncate -s ${VMSIZE} ${VMBASE}.tmp
+ mkdir -p ${DESTDIR}/new
+ mdnew=$(mdconfig -f ${VMBASE}.tmp)
+ newfs -L rootfs /dev/${mdnew}
+ mount /dev/${mdnew} ${DESTDIR}/new
+
+ tar -cf- -C ${DESTDIR}/old . | tar -xUf- -C ${DESTDIR}/new
+
+ umount_loop /dev/${mdold}
+ rmdir ${DESTDIR}/old
+ mdconfig -d -u ${mdold}
+
+ umount_loop /dev/${mdnew}
+ rmdir ${DESTDIR}/new
+ tunefs -n enable /dev/${mdnew}
+ mdconfig -d -u ${mdnew}
+ mv ${VMBASE}.tmp ${VMBASE}
+}
+
+vm_install_base() {
+ # Installs the FreeBSD userland/kernel to the virtual machine disk.
+
+ cd ${WORLDDIR} && \
+ make DESTDIR=${DESTDIR} \
+ installworld installkernel distribution || \
+ err "\n\nCannot install the base system to ${DESTDIR}."
+
+ echo '# Custom /etc/fstab for FreeBSD VM images' \
+ > ${DESTDIR}/etc/fstab
+ echo "/dev/${ROOTLABEL}/rootfs / ufs rw 1 1" \
+ >> ${DESTDIR}/etc/fstab
+ if [ -z "${NOSWAP}" ]; then
+ echo '/dev/gpt/swapfs none swap sw 0 0' \
+ >> ${DESTDIR}/etc/fstab
+ fi
+
+ mkdir -p ${DESTDIR}/dev
+ mount -t devfs devfs ${DESTDIR}/dev
+ chroot ${DESTDIR} /usr/bin/newaliases
+ chroot ${DESTDIR} /etc/rc.d/ldconfig forcestart
+ umount_loop ${DESTDIR}/dev
+
+ cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf
+
+ return 0
+}
+
+vm_extra_install_base() {
+ # Prototype. When overridden, runs extra post-installworld commands
+ # as needed, based on the target virtual machine image or cloud
+ # provider image target.
+
+ return 0
+}
+
+vm_extra_enable_services() {
+ if [ ! -z "${VM_RC_LIST}" ]; then
+ for _rcvar in ${VM_RC_LIST}; do
+ echo ${_rcvar}_enable="YES" >> ${DESTDIR}/etc/rc.conf
+ done
+ fi
+
+ return 0
+}
+
+vm_extra_install_packages() {
+ if [ -z "${VM_EXTRA_PACKAGES}" ]; then
+ return 0
+ fi
+ mkdir -p ${DESTDIR}/dev
+ mount -t devfs devfs ${DESTDIR}/dev
+ chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes \
+ /usr/sbin/pkg bootstrap -y
+ chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes \
+ /usr/sbin/pkg install -y ${VM_EXTRA_PACKAGES}
+ umount_loop ${DESTDIR}/dev
+
+ return 0
+}
+
+vm_extra_install_ports() {
+ # Prototype. When overridden, installs additional ports within the
+ # virtual machine environment.
+
+ return 0
+}
+
+vm_extra_pre_umount() {
+ # Prototype. When overridden, performs additional tasks within the
+ # virtual machine environment prior to unmounting the filesystem.
+ # Note: When overriding this function, removing resolv.conf in the
+ # disk image must be included.
+
+ rm -f ${DESTDIR}/etc/resolv.conf
+ return 0
+}
+
+vm_extra_pkg_rmcache() {
+ if [ -e ${DESTDIR}/usr/local/sbin/pkg ]; then
+ chroot ${DESTDIR} env ASSUME_ALWAYS_YES=yes \
+ /usr/local/sbin/pkg clean -y -a
+ fi
+
+ return 0
+}
+
+umount_loop() {
+ DIR=$1
+ i=0
+ sync
+ while ! umount ${DIR}; do
+ i=$(( $i + 1 ))
+ if [ $i -ge 10 ]; then
+ # This should never happen. But, it has happened.
+ echo "Cannot umount(8) ${DIR}"
+ echo "Something has gone horribly wrong."
+ return 1
+ fi
+ sleep 1
+ done
+
+ return 0
+}
+
+vm_create_disk() {
+ echo "Creating image... Please wait."
+ echo
+
+ write_partition_layout || return 1
+
+ return 0
+}
+
+vm_extra_create_disk() {
+
+ return 0
+}
+
OpenPOWER on IntegriCloud