#!/bin/sh
#
# $Id: cdroot_inst,v 1.6 2002/08/09 22:50:54 bsd Exp $
#
# Copyright 2001, 2002  Brian S. Dean <bsd@bsdhome.com>
# 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 BRIAN S. DEAN ``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 BRIAN S. DEAN 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.
# 

ckrc() {
  rc=$?
  if [ "$rc" -ne 0 ]; then
    echo
    echo "$0: $1; rc=$rc"
    echo
    exit 1
  fi
}

getyn() {
  case "$yn" in
    [yY][eE][sS]|[yY])
      echo "YES"
      ;;
    *)
      echo "NO"
      ;;
  esac
}

answset() {
  if [ -n "$NO_INPUT" ]; then
    echo "$2 [$1]"
    answ=$1
  else
    answ=X
  fi
}

yesno() {
  answset $1 "$2"
  while [ $answ = X ]; do
    echo -n "$2 [$1] "
    read answ
    if [ X$answ = X ]; then answ=$1; fi
    case $answ in
      y|yes|Y|YES) answ=YES;;
      n|no|N|NO)   answ=NO;;
      *) echo invalid answer
      answ=X
      ;;
    esac
  done
}

respond() {
  eval var="$1"
  eval var_val=\${$var}
  answset ${var_val} "$2"
  while [ "$answ" = X ]; do
    echo -n "$2 [$var_val] "
    read answ
    if [ "X$answ" = X ]; then answ="$var_val"; fi
  done
  eval ${var}="\$answ"
}

responddef() {
  eval var="$1"
  eval var_val="\$2"
  answset ${var_val} "$3"
  while [ "$answ" = X ]; do
    echo -n "$3 [$var_val] "
    read answ
    if [ "X$answ" = X ]; then answ="$var_val"; fi
  done
  eval ${var}="\$answ"
}


#
# Defaults
#
DISK=`(dmesg | grep -E '^ar0:';   \
       dmesg | grep -E '^ad0:';   \
       dmesg | grep -E '^da0:') | \
       head -1 | cut -f1 -d:`
DISK=${DISK:-NODEFAULTDISK}

PARTITIONS="root:a:128 swap:b:4096 var:e:4096 tmp:f:2048 usr:g:0"
MEDIA="LOCAL"


P=""
args=`getopt d:s:m: $*`
if [ "$?" -ne 0 ]; then
  usage
  exit 1
fi

set -- $args
for i; do
  case "$i" in
    -d)
      DISK=$2;
      shift; shift
      ;;
    -s)
      P="$P $2"
      shift; shift
      ;;
    -m)
      MEDIA="$2"
      shift; shift
      ;;
    --)
      shift;
      break;
      ;;
  esac
done

#P=""
##
## Allow command line overrides
##
#while [[ "$1" = +(-*) ]]; do
#  case $1 in
#    -d)
#      DISK=$2;
#      shift; shift
#      ;;
#    -s)
#      P="$P $2"
#      shift; shift
#      ;;
#    -m)
#      MEDIA="$2"
#      shift; shift
#      ;;
#    *)
#      echo "$0: unknown option $1"
#      usage
#      exit 1
#      ;;
#  esac
#done

if [ -n "$P" ]; then
  PARTITIONS="$P"
fi

echo "DISK       = $DISK"
echo "PARTITIONS = $PARTITIONS"
echo "MEDIA      = $MEDIA"
#exit 1

df -t ufs | grep /dev/${DISK} > /dev/null 2>&1
rc=$?
if [ "$rc" -eq 0 ]; then
  echo
  echo "$0: disk ${DISK} is already mounted.  Unmount ${DISK} and try again."
  echo
  exit 1
fi


cat <<EOF

This program will install FreeBSD onto your hard disk.  This CD
contains a FreeBSD installation which you may use.  You can also
install a different installation if it is available via NFS.

