diff options
Diffstat (limited to 'release')
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; ¢rino; Duo and ¢rino; 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 + É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&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—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—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; 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">${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>$2b$</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 $2y$ 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 ™ 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 ™.</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 + ${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 ® + touchpads and the ClickPad ® mouse on newer + Lenovo ™ 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™ + Wireless-N 135 chipset has been added.</para> + + <para revision="260552">Firmware for &intel; Centrino™ + 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; 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™ + 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; MacMini 3,1.</para> + + <para revision="268351">Support for &os;/ia64 has been dropped + as of &os; 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 ®.</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; 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™ 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 X™ + and Solaris™. 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 ™ 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> </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; 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; Ports + Collection, package infrastructure, and package maintenance and + installation tools.</para> + + <sect2 xml:id="ports-infrastructure"> + <title>Infrastructure Changes</title> + + <para> </para> + </sect2> + + <sect2 xml:id="ports-packages "> + <title>Packaging Changes</title> + + <para> </para> + </sect2> + </sect1> + + <sect1 xml:id="doc"> + <title>Documentation</title> + + <para>This section covers changes to the &os; Documentation + Project sources and toolchain.</para> + + <sect2 xml:id="doc-sources"> + <title>Documentation Source Changes</title> + + <para> </para> + </sect2> + + <sect2 xml:id="doc-toolchain"> + <title>Documentation Toolchain Changes</title> + + <para> </para> + </sect2> + </sect1> + + <sect1 xml:id="releng"> + <title>Release Engineering and Integration</title> + + <para>This section convers changes that are specific to the + &os; 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 <<a href="mailto:questions@FreeBSD.org">questions@FreeBSD.org</a>>.</small></p> + + <p align="center"><small>All users of FreeBSD <xsl:value-of select="$release.branch"/> should + subscribe to the <<a href="mailto:{$release.maillist}@FreeBSD.org"><xsl:value-of select="$release.maillist"/>@FreeBSD.org</a>> + mailing list.</small></p> + + <p align="center"><small>For questions about this documentation, + e-mail <<a href="mailto:doc@FreeBSD.org">doc@FreeBSD.org</a>>.</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 & since jade seems to + # be confused when it is encoded as & inside an entity. + $l =~ s/&/&/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/'/‘/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> </para></entry> + <entry><para> </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&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> </para></entry> + <entry><para> </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&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 &os; 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 & 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 @@ +============================================================== + + [31m)\_)\[37m Welcome to PicoBSD + [31m([37m[1mo,o[m[31m)[37m + [32m__ [31m\~/[37m + [32m-->=[41m===[0m[31m\[37m + [32m~~[37m [31md d[37m + +============================================================== 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 Binary files differnew file mode 100644 index 0000000..0c5d3ed --- /dev/null +++ b/release/picobsd/tinyware/view/fbsd.png 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 +} + |