1 #!/bin/ksh
   2 #
   3 # CDDL HEADER START
   4 #
   5 # The contents of this file are subject to the terms of the
   6 # Common Development and Distribution License (the "License").
   7 # You may not use this file except in compliance with the License.
   8 #
   9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10 # or http://www.opensolaris.org/os/licensing.
  11 # See the License for the specific language governing permissions
  12 # and limitations under the License.
  13 #
  14 # When distributing Covered Code, include this CDDL HEADER in each
  15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16 # If applicable, add the following below this CDDL HEADER, with the
  17 # fields enclosed by brackets "[]" replaced with your own identifying
  18 # information: Portions Copyright [yyyy] [name of copyright owner]
  19 #
  20 # CDDL HEADER END
  21 #
  22 #
  23 # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  24 # Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
  25 #
  26 
  27 # This started its life as the Caiman text-installer menu, hence the old
  28 # OpenSolaris CDDL statement.
  29 
  30 # LOGNAME variable is needed to display the shell prompt appropriately
  31 export LOGNAME=root
  32 
  33 # Block all signals which could terminate the menu or return to a parent process
  34 trap "" TSTP INT TERM ABRT QUIT
  35 
  36 # Determine which shell program to use by grabbing this user's login-shell
  37 # from /etc/passwd
  38 ROOT_SHELL=$(/usr/bin/getent passwd $LOGNAME |/usr/bin/cut -d':' -f7)
  39 
  40 # On the off chance that $LOGNAME has no shell (default grabbed from passwd(4)p)
  41 if [[ -z "$ROOT_SHELL" ]]; then
  42         ROOT_SHELL="/usr/bin/sh"
  43 fi
  44 
  45 # Get the user's keyboard choice out of the way now.
  46 /usr/bin/kbd -s
  47 /usr/bin/loadkeys
  48 # Remember it post-installation scribbling into installed-image /etc/default/kbd
  49 ktype=`/usr/bin/kbd -l | grep type | awk -F= '{print $2}'`
  50 layout=`/usr/bin/kbd -l | grep layout | awk -F= '{print $2}' | awk '{print $1}'`
  51 klang=`grep -w $layout /usr/share/lib/keytables/type_$ktype/kbd_layouts | awk -F= '{print $1}'`
  52 
  53 # Define the menu of commands and prompts
  54 menu_items=( \
  55     (menu_str="Find disks, create rpool, and install OmniOS"             \
  56         cmds=("/kayak/find-and-install.sh $klang")                       \
  57         do_subprocess="true"                                             \
  58         msg_str="")                                                      \
  59     (menu_str="Install OmniOS straight on to a preconfigured rpool"      \
  60         cmds=("/kayak/rpool-install.sh rpool $klang")                    \
  61         do_subprocess="true"                                             \
  62         msg_str="")                                                      \
  63     (menu_str="Shell (for manual rpool creation, or post-install ops on /mnt)" \
  64         cmds=("$ROOT_SHELL")                                             \
  65         do_subprocess="true"                                             \
  66         msg_str="To return to the main menu, exit the shell")    \
  67     # this string gets overwritten every time $TERM is updated
  68     (menu_str="Terminal type (currently ""$TERM)"                \
  69         cmds=("prompt_for_term_type")                                    \
  70         do_subprocess="false"                                            \
  71         msg_str="")                                                      \
  72     (menu_str="Reboot"                                   \
  73         cmds=("/usr/sbin/reboot" "/usr/bin/sleep 10000")                 \
  74         do_subprocess="true"                                             \
  75         msg_str="")                                                      \
  76 )
  77 
  78 # Update the menu_str for the terminal type
  79 # entry. Every time the terminal type has been
  80 # updated, this function must be called.
  81 function update_term_menu_str
  82 {
  83     # update the menu string to reflect the current TERM
  84     for i in "${!menu_items[@]}"; do
  85             if [[ "${menu_items[$i].cmds[0]}" = "prompt_for_term_type" ]] ; then
  86                 menu_items[$i].menu_str="Terminal type (currently $TERM)"
  87             fi
  88     done
  89 }
  90 
  91 # Set the TERM variable as follows:
  92 #
  93 # Just set it to "sun-color" for now.
  94 #
  95 function set_term_type
  96 {
  97     export TERM=sun-color
  98     update_term_menu_str
  99 }
 100 
 101 # Prompt the user for terminal type
 102 function prompt_for_term_type
 103 {
 104         integer i
 105 
 106         # list of suggested termtypes
 107         typeset termtypes=(
 108                 typeset -a fixedlist
 109                 integer list_len        # number of terminal types
 110         )
 111 
 112         # hard coded common terminal types
 113         termtypes.fixedlist=(
 114                 [0]=(  name="sun-color"         desc="PC Console"           )
 115                 [1]=(  name="xterm"             desc="xterm"                )
 116                 [2]=(  name="vt100"             desc="DEC VT100"            )
 117         )
 118 
 119         termtypes.list_len=${#termtypes.fixedlist[@]}
 120 
 121         # Start with a newline before presenting the choices
 122         print
 123         printf "Indicate the type of terminal being used, such as:\n"
 124 
 125         # list suggested terminal types
 126         for (( i=0 ; i < termtypes.list_len ; i++ )) ; do
 127                 nameref node=termtypes.fixedlist[$i]
 128                 printf "  %-10s %s\n" "${node.name}" "${node.desc}"
 129         done
 130 
 131         print
 132         # Prompt user to select terminal type and check for valid entry
 133         typeset term=""
 134         while true ; do
 135                 read "term?Enter terminal type [$TERM]: " || continue
 136 
 137                 # if the user just hit return, don't set the term variable
 138                 [[ "${term}" = "" ]] && return
 139                         
 140                 # check if the user specified option is valid
 141                 term_entry=`/usr/bin/ls /usr/gnu/share/terminfo/*/$term 2> /dev/null`
 142                 [[ ! -z ${term_entry} ]] && break
 143                 print "terminal type not supported. Supported terminal types can be \n" "${term}"
 144                 print "found by using the Shell to list the contents of /usr/gnu/share/terminfo.\n\n"
 145         done
 146 
 147         export TERM="${term}"
 148         update_term_menu_str
 149 }
 150 
 151 set_term_type
 152 
 153 # default to the Installer option
 154 defaultchoice=1
 155 
 156 for ((;;)) ; do
 157 
 158         # Display the menu.
 159         stty sane
 160         clear
 161         printf \
 162             "Welcome to the OmniOS installation menu"
 163         print " \n\n"
 164         for i in "${!menu_items[@]}"; do
 165                 print "\t$((${i} + 1))  ${menu_items[$i].menu_str}"
 166         done
 167 
 168         # Take an entry (by number). If multiple numbers are
 169         # entered, accept only the first one.
 170         input=""
 171         dummy=""
 172         print -n "\nPlease enter a number [${defaultchoice}]: "
 173         read input dummy 2>/dev/null
 174 
 175         # If no input was supplied, select the default option
 176         [[ -z ${input} ]] && input=$defaultchoice
 177 
 178         # First char must be a digit.
 179         if [[ ${input} =~ [^1-9] || ${input} > ${#menu_items[@]} ]] ; then
 180                 continue
 181         fi
 182 
 183         # Reorient to a zero base.
 184         input=$((${input} - 1))
 185 
 186         nameref msg_str=menu_items[$input].msg_str
 187 
 188         # Launch commands as a subprocess.
 189         # However, launch the functions within the context 
 190         # of the current process.
 191         if [[ "${menu_items[$input].do_subprocess}" = "true" ]] ; then
 192                 (
 193                 trap - TSTP INT TERM ABRT QUIT
 194                 # Print out a message if requested
 195                 [[ ! -z "${msg_str}" ]] && printf "%s\n" "${msg_str}"
 196                 for j in "${!menu_items[$input].cmds[@]}"; do
 197                         ${menu_items[${input}].cmds[$j]}
 198                 done
 199                 )
 200         else
 201                 # Print out a message if requested
 202                 [[ ! -z "${msg_str}" ]] && printf "%s\n" "${msg_str}"
 203                 for j in "${!menu_items[$input].cmds[@]}"; do
 204                         ${menu_items[${input}].cmds[$j]}
 205                 done
 206         fi
 207 done