The default disk and paritioning is as follows:

    DISK       = $DISK
    PARTITIONS = $PARTITIONS
    MEDIA      = $MEDIA

If you wish to change these, exit now and specify:

  -d <DISK> -s <PARTITION_1> -s <PARTITION_2> ... -s <PARTITION_N> -m <MEDIA_OPTIONS>

on the command line.

MEDIA_OPTIONS may be:

    "NFS host:/path-to-top-of-nfs-install"
or
    "LOCAL"

EOF

yesno YES "Do you wish to continue?"
if [ "$answ" = "NO" ]; then
  echo
  echo "Installation aborted."
  echo
  exit 1
fi




get_network_info() {
  CDROOT_NETIF=""
  NET_INTERFACES=`ifconfig -l`
  if [ -n "$NET_INTERFACES" ]; then
    CDROOT_NETIF=`echo "$NET_INTERFACES" | cut -f1 -d' '`
  fi
  CDROOT_CONFIG_NETWORK=NO

  if [ -n "$CDROOT_NETIF" ]; then
    echo "I see you have a network interface ($CDROOT_NETIF)"
    yesno YES "Do you wish to configure it?"
    if [ "$answ" = "YES" ]; then
      CDROOT_CONFIG_NETWORK=YES
      CDROOT_HOST=""
      CDROOT_IP=""
      CDROOT_NETMASK=""
      CDROOT_DEFROUTE=""
      fini=0
      while [ $fini -eq 0 ]; do
        echo
        respond CDROOT_HOST "Enter hostname          >"
        respond       CDROOT_IP "Enter ip address        >"
        respond  CDROOT_NETMASK "Enter network mask      >"
        respond CDROOT_DEFROUTE "Enter default route     >"
        respond  CDROOT_NAMESRV "Enter nameserver        >"
        respond    CDROOT_NETIF "Enter network interface >"
        cat <<EOF
  
      Hostname          = $CDROOT_HOST
      IP Address        = $CDROOT_IP
      Network Mask      = $CDROOT_NETMASK
      Default Route     = $CDROOT_DEFROUTE
      Nameserver        = $CDROOT_NAMESRV
      Network Interface = $CDROOT_NETIF
  
EOF
  
        yesno YES "Is this correct?"
        if [ "$answ" = YES ]; then
          fini=1
        fi
      done
    else
      CDROOT_CONFIG_NETWORK=NO
      echo "Not configuring a network."
    fi
  fi
  
  echo
}


if [ -f /etc/cdroot_site_overrides ]; then
  echo "Sourcing site overrides ..."
  . /etc/cdroot_site_overrides
fi


get_network_info


if [ "$CDROOT_CONFIG_NETWORK" = "YES" ]; then
  echo "Attempting to configure your network interface"
  ifconfig $CDROOT_NETIF $CDROOT_IP netmask $CDROOT_NETMASK
  rc=$?
  if [ "$rc" -ne 0 ]; then
    echo "Failed to configure $CDROOT_NETIF"
    exit 1
  fi
  if [ -n "$CDROOT_DEFROUTE" ]; then
    route add default $CDROOT_DEFROUTE
    rc=$?
    if [ "$rc" -ne 0 ]; then
      echo "Failed to add default route $CDROOT_DEFROUTE"
      exit 1
    fi
  fi
  if [ -n "$CDROOT_NAMESRV" ]; then
    echo "nameserver $CDROOT_NAMESRV" > /etc/resolv.conf
  fi
fi




#
# make sure the needed device nodes are in /dev
#
if [ ! -c /dev/${DISK} ]; then
  (cd /dev && sh MAKEDEV ${DISK})
fi

if [ ! -c /dev/${DISK}s1 ]; then
  (cd /dev && sh MAKEDEV ${DISK}s1)
fi

if [ ! -c /dev/${DISK}s1a ]; then
  (cd /dev && sh MAKEDEV ${DISK}s1a)
fi

/etc/cdroot_initdisk -F $DISK $PARTITIONS
ckrc "failed to initialize disk $DISK"

