1 #!/sbin/sh
   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, Version 1.0 only
   7 # (the "License").  You may not use this file except in compliance
   8 # with the License.
   9 #
  10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  11 # or http://www.opensolaris.org/os/licensing.
  12 # See the License for the specific language governing permissions
  13 # and limitations under the License.
  14 #
  15 # When distributing Covered Code, include this CDDL HEADER in each
  16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  17 # If applicable, add the following below this CDDL HEADER, with the
  18 # fields enclosed by brackets "[]" replaced with your own identifying
  19 # information: Portions Copyright [yyyy] [name of copyright owner]
  20 #
  21 # CDDL HEADER END
  22 #
  23 #       Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24 #       Use is subject to license terms.
  25 #
  26 #       Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
  27 #         All Rights Reserved
  28 
  29 
  30 
  31 #ident  "%Z%%M% %I%     %E% SMI"
  32 
  33 #       Sequence performed to change the init state of a machine.  Only allows
  34 #       transitions to states 0,1,5,6,s,S (i.e.: down or administrative states).
  35 
  36 #       This procedure checks to see if you are permitted and allows an
  37 #       interactive shutdown.  The actual change of state, killing of
  38 #       processes and such are performed by the new init state, say 0,
  39 #       and its /sbin/rc0.
  40 
  41 usage() {
  42         echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]"
  43         exit 1
  44 }
  45 
  46 notify() {
  47         /usr/sbin/wall -a <<-!
  48         $*
  49         !
  50         if [ -x /usr/sbin/showmount -a -x /usr/sbin/rwall ]
  51         then
  52                 remotes=`/usr/sbin/showmount`
  53                 if [ "X${remotes}" != "X" ]
  54                 then
  55                         /usr/sbin/rwall -q ${remotes} <<-!
  56                         $*
  57                         !
  58                 fi
  59         fi
  60 }
  61 
  62 nologin=/etc/nologin
  63 
  64 # Set the PATH so that to guarentee behavior of shell built in commands
  65 # (such as echo).
  66 
  67 PATH=/usr/sbin:/usr/bin:/sbin
  68 
  69 # Initial sanity checks:
  70 #       Make sure /usr is mounted
  71 #       Check the user id (only root can run shutdown)
  72 
  73 if [ ! -d /usr/bin ]
  74 then
  75         echo "$0:  /usr is not mounted.  Mount /usr or use init to shutdown."
  76         exit 1
  77 fi
  78 
  79 if [ -x /usr/bin/id ]
  80 then
  81         eval `/usr/bin/id  |  /usr/bin/sed 's/[^a-z0-9=].*//'`
  82         if [ "${uid:=0}" -ne 0 ]
  83         then
  84                 echo "$0:  Only root can run $0"
  85                 exit 2
  86         fi
  87 else
  88         echo "$0:  can't check user id."
  89         exit 2
  90 fi
  91 
  92 # Get options (defaults immediately below):
  93 
  94 grace=60
  95 askconfirmation=yes
  96 initstate=s
  97 
  98 while getopts g:i:y? c
  99 do
 100         case $c in
 101         g)
 102                 case $OPTARG in
 103                 *[!0-9]* )
 104                         echo "$0: -g requires a numeric option"
 105                         usage
 106                         ;;
 107                 [0-9]* )
 108                         grace=$OPTARG
 109                         ;;
 110                 esac
 111                 ;;
 112         i)
 113                 case $OPTARG in
 114                 [Ss0156])
 115                         initstate=$OPTARG
 116                         ;;
 117                 [234abcqQ])
 118                         echo "$0: Initstate $OPTARG is not for system shutdown"
 119                         exit 1
 120                         ;;
 121                 *)
 122                         echo "$0: $OPTARG is not a valid initstate"
 123                         usage
 124                         ;;
 125                 esac
 126                 ;;
 127         y)
 128                 askconfirmation=
 129                 ;;
 130         \?)     usage
 131                 ;;
 132         esac
 133 done
 134 shift `expr $OPTIND - 1`
 135 
 136 echo '\nShutdown started.    \c'
 137 /usr/bin/date
 138 echo
 139 
 140 NODENAME=`uname -n`
 141 
 142 /sbin/sync
 143 cd /
 144 
 145 trap "rm $nologin >/dev/null 2>&1 ;exit 1"  1 2 15
 146 
 147 # If other users are on the system (and any grace period is given), warn them.
 148 
 149 for i in 7200 3600 1800 1200 600 300 120 60 30 10; do
 150         if [ ${grace} -gt $i ]
 151         then
 152                 hours=`/usr/bin/expr ${grace} / 3600`
 153                 minutes=`/usr/bin/expr ${grace} % 3600 / 60`
 154                 seconds=`/usr/bin/expr ${grace} % 60`
 155                 time=""
 156                 if [ ${hours} -gt 1 ]
 157                 then
 158                         time="${hours} hours "
 159                 elif [ ${hours} -eq 1 ]
 160                 then
 161                         time="1 hour "
 162                 fi
 163                 if [ ${minutes} -gt 1 ]
 164                 then
 165                         time="${time}${minutes} minutes "
 166                 elif [ ${minutes} -eq 1 ]
 167                 then
 168                         time="${time}1 minute "
 169                 fi
 170                 if [ ${hours} -eq 0 -a ${seconds} -gt 0 ]
 171                 then
 172                         if [ ${seconds} -eq 1 ]
 173                         then
 174                                 time="${time}${seconds} second"
 175                         else
 176                                 time="${time}${seconds} seconds"
 177                         fi
 178                 fi
 179 
 180                 (notify \
 181 "The system ${NODENAME} will be shut down in ${time}
 182 $*") &
 183 
 184 pid1=$!
 185 
 186                 rm $nologin >/dev/null 2>&1
 187                 cat > $nologin <<-!
 188 
 189                         NO LOGINS: System going down in ${time}
 190                         $*
 191 
 192                 !
 193 
 194                 /usr/bin/sleep `/usr/bin/expr ${grace} - $i`
 195                 grace=$i
 196         fi
 197 done
 198 
 199 # Confirm that we really want to shutdown.
 200 
 201 if [ ${askconfirmation} ]
 202 then
 203         echo "Do you want to continue? (y or n):   \c"
 204         read b
 205         if [ "$b" != "y" ]
 206         then
 207                 notify "False Alarm:  The system ${NODENAME} will not be brought down."
 208                 echo 'Shutdown aborted.'
 209                 rm $nologin >/dev/null 2>&1
 210                 exit 1
 211         fi
 212 fi
 213 
 214 # Final shutdown message, and sleep away the final 10 seconds (or less).
 215 
 216 (notify \
 217 "THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! !
 218 Log off now or risk your files being damaged
 219 $*") &
 220 
 221 pid2=$!
 222 
 223 if [ ${grace} -gt 0 ]
 224 then
 225         /usr/bin/sleep ${grace}
 226 fi
 227 
 228 # Go to the requested initstate.
 229 
 230 
 231 echo "Changing to init state $initstate - please wait"
 232 
 233 if [ "$pid1" ] || [ "$pid2" ]
 234 then
 235         /usr/bin/kill $pid1 $pid2 > /dev/null 2>&1
 236 fi
 237 
 238 /sbin/init ${initstate}