#!/bin/ksh -p
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright 2015 Joyent, Inc.  All rights reserved.
# Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
#

#
# Since CentOS, Red Hat Enterprise Linux, and Fedora all use approximately
# the same source, this file should be good for all three.
#
# Currently, this file assumed a pre-systemd existence, so this should be
# CentOS 6.x or earlier.  Testing has been done on CentOS 6.6.
#

# This script was taken from an earlier file.  Initialize some variables here.
install_aborted="Install aborted"
disable_failed="Disable failed"
create_failed="Create failed"
tag=lx-redhat.$$
tmpfile=/tmp/$tag
cmd2_failed=lx_boot_zone_redhat

#
# The default /etc/inittab spawns mingetty on each of the virtual consoles
# as well as xdm on the X console.  Since we don't have virtual consoles nor
# an X console, spawn a single mingetty on /dev/console instead.
#
# Don't bother changing the file if it looks like we already did.
#
if ! egrep -s "Disabled by lx brand" $ZONEROOT/etc/inittab; then
        log "Modifying: \"$ZONEROOT/etc/inittab\"..."

        sed 's/^[1-6]:/# Disabled by lx brand: &/
            s/^id:5:initdefault:/id:3:initdefault: # Modified by lx brand: &/' \
            $ZONEROOT/etc/inittab > $tmpfile

        #
        # Don't bother with further alterations if the sed above failed...
        #
        if [[ $? -eq 0 ]]; then
                #
                # Attempt to save off the original inittab
                # before moving over the modified version.
                #
                mv -f $ZONEROOT/etc/inittab $ZONEROOT/etc/inittab.$tag 2>/dev/null

                mv -f $tmpfile $ZONEROOT/etc/inittab

                if [[ $? -ne 0 ]]; then
                        log "mv of \"$tmpfile\" to" \
                            "\"$ZONEROOT/etc/inittab\"" \
                            "failed!"
                        i18n_echo "$cmd2_failed" "mv" \
                            "$tmpfile" \
                            "$ZONEROOT/etc/inittab"
                        i18n_echo "$install_aborted"
                        exit 1
                else
                        chmod 644 $ZONEROOT/etc/inittab
                fi
	else
                log "Attempt to disable entries in" \
                    "\"$ZONEROOT/etc/inittab\" failed!"
                i18n_echo "$disable_failed" "$ZONEROOT/etc/inittab"
                i18n_echo "$install_aborted"
                exit 1
	fi
fi

#
# We use our own way of bringing up networking, so don't let the init system
# try.
#
log ""
log "Modifying: \"$ZONEROOT/etc/sysconfig/network\"..."

mv -f $ZONEROOT/etc/sysconfig/network $ZONEROOT/etc/sysconfig/network.$tag 2>/dev/null

cat > $ZONEROOT/etc/sysconfig/network <<- EOF
        NETWORKING="no"
        #
        # To enable networking, change the "no" above to "yes" and
        # uncomment and fill in the following parameters.
        #
        # If you are specifying a hostname by name rather than by IP address,
        # be sure the system can resolve the name properly via the use of a
        # name service and/or the proper name files, as specified by
        # nsswitch.conf.  See nsswitch.conf(5) for further details.
        #
        # HOSTNAME=your_hostname_here
        #
EOF

if [[ $? -ne 0 ]]; then
        log "Could not create new \"$ZONEROOT/etc/sysconfig/network\"!"
        i18n_echo "$create_failed" "$ZONEROOT/etc/sysconfig/network"
        i18n_echo "$install_aborted"
        exit 1
fi

#
# SELinux must be disabled otherwise we won't get past init.
#
if [[ egrep -s "^SELINUX=enforcing" $ZONEROOT/etc/selinux/config ||
	egrep -s "^SELINUX=permissive" $ZONEROOT/etc/selinux/config ]]; then
        log "Modifying: \"$ZONEROOT/etc/selinux/config\"..."

        tmpfile=/tmp/selinux_config.$$

        sed 's/^SELINUX=enforcing/SELINUX=disabled/' \
            $ZONEROOT/etc/selinux/config | \
	    sed 's/^SELINUX=permissive/SELINUX=disabled/' > $tmpfile

        if [[ $? -eq 0 ]]; then
                mv -f $ZONEROOT/etc/selinux/config $ZONEROOT/etc/selinux/config.$tag 2>/dev/null

                mv -f $tmpfile $ZONEROOT/etc/selinux/config

                if [[ $? -ne 0 ]]; then
                        log "mv of \"$tmpfile\" to" \
                            "\"$ZONEROOT/etc/selinux/config\"" \
                            "failed!"
                        i18n_echo "$cmd2_failed" "mv" \
                            "$tmpfile" \
                            "$ZONEROOT/etc/selinux/config"
                        i18n_echo "$install_aborted"
                        exit 1
                else
                        chmod 644 $ZONEROOT/etc/selinux/config
                fi
        else
                log "Attempt to disable entries in" \
                    "\"$ZONEROOT/etc/selinux/config\" failed!"
                i18n_echo "$disable_failed" "$ZONEROOT/etc/selinux/config"
                i18n_echo "$install_aborted"
                exit 1
        fi