#
# generate parition arrays
#
i=0
for p in $PARTITIONS; do
  sln=`echo $p | cut -f1 -d:`
  sla=`echo $p | cut -f2 -d:`
  slz=`echo $p | cut -f3 -d:`
  eval slname_${i}="$sln"
  eval slsize_${i}="$slz"
  eval slslic_${i}="$sla"
  i=`expr $i + 1`
done
N_SLICES=$i


#
# mount requested partitions
#
i=0
while [ $i -ne $N_SLICES ]; do
  eval n=\${slname_${i}}
  case $n in
    root)
      mp=/mnt
      ;;
    swap)
      mp=none
      ;;
    *)
      eval mp=/mnt/\${slname_${i}}
      ;;
  esac

  eval DEV=/dev/${DISK}s1\${slslic_${i}}

  if [ "$n" != "swap" ]; then
    if [ ! -d "$mp" ]; then
      rm -f $mp
      mkdir -p $mp
    fi
    eval s=\${slslic_${i}}
    if [ "$s" != "a" ]; then
      echo "Enabling softupdates on $mp"
      tunefs -n enable $DEV
    fi
    echo "mounting $mp"
    mount $DEV $mp
    ckrc "failed to mount $n $DEV on $mp"
  else
    echo "configuring swap on $DEV"
    swapon $DEV
    ckrc "failed to configure swap on $DEV"
  fi

  i=`expr $i + 1`
done

#
# Specify the install destination
#
DESTDIR=/mnt

if [ "$MEDIA" = "LOCAL" ]; then
  MEDIA_PATH=/dist
else
  NFS_TARGET=`echo "$MEDIA" | cut -f2 -d' '`
  mount $NFS_TARGET /dist
  rc=$?
  if [ "$rc" -ne 0 ]; then
    echo "Failed to NFS mount $NFS_TARGET"
    exit 1
  fi
fi

DISTDIR=/dist

if [ -f /etc/install/dists.dat ]; then
  DISTDIRS=`cat /etc/install/dists.dat`
else
  DISTDIRS="bin catpages compat22 compat3x compat4x crypto dict \
	    doc games info manpages proflibs src ports"
fi


installdistdir () {
  if [ -z "${DESTDIR}" ]; then
    echo "Internal error: DESTDIR not set in 'installdistdir()'"
    return 1
  fi
  case $1 in
    src)
      DEST=$DESTDIR/usr/src
      ;;
    *)
      DEST=$DESTDIR
      ;;
  esac
  (cd $DISTDIR/$1 &&                                           \
   echo "+ $1 ..." &&                                          \
   if [ ! -d $DEST ]; then                                     \
     mkdir -p $DEST;                                           \
   fi &&                                                       \
   for i in *.mtree; do                                        \
     if [ -f "$i" ]; then                                      \
       echo "  - mtree $i";                                    \
       mtree -deUq -f $i -p ${DEST}/ > /dev/null 2>&1;         \
       rc=$?;                                                  \
       if [ "$rc" -ne 0 ]; then                                \
         echo "WARNING: mtree -f $i failed; rc=$rc";           \
       fi;                                                     \
     fi;                                                       \
   done &&                                                     \
   for dc in *.aa ports.tgz; do                                \
     if [ -f "$dc" ]; then                                     \
       fc=`echo "$dc" | head -c 1`;                            \
       if [ "$fc" = "s" ]; then                                \
         DEST=$DESTDIR/usr/src;                                \
         if [ ! -d $DEST ]; then                               \
           mkdir -p $DEST;                                     \
         fi;                                                   \
       fi;                                                     \
       if [ "$dc" != "ports.tgz" ]; then                       \
         comp=${dc%%.*};                                       \
         files="$comp.??";                                     \
       else                                                    \
         comp=$dc;                                             \
         files=$dc;                                            \
         DEST=$DESTDIR/usr;                                    \
       fi;                                                     \
       echo "  - extract $comp in ${DEST}...";                 \
       cat $files | tar --unlink -xpzf - -C ${DEST};           \
     fi
   done)
}


