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 41usage() { 42 echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]" 43 exit 1 44} 45 46notify() { 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 62nologin=/etc/nologin 63 64# Set the PATH so that to guarentee behavior of shell built in commands 65# (such as echo). 66 67PATH=/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 73if [ ! -d /usr/bin ] 74then 75 echo "$0: /usr is not mounted. Mount /usr or use init to shutdown." 76 exit 1 77fi 78 79if [ -x /usr/bin/id ] 80then 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 87else 88 echo "$0: can't check user id." 89 exit 2 90fi 91 92# Get options (defaults immediately below): 93 94grace=60 95askconfirmation=yes 96initstate=s 97 98while getopts g:i:y? c 99do 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 133done 134shift `expr $OPTIND - 1` 135 136echo '\nShutdown started. \c' 137/usr/bin/date 138echo 139 140NODENAME=`uname -n` 141 142/sbin/sync 143cd / 144 145trap "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 149for 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 184pid1=$! 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 197done 198 199# Confirm that we really want to shutdown. 200 201if [ ${askconfirmation} ] 202then 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 212fi 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 ! ! ! 218Log off now or risk your files being damaged 219$*") & 220 221pid2=$! 222 223if [ ${grace} -gt 0 ] 224then 225 /usr/bin/sleep ${grace} 226fi 227 228# Go to the requested initstate. 229 230 231echo "Changing to init state $initstate - please wait" 232 233if [ "$pid1" ] || [ "$pid2" ] 234then 235 /usr/bin/kill $pid1 $pid2 > /dev/null 2>&1 236fi 237 238/sbin/init ${initstate} 239