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