fi

#
# /etc/rc.d/init.d/keytable tries to load a physical keyboard map, which won't
# work in a zone. If we remove etc/sysconfig/keyboard, it won't try this at all.
#
mv -f $ZONEROOT/etc/sysconfig/keyboard $ZONEROOT/etc/sysconfig/keyboard.$tag 2>/dev/null

#
# The following scripts attempt to start services or otherwise configure
# the system in ways incompatible with zones, so don't execute them at boot
# time.
#
log ""
log "Modifying \"$ZONEROOT/etc/rc.d/init.d\" to disable any"
log "  services not supported by LX Zones:"
unsupported_services="
        kudzu
        microcode_ctl
        network
        random
        pcmcia
        isdn
        iptables
        ip6tables
        iscsi
        psacct
        gpm
        irda
        smartd
        rawdevices
        netdump
        hpoj
        mdmonitor
        mdmpd
        irqbalance
"

for file in $unsupported_services; do
        if [[ -a "$ZONEROOT/etc/rc.d/init.d/$file" ]]; then

            if mv -f "$ZONEROOT/etc/rc.d/init.d/$file" "$ZONEROOT/etc/rc.d/init.d/$file.$tag"; then
                    log "    + Moved script \"$ZONEROOT/etc/rc.d/init.d/$file\" to"
                    log "          \"$ZONEROOT/etc/rc.d/init.d/$file.$tag\""
            fi
        fi

        rc_files="$(echo $ZONEROOT/etc/rc.d/rc[0-6].d/[SK]+([0-9])$file)"

        if [[ "$rc_files" != "$ZONEROOT/etc/rc.d/rc[0-6].d/[SK]+([0-9])$file" ]]; then
                for file in $rc_files; do
                        if [[ -h "$file" ]]; then
                                rm -f "$file" &&
                                    log "    + Removed symbolic link \"$file\""
                        else
                                rm -f "$file" &&
                                    log "    + Removed script \"$file\""
                        fi
                done
        fi
done

#
# There is a lot of stuff in the standard halt and reboot scripts that we
# have no business running in a zone.  Fortunately, the stuff we want to
# skip is all in one contiguous chunk.
#
# Don't bother to modify the file if it looks like we already did.
#
if ! egrep -s "Disabled by lx brand" $ZONEROOT/etc/rc.d/init.d/halt; then
        log ""
        log "Modifying  \"$ZONEROOT/etc/rc.d/init.d/halt\" for operation"
        log "  within a zone..."
        awk 'BEGIN {skip = ""}
            /^# Save mixer/ {skip = "# Disabled by lx brand: "}
            /halt.local/ {skip = ""}
            /./ {print skip $0}' $ZONEROOT/etc/rc.d/init.d/halt > /tmp/halt.$$

        if [[ $? -eq 0 ]]; then
                mv -f $ZONEROOT/etc/rc.d/init.d/halt $ZONEROOT/etc/rc.d/init.d/halt.$tag 2>/dev/null
                mv -f /tmp/halt.$$ $ZONEROOT/etc/rc.d/init.d/halt
                chmod 755 $ZONEROOT/etc/rc.d/init.d/halt
        else
                log "Attempt to modify \"$ZONEROOT/etc/rc.d/init.d/halt\"" \
                    "FAILED"
                log "Continuing with balance of zone setup..."
        fi
fi

#
# Fix up /etc/rc.d/rc.sysinit:
#
# 1) /sbin/hwclock requires the iopl() system call, which BrandZ won't support.
#    Since the hardware clock cannot be set from within a zone, we comment out
#    the line.
#
# 2) Disable dmesg commands, since we don't implement klogctl
#
# 3) Disable initlog and the mount of /dev/pts
#
# 4) Don't touch /dev/tty* in order to start virtual terminals, as that won't
#    work from within a zone.
#
# 5) Don't try to check the root filesystem (/) as there is no associated
#    physical device, and any attempt to run fsck will fail.
#
# Don't modify the rc.sysinit file if it looks like we already did.
#
if ! egrep -s "Disabled by lx brand" $ZONEROOT/etc/rc.d/rc.sysinit; then
        log ""
        log "Modifying: \"$ZONEROOT/etc/rc.d/rc.sysinit\"..."
        log ""

        tmpfile=/tmp/lx_rc.sysinit.$$

        sed 's@^/sbin/hwclock@# Disabled by lx brand: &@
            s@^HOSTTYPE=@HOSTTYPE=\"s390\" # Spoofed for lx brand: &@
            s@/bin/dmesg -n@: # Disabled by lx brand: &@
            s@^dmesg -s@# Disabled by lx brand: &@
            s@initlog -c \"fsck@: # Disabled by lx brand: &@
            s@^.*mount .* /dev/pts$@# Disabled by lx brand: &@' \
            $ZONEROOT/etc/rc.d/rc.sysinit > $tmpfile

        #
        # Only install the new rc.sysinit if the edit above succeeded.
        #
        if [[ $? -eq 0 ]]; then
                #
                # Attempt to save off the original rc.sysinit
                # before moving over the modified version.
                #
                mv -f $ZONEROOT/etc/rc.d/rc.sysinit $ZONEROOT/etc/rc.d/rc.sysinit.$tag 2>/dev/null

                if ! mv -f $tmpfile $ZONEROOT/etc/rc.d/rc.sysinit; then
                        log "mv of \"$tmpfile\" to" \
                            "\"$ZONEROOT/etc/rc.d/rc.sysinit\" failed!"
                        i18n_echo "$cmd2_failed" "mv" "$tmpfile" \
                            "$ZONEROOT/etc/rc.d/rc.sysinit"
                        i18n_echo "$install_aborted"
                        exit 1
                else
                        chmod 755 $ZONEROOT/etc/rc.d/rc.sysinit
                fi
        else
                log "Attempt to modify entries in" \
                    "\"$ZONEROOT/etc/rc.d/rc.sysinit\" failed!"
                i18n_echo "$mod_failed" "$ZONEROOT/etc/rc.d/rc.sysinit"
                i18n_echo "$install_aborted"
                exit 1
        fi
fi

# Function for setting up networking in the zone.
# Generate the networking.conf upstart script
setup_net()
{
    zonecfg -z $ZONENAME info net >/tmp/$ZONENAME.$$
    zonecfg -z $ZONENAME info attr name=resolvers >>/tmp/$ZONENAME.$$

   awk '
        BEGIN {
            printf("description\t\"configure virtual network devices\"\n\n")
            printf("emits static-network-up\n")
            printf("emits net-device-up\n\n")

            printf("start on local-filesystems\n\n")

            printf("task\n\n")

            printf("pre-start exec mkdir -p /run/network\n\n")

            printf("script\n")
            printf("    /sbin/ipmgmtd || true\n")
            printf("    /sbin/ifconfig-native lo0 plumb\n")
            printf("    /sbin/ifconfig-native lo0 up\n")
            printf("    /sbin/ifconfig-native lo0 inet6 plumb\n")
            printf("    /sbin/ifconfig-native lo0 inet6 up\n")
            printf("    /sbin/initctl emit --no-wait net-device-up IFACE=lo LOGICAL=lo ADDRFAM=inet METHOD=loopback || true\n")

        } {
            if ($1 == "net:") {
                in_net = 1
                in_attr = 0
                next
            } else if ($1 == "attr:") {
                in_net = 0
                in_attr = 1
                next
            }

            if (in_net == 1) {
                if ($1 == "physical:") {
                    phys = $2
                } else if ($1 == "property:") {
                    split($2, a, ",")
                    split(a[1], k, "=")
                    split(a[2], v, "=")

                    val = substr(v[2], 2)
                    val = substr(val, 1, length(val) - 2)

                    if (k[2] == "ip")
                        ip = val
                    else if (k[2] == "netmask")
                        mask = val
                    else if (k[2] == "primary")
                        prim = val
                    else if (k[2] == "gateway")
                        gw = val
                }

                if ($1 == "net:" && phys != "") {
                    printf("    /sbin/ifconfig-native %s plumb || true\n", phys)
                    printf("    /sbin/ifconfig-native %s %s netmask %s up || true\n",
                        phys, ip, mask)
                    printf("    /sbin/ifconfig-native %s inet6 plumb up || true\n", phys)
                    if (prim == "true" && length(gw) > 0)

                        printf("    /sbin/route add default %s || true\n", gw)
                    printf("    /sbin/initctl emit --no-wait net-device-up IFACE=%s\n",
                        phys)

                    phys = ""
                    prim = ""
                    gw = ""
                }
            } else if (in_attr == 1) {
                if ($1 == "value:") {
                    nres = split($2, resolvers, ",")
                }
            }
        }
        END {
            printf("    /sbin/ifconfig-native %s plumb || true\n", phys)
            printf("    /sbin/ifconfig-native %s %s netmask %s up || true\n",
                phys, ip, mask)
            printf("    /sbin/ifconfig-native %s inet6 plumb up || true\n", phys)
            if (prim == "true" && length(gw) > 0)
                printf("    /sbin/route add default %s || true\n", gw)
            printf("    /sbin/initctl emit --no-wait net-device-up IFACE=%s\n",
                phys)

            printf("    /sbin/initctl emit --no-wait static-network-up\n")

            for (i = 1; i <= nres; i++)
                printf("    echo \"nameserver %s\" >> %s\n", resolvers[i],
                    "/run/resolvconf/resolv.conf")

            printf("end script\n")
        }' /tmp/$ZONENAME.$$ > $fnm

        rm -f /tmp/$ZONENAME.$$
}


# NOTE: The networking setup assumes an exclusive-stack zone.
iptype=`/usr/sbin/zonecfg -z $ZONENAME info ip-type | cut -f2 -d' '`

if [[ "$iptype" == "exclusive" ]]; then
        fnm=$ZONEROOT/etc/init/networking.conf
        if [[ ! -h $fnm && -f $fnm ]] then
                setup_net
        fi
fi

### XXX KEBE SAYS THERE IS PROBABLY MORE HERE TO DO!