for dir in $DISTDIRS; do
  installdistdir $dir
done



#
# Re-generate /dev
#
echo "making all devices ..."
if [ -f /etc/MAKEDEV ]; then
  cp -p /etc/MAKEDEV /mnt/dev
  (cd /mnt/dev && sh MAKEDEV all ${DISK}s1a)
fi

#
# construct a new /etc/fstab file
#
echo "preparing a new /etc/fstab file ..."
fstab=/mnt/etc/fstab
rm -f $fstab

i=0
while [ $i -ne $N_SLICES ]; do
  eval name=\${slname_${i}}
  case $name in
    root)
      mp=/
      type=ufs
      options="rw"
      dump=1
      pass=1
      ;;
    swap)
      mp=none
      type=swap
      options="sw"
      dump=0
      pass=0
      ;;
    *)
      eval mp=/\${slname_${i}}
      type=ufs
      options="rw"
      dump=2
      pass=2
      ;;
  esac
  eval echo "/dev/${DISK}s1\${slslic_${i}} $mp $type $options $dump $pass" >> $fstab
  i=`expr $i + 1`
done
echo "proc /proc procfs rw 0 0" >> $fstab

echo "generate /etc/rc.conf"
rm -f /mnt/etc/rc.conf

if [ "$CDROOT_CONFIG_NETWORK" = YES ]; then
  if [ -n "$CDROOT_DEFROUTE" ]; then
    defroute="defaultrouter=\"$CDROOT_DEFROUTE\""
  fi
  cat <<EOF >> /mnt/etc/rc.conf
network_interfaces="$CDROOT_NETIF lo0"
ifconfig_$CDROOT_NETIF="inet $CDROOT_IP netmask $CDROOT_NETMASK"
$defroute
hostname="$CDROOT_HOST"
EOF
fi

cat <<EOF >> /mnt/etc/rc.conf
inetd_enable=YES
inetd_flags="-wW -R 8192"
sshd_enable=YES
nfs_client_enable=YES
nfs_server_enable=YES
moused_enable=YES
moused_type=ps/2
moused_port=/dev/psm0
EOF

if [ -f /etc/resolv.conf ]; then
  echo "copy resolv.conf"
  cp /etc/resolv.conf /mnt/etc
fi

if [ ! -f /mnt/kernel ]; then
  echo "install generic kernel"
  cp /mnt/kernel.GENERIC /mnt/kernel
fi

echo "install /boot.config"
echo "-P" > /mnt/boot.config

echo "enable logins on /dev/ttyd0"
tfile=/tmp/ttys.$$
cat $DESTDIR/etc/ttys | sed 's+^ttyd0	"/usr/libexec/getty std.9600"	dialup	off secure+ttyd0   "/usr/libexec/getty std.9600"   xterm   on  secure+g' > $tfile && cp $tfile $DESTDIR/etc/ttys
rm -f $tfile

echo "enable hardware flow control by default on std.9600"
tfile=/tmp/gettytab.$$
cat $DESTDIR/etc/gettytab | sed 's+^	:np:sp#9600:$+	:np:sp#9600:hw:+g' > $tfile && cp $tfile $DESTDIR/etc/gettytab
rm -f $tfile


#
# unmount the disk
#
for i in `df | grep /dev/$DISK | tr -s ' ' | cut -f1 -d' '`; do
  if [ "$i" != "/dev/${DISK}s1a" ]; then
    echo "$i ..."
    umount $i
  fi
done

sleep 2; sync; sleep 2; sync

for i in `df | grep /dev/$DISK | tr -s ' ' | cut -f1 -d' '`; do
  echo "$i ..."
  umount $i
done

echo "done."



syntax highlighted by Code2HTML, v. 0.9.1