summaryrefslogtreecommitdiff
path: root/sysutils/personality
diff options
context:
space:
mode:
authorAndreas Klemm <andreas@FreeBSD.org>2001-03-25 20:34:50 +0000
committerAndreas Klemm <andreas@FreeBSD.org>2001-03-25 20:34:50 +0000
commit6b34a8a9ea3afef3629ceb2f5b268a1e328daa4b (patch)
treed1d6aaddc25db2df7c2e3e90fa296246fb0d4cc2 /sysutils/personality
parentSet PORTREVISION because of new files/patch-reply.c. It looks as (diff)
new port of Michael Smith's personality script
personality manages different system configurations
Notes
Notes: svn path=/head/; revision=40370
Diffstat (limited to 'sysutils/personality')
-rw-r--r--sysutils/personality/Makefile32
-rw-r--r--sysutils/personality/pkg-comment1
-rw-r--r--sysutils/personality/pkg-descr21
-rw-r--r--sysutils/personality/pkg-message8
-rw-r--r--sysutils/personality/pkg-plist1
-rw-r--r--sysutils/personality/src/personality536
-rw-r--r--sysutils/personality/src/personality.872
7 files changed, 671 insertions, 0 deletions
diff --git a/sysutils/personality/Makefile b/sysutils/personality/Makefile
new file mode 100644
index 000000000000..93cdaeeb9c94
--- /dev/null
+++ b/sysutils/personality/Makefile
@@ -0,0 +1,32 @@
+# New ports collection makefile for: personality
+# Date created: 25 Mar 2001
+# Whom: Andreas Klemm <andreas@FreeBSD.org>
+#
+# $FreeBSD$
+#
+
+PORTNAME= personality
+PORTVERSION= 1.0
+CATEGORIES= sysutils
+DISTFILES= # none
+
+MAINTAINER= andreas@FreeBSD.org
+
+WRKSRC= ${WRKDIR}/src
+NO_BUILD= YES
+
+do-extract:
+ @ ${RM} -rf ${WRKDIR}
+ @ ${MKDIR} ${WRKDIR}
+ @ ${CP} -RP ${.CURDIR}/src ${WRKDIR}
+
+MAN8= personality.8
+
+do-install:
+ @ ${INSTALL_SCRIPT} ${WRKSRC}/personality ${PREFIX}/sbin
+ @ ${INSTALL_DATA} ${WRKSRC}/personality.8 ${PREFIX}/man/man8
+
+post-install:
+ @ ${CAT} ${.CURDIR}/pkg-message
+
+.include <bsd.port.mk>
diff --git a/sysutils/personality/pkg-comment b/sysutils/personality/pkg-comment
new file mode 100644
index 000000000000..c1db3d268ca2
--- /dev/null
+++ b/sysutils/personality/pkg-comment
@@ -0,0 +1 @@
+System configuration management utility to alter system personality
diff --git a/sysutils/personality/pkg-descr b/sysutils/personality/pkg-descr
new file mode 100644
index 000000000000..ec52a04bd2d3
--- /dev/null
+++ b/sysutils/personality/pkg-descr
@@ -0,0 +1,21 @@
+This script provides functionality for manipulating collections of
+configuration files which can be organised so as to alter the
+personality of a system.
+
+Initially, the "base" personality is established. This personality
+contains the "reference" copies of configuration files, and is used
+when creating new personalities. The files which are currently
+considered part of the system's personality are those contained in
+the base personality.
+
+A new personality is established by making a copy of the base
+personality under a new name. Each personality maintains a separate
+copy of all configuration files under /etc/personality.
+
+To install a new personality, the files currently in place are
+saved back to the current personality as indicated in
+/etc/personality/current, and the files for the new personality
+copied into place. The 'select' and 'menu' commands which perform
+these installations are implemented in such a fashion as to only
+require the tools available on the root filesystem, so that they
+may be invoked at the earliest stage during system startup.
diff --git a/sysutils/personality/pkg-message b/sysutils/personality/pkg-message
new file mode 100644
index 000000000000..68041d109a3c
--- /dev/null
+++ b/sysutils/personality/pkg-message
@@ -0,0 +1,8 @@
+To change the personality of your system at system boot
+you have to add the following line into the /etc/rc script.
+
+[ -x /usr/local/sbin/personality ] && /usr/local/sbin/personality menu 60
+
+Make sure that you add this after mounting of the ufs filesystems.
+If you prefer you can use other values than 60 seconds.
+After 60 seconds the system boots with the last configuration.
diff --git a/sysutils/personality/pkg-plist b/sysutils/personality/pkg-plist
new file mode 100644
index 000000000000..5d1b869aca3e
--- /dev/null
+++ b/sysutils/personality/pkg-plist
@@ -0,0 +1 @@
+sbin/personality
diff --git a/sysutils/personality/src/personality b/sysutils/personality/src/personality
new file mode 100644
index 000000000000..e20f373a0e60
--- /dev/null
+++ b/sysutils/personality/src/personality
@@ -0,0 +1,536 @@
+#! /bin/sh
+##############################################################################
+#
+# Copyright (c) 1997 Michael Smith
+# 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 script provides functionality for manipulating collections of
+# configuration files which can be organised so as to alter the
+# personality of a system.
+#
+# Initially, the "base" personality is established. This personality
+# contains the "reference" copies of configuration files, and is used
+# when creating new personalities. The files which are currently
+# considered part of the system's personality are those contained in
+# the base personality.
+#
+# A new personality is established by making a copy of the base
+# personality under a new name. Each personality maintains a
+# separate copy of all configuration files under /etc/personality.
+#
+# To install a new personality, the files currently in place are
+# saved back to the current personality as indicated in
+# /etc/personality/current, and the files for the new personality
+# copied into place. The 'select' and 'menu' commands which perform
+# these installations are implemented in such a fashion as to only
+# require the tools available on the root filesystem, so that they
+# may be invoked at the earliest stage during system startup.
+#
+# If the current personality has become damaged, it can be restored
+# from the saved copy.
+#
+# Files can be added to and removed from the personality set. When
+# a new file is added, it is copied from the current system into all
+# personalities and added to the list file. When a file is removed
+# the current version is kept in place, but all copies are removed
+# from saved personalities and the file is removed from the list.
+#
+# XXX To Do :
+# Files can be inherited by one personality from another. This is
+# simply achieved by copying the relevant files under /etc/personality,
+# and into the current system if required.
+#
+##############################################################################
+
+# Establish some global constants
+P_ROOT=/etc/personality
+#P_ROOT=/tmp/personality
+P_BASE="${P_ROOT}/_base"
+P_CURRENT="${P_ROOT}/current"
+P_FILES="${P_ROOT}/files"
+P_LIST="${P_ROOT}/list"
+scriptname="$0"
+
+##############################################################################
+# pers_main
+#
+# Execution begins here after the file has been read.
+#
+pers_main()
+{
+ case "$1" in
+ menu)
+ pers_menu $2 $3
+ ;;
+ select)
+ pers_select $2
+ ;;
+ restore)
+ pers_restore
+ ;;
+ save)
+ pers_save
+ ;;
+ saveas)
+ pers_saveas $2
+ pers_reindex
+ ;;
+ create)
+ pers_create $2
+ pers_reindex
+ ;;
+ delete)
+ pers_delete $2
+ pers_reindex
+ ;;
+ add)
+ pers_add $2
+ pers_reindex
+ ;;
+ list)
+ pers_list
+ ;;
+ remove)
+ pers_remove $2
+ pers_reindex
+ ;;
+ init)
+ pers_init
+ pers_reindex
+ ;;
+ *)
+ usage
+ ;;
+ esac
+}
+
+##############################################################################
+# pers_menu
+#
+# Present a menu of currently-selectable personalities, assign hotkeys,
+# describe the default and optionally go with the default after a timeout
+#
+pers_menu()
+{
+ # Look and see if there's actually anything to work with
+ if [ ! -d "${P_ROOT}" ]; then
+ return
+ fi
+
+ # Pick up a timeout if specified, default to 10 seconds
+ timeout=10
+ if [ ! -z "$1" ]; then
+ timeout="$1"
+ fi
+
+ # Assign a default, if suitable
+ defpers=""
+ defname="<none>"
+ if [ -f "${P_CURRENT}" ]; then
+ defpers=`cat "${P_CURRENT}"`
+ defname="${defpers}"
+ fi
+
+ # Loop prompting/reading input until we get a result
+ while :; do
+
+ # Print menu
+ echo "";
+ echo "Select System Personality"
+ echo "========================="
+ hkey=0
+ for pers in `cat "${P_LIST}"`; do
+ echo " ${hkey}) ${pers}"
+ eval index_${hkey}="${pers}"
+ hkey=`expr ${hkey} + 1`
+ done
+ echo "";
+
+ echo " Default : ${defname}"
+ read -t "${timeout}" -p " Selection : " input
+ eval selvar=\$index_"${input}"
+ selpers=""
+ if [ -z "${input}" ]; then
+ selpers="${defpers}"
+ break
+ elif [ -n "${selvar}" ]; then
+ selpers="${selvar}"
+ break
+ elif [ -d "${P_ROOT}/_${input}" ]; then
+ selpers="${input}"
+ break
+ fi
+ done
+
+ # $selpers now contains the personality we wish to select,
+ # or is empty if we selected the default when there was none
+ if [ -z "${selpers}" ]; then
+ return
+ fi
+
+ # select the personality nominated
+ pers_select "${selpers}"
+}
+
+##############################################################################
+# pers_select
+#
+# Copy the files from the nominated personality out of the repository
+# into the real system. Note that this must be able to run with
+# nothing other than the contents of /bin available.
+#
+pers_select()
+{
+ src="${P_ROOT}/_$1";
+ if [ ! -d "${src}" ]; then
+ fail "no such personality '$1'"
+ fi
+
+ # Iterate over the file listing, copy them all out
+ for file in `cat "${P_FILES}"`; do
+ cp -p "${src}/${file}" "${file}"
+ done
+
+ # Register this personality as being current
+ echo "$1" > "${P_CURRENT}"
+}
+
+##############################################################################
+# pers_restore
+#
+# Reload the configuration files for the current personality, eliminating
+# any changes that may have been made.
+#
+pers_restore()
+{
+ if [ ! -e "${P_CURRENT}" ]; then
+ fail "no personality currently active"
+ fi
+
+ # Check that the current personality exists
+ pers=`cat "${P_CURRENT}"`
+ src="${P_ROOT}/_${pers}"
+ if [ ! -d "${src}" ]; then
+ fail "current personality '${pers}' not in the repository!"
+ fi
+
+ # Iterate over the file listing, copy them all out
+ for file in `cat "${P_FILES}"`; do
+ cp -p "${src}/${file}" "${file}"
+ done
+}
+
+##############################################################################
+# pers_save
+#
+# If a personality is current, save the current set of files to that
+# personality.
+#
+pers_save()
+{
+ if [ ! -e "${P_CURRENT}" ]; then
+ fail "no personality currently active"
+ fi
+
+ # Check that the current personality exists
+ pers=`cat "${P_CURRENT}"`
+ dest="${P_ROOT}/_${pers}"
+ if [ ! -d "${dest}" ]; then
+ fail "current personality '${pers}' not in the repository!"
+ fi
+
+ # OK, go ahead and save stuff. If this fails, we're
+ # moderately stuffed, so don't worry about it.
+ for file in `cat "${P_FILES}"`; do
+ stub=`dirname "${file}"`
+ mkdir -p "${dest}/${stub}"
+ cp -p "${file}" "${dest}/${file}"
+ done
+}
+
+##############################################################################
+# pers_saveas
+#
+# Take the currently-active set of configuration files, and save them as
+# a new personality, set the new personality as current.
+#
+pers_saveas()
+{
+ dest="${P_ROOT}/_$1"
+ if [ -e "${dest}" ]; then
+ fail "cannot create new personality '$1', name already in use"
+ fi
+
+ # Create the personality directory
+ mkdir -p "${dest}" || pers_saveas_fail "$1"
+
+ # iterate over files to save, copy them in
+ for file in `cat "${P_FILES}"`; do
+ stub=`dirname "${file}"`
+ mkdir -p "${dest}/${stub}"
+ cp -p "${file}" "${dest}/${file}" || pers_saveas_fail $1
+ done
+
+ # new personality is current
+ echo "$1" > "${P_CURRENT}"
+}
+
+########################################
+# pers_saveas_fail
+#
+# The 'save as' operation failed. Clean
+# up and emit a failure message.
+#
+pers_saveas_fail()
+{
+ rm -Rf "${P_ROOT}/_$1"
+ fail "could not save current personality as '$1'"
+}
+
+##############################################################################
+# pers_create
+#
+# Create a new personality, duplicated from the current base personality
+#
+pers_create()
+{
+ if [ -e "${P_ROOT}/_$1" ]; then
+ fail "cannot create new personality '$1', name already in use"
+ fi
+
+ # Ok, duplicate it
+ cp -Rp "${P_BASE}" "${P_ROOT}/_$1" || pers_create_fail "$1"
+}
+
+########################################
+# pers_create_fail
+#
+# An attempt to create a personality failed.
+# Clean up and exit with an error message.
+#
+pers_create_fail()
+{
+ rm -Rf "${P_ROOT}/_$1"
+ fail "'$1' could not be created"
+}
+
+##############################################################################
+# pers_delete
+#
+# Remove a personality from the system. It is legitimate to remove
+# the current personality.
+#
+pers_delete()
+{
+ if [ ! -e "${P_ROOT}/_$1" ]; then
+ fail "no such personality '$1' to remove"
+ fi
+ if [ "$1" = _base ]; then
+ fail "cannot remove base personality"
+ fi
+
+ # If the requested personality is current, remove the
+ # reference.
+ if [ -e "${P_CURRENT}" ]; then
+ if [ `cat "${P_CURRENT}"` = "$1" ]; then
+ rm -f "${P_CURRENT}"
+ fi
+ fi
+
+ # Remove the repository entry
+ rm -Rf "${P_ROOT}/_$1";
+
+ # Make sure it's gone
+ if [ -e "${P_ROOT}/_$1" ]; then
+ fail "failed to completely remove personality '$1'";
+ fi
+}
+
+##############################################################################
+# pers_add
+#
+# Add a new file to the system; copy it from the 'real' path into
+# each personality directory. Check first to make sure it's not already
+# part of the system, and check that the path supplied is absolute.
+#
+# The file is stored with its full path relative to the repository
+# directory.
+#
+pers_add()
+{
+ if [ ! -r "/$1" ]; then
+ fail "cannot read '$1' to add to the Personality System"
+ fi
+ if [ -e "${P_BASE}/$1" ]; then
+ fail "file '$1' already part of the Personality System"
+ fi
+ if [ ! -f "$1" ]; then
+ fail "only files can be added to the Personality System"
+ fi
+
+ # looks OK, copy it in
+ stub=`dirname "$1"`
+ for targ in ${P_ROOT}/_*; do
+ mkdir -p "${targ}/${stub}"
+ cp -p "$1" "${targ}/${stub}" || pers_add_fail "$1";
+ done
+}
+
+########################################
+# pers_add_fail
+#
+# A failure occurred while adding a file to
+# the repository; back out any copies that
+# made it in and abort with an error.
+#
+pers_add_fail()
+{
+ for cand in ${P_ROOT}/_*; do
+ if [ -f "${cand}/$1" ]; then
+ rm -f "${cand}/$1";
+ fi
+ done
+ fail "'$1' could not be added";
+}
+
+##############################################################################
+# pers_remove
+#
+# Remove a file from all personalities in the repository.
+#
+pers_remove()
+{
+ if [ ! -f "${P_BASE}/$1" ]; then
+ fail "'$1' is not part of the Personality System";
+ fi
+
+ # OK, it should be there; nuke whatever we can find
+ for cand in ${P_ROOT}/_*; do
+ if [ -f "${cand}/$1" ]; then
+ rm -f "${cand}/$1";
+ fi
+ done
+}
+
+##############################################################################
+# pers_list
+#
+# List all of the files that comprise the system personality.
+#
+pers_list()
+{
+ echo "Current personalities:"
+ for pers in `cat "${P_LIST}"`; do
+ echo " ${pers}";
+ done
+ echo "Files in system personality:"
+ for file in `cat "${P_FILES}"`; do
+ echo " ${file}"
+ done
+}
+
+##############################################################################
+# pers_init
+#
+# Initialise the personality collection; refuse to do so if there is
+# already one in place, or something else occupying the root path.
+#
+pers_init()
+{
+ if [ -e "${P_ROOT}" ]; then
+ fail "cannot initialise, '${P_ROOT}' already exists"
+ fi
+
+ # Create the repository with no files, and no current personality
+ mkdir -p "${P_ROOT}"
+ mkdir -p "${P_BASE}"
+}
+
+##############################################################################
+# pers_reindex
+#
+# Clean out any empty directories in the repository. This is achieved
+# by silently trying to rmdir everything that looks like a directory
+# under any personality.
+#
+# Then rebuild the list of files that comprise the system personality,
+# so that the select and menu functions work.
+#
+pers_reindex()
+{
+ # Remove empty directories
+ for cand in ${P_ROOT}/_*; do
+ find -dX "${cand}/." -type d | xargs rmdir >/dev/null 2>&1
+ done
+
+ # Regenerate the files list
+ find -X "${P_BASE}" -type f | sed "s%${P_BASE}%%" > "${P_FILES}"
+ # regenerate the personalities list
+ ls -d "${P_ROOT}/_"* | sed "s%${P_ROOT}/_%%" > "${P_LIST}"
+}
+
+##############################################################################
+# usage
+#
+# Emit a (hopefully) helpful diagnostic and exit
+#
+usage()
+{
+ echo "${scriptname}: incorrect argument(s)"
+ echo ""
+ echo " Usage is ${scriptname} <command>, where valid commands are :"
+ echo " menu [<timeout>] Invoke the menu-driven personality selector"
+ echo " select <personality> Select a specific personality"
+ echo " restore Restore the current personality from the saved version"
+ echo " save Save the current personality"
+ echo " saveas <personality> Save the current personality under a new name"
+ echo " create <personality> Create a new personality from the base"
+ echo " delete <personality> Delete a personality"
+ echo " add <full path> Add a new file"
+ echo " remove <full path> Remove a file"
+ echo " list List all files"
+ echo " init Initialise the Personality System"
+ echo ""
+ exit 2;
+}
+
+##############################################################################
+# fail
+#
+# Emit an error message to stderr and exit
+#
+fail ()
+{
+ echo "${scriptname}: $1";
+ exit 1;
+}
+
+##############################################################################
+# Now we have parsed everything, start.
+pers_main $1 $2 $3 $4;
+exit 0;
diff --git a/sysutils/personality/src/personality.8 b/sysutils/personality/src/personality.8
new file mode 100644
index 000000000000..46f8690d9ee7
--- /dev/null
+++ b/sysutils/personality/src/personality.8
@@ -0,0 +1,72 @@
+.\" Copyright (c) 2000
+.\" Andreas Klemm <andreas@FreeBSD.org>. All rights reserved.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 25, 2001
+.Dt PERSONALITY 1
+.Os
+.Sh NAME
+.Nm personality
+.Nd system configuration management utility
+.Sh SYNOPSIS
+.Nm personality
+.Op options ...
+.Sh DESCRIPTION
+This script provides functionality for manipulating collections of
+configuration files which can be organised so as to alter the
+personality of a system.
+.Pp
+Initially, the
+.Ic base
+personality is established. This personality contains the
+.Ic reference
+copies of configuration files, and is used when creating new personalities.
+The files which are currently considered part of the system's personality
+are those contained in the base personality.
+.Pp
+A new personality is established by making a copy of the base personality
+under a new name. Each personality maintains a separate copy of all
+configuration files under
+.Ic /etc/personality .
+.Pp
+To install a new personality, the files currently in place are saved back
+to the current personality as indicated in
+.Ic /etc/personality/current ,
+and the files for the new personality copied into place.
+.Pp
+The
+.Ic select
+and
+.Ic menu
+commands which perform these installations are implemented in such a
+fashion as to only require the tools available on the root filesystem,
+so that they may be invoked at the earliest stage during system startup.
+.Pp
+If the current personality has become damaged, it can be restored
+from the saved copy.
+.Pp
+Files can be added to and removed from the personality set. When a new
+file is added, it is copied from the current system into all personalities
+and added to the list file. When a file is removed the current version is
+kept in place, but all copies are removed from saved personalities and the
+file is removed from the list.
+.Sh FILES
+.Bl -tag -width /etc/personality/current -compact
+.It Pa /etc/personality
+configuration base
+.It Pa /etc/personality/_base
+system files under management of personality
+.It Pa /etc/personality/current
+backup location of current files before new personality is copied into place
+.Sh SEE ALSO
+.Xr rc 8
+.Sh BUGS
+Currently none.
+.Sh HISTORY
+The
+.Nm
+script has been written 1997 by Mike Smith <msmith@FreeBSD.org>.
+The
+.Nm
+manual page has been written by Andreas Klemm <andreas@FreeBSD.org>.