10Sstevel@tonic-gate#!/sbin/sh 20Sstevel@tonic-gate# 30Sstevel@tonic-gate# CDDL HEADER START 40Sstevel@tonic-gate# 50Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*8944Sdp@eng.sun.com# Common Development and Distribution License (the "License"). 7*8944Sdp@eng.sun.com# You may not use this file except in compliance with the License. 80Sstevel@tonic-gate# 90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate# See the License for the specific language governing permissions 120Sstevel@tonic-gate# and limitations under the License. 130Sstevel@tonic-gate# 140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate# 200Sstevel@tonic-gate# CDDL HEADER END 210Sstevel@tonic-gate# 22*8944Sdp@eng.sun.com# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate# Use is subject to license terms. 240Sstevel@tonic-gate# 250Sstevel@tonic-gate# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T 260Sstevel@tonic-gate# All Rights Reserved 270Sstevel@tonic-gate 280Sstevel@tonic-gate 290Sstevel@tonic-gate 300Sstevel@tonic-gate# Sequence performed to change the init state of a machine. Only allows 310Sstevel@tonic-gate# transitions to states 0,1,5,6,s,S (i.e.: down or administrative states). 320Sstevel@tonic-gate 330Sstevel@tonic-gate# This procedure checks to see if you are permitted and allows an 340Sstevel@tonic-gate# interactive shutdown. The actual change of state, killing of 350Sstevel@tonic-gate# processes and such are performed by the new init state, say 0, 360Sstevel@tonic-gate# and its /sbin/rc0. 370Sstevel@tonic-gate 380Sstevel@tonic-gateusage() { 390Sstevel@tonic-gate echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]" 400Sstevel@tonic-gate exit 1 410Sstevel@tonic-gate} 420Sstevel@tonic-gate 430Sstevel@tonic-gatenotify() { 440Sstevel@tonic-gate /usr/sbin/wall -a <<-! 450Sstevel@tonic-gate $* 460Sstevel@tonic-gate ! 470Sstevel@tonic-gate if [ -x /usr/sbin/showmount -a -x /usr/sbin/rwall ] 480Sstevel@tonic-gate then 490Sstevel@tonic-gate remotes=`/usr/sbin/showmount` 500Sstevel@tonic-gate if [ "X${remotes}" != "X" ] 510Sstevel@tonic-gate then 520Sstevel@tonic-gate /usr/sbin/rwall -q ${remotes} <<-! 530Sstevel@tonic-gate $* 540Sstevel@tonic-gate ! 550Sstevel@tonic-gate fi 560Sstevel@tonic-gate fi 570Sstevel@tonic-gate} 580Sstevel@tonic-gate 590Sstevel@tonic-gatenologin=/etc/nologin 600Sstevel@tonic-gate 610Sstevel@tonic-gate# Set the PATH so that to guarentee behavior of shell built in commands 620Sstevel@tonic-gate# (such as echo). 630Sstevel@tonic-gate 640Sstevel@tonic-gatePATH=/usr/sbin:/usr/bin:/sbin 650Sstevel@tonic-gate 660Sstevel@tonic-gate# Initial sanity checks: 670Sstevel@tonic-gate# Make sure /usr is mounted 680Sstevel@tonic-gate# Check the user id (only root can run shutdown) 690Sstevel@tonic-gate 700Sstevel@tonic-gateif [ ! -d /usr/bin ] 710Sstevel@tonic-gatethen 720Sstevel@tonic-gate echo "$0: /usr is not mounted. Mount /usr or use init to shutdown." 730Sstevel@tonic-gate exit 1 740Sstevel@tonic-gatefi 750Sstevel@tonic-gate 760Sstevel@tonic-gateif [ -x /usr/bin/id ] 770Sstevel@tonic-gatethen 780Sstevel@tonic-gate eval `/usr/bin/id | /usr/bin/sed 's/[^a-z0-9=].*//'` 790Sstevel@tonic-gate if [ "${uid:=0}" -ne 0 ] 800Sstevel@tonic-gate then 810Sstevel@tonic-gate echo "$0: Only root can run $0" 820Sstevel@tonic-gate exit 2 830Sstevel@tonic-gate fi 840Sstevel@tonic-gateelse 850Sstevel@tonic-gate echo "$0: can't check user id." 860Sstevel@tonic-gate exit 2 870Sstevel@tonic-gatefi 880Sstevel@tonic-gate 890Sstevel@tonic-gate# Get options (defaults immediately below): 900Sstevel@tonic-gate 910Sstevel@tonic-gategrace=60 920Sstevel@tonic-gateaskconfirmation=yes 930Sstevel@tonic-gateinitstate=s 940Sstevel@tonic-gate 950Sstevel@tonic-gatewhile getopts g:i:y? c 960Sstevel@tonic-gatedo 970Sstevel@tonic-gate case $c in 980Sstevel@tonic-gate g) 990Sstevel@tonic-gate case $OPTARG in 1000Sstevel@tonic-gate *[!0-9]* ) 1010Sstevel@tonic-gate echo "$0: -g requires a numeric option" 1020Sstevel@tonic-gate usage 1030Sstevel@tonic-gate ;; 1040Sstevel@tonic-gate [0-9]* ) 1050Sstevel@tonic-gate grace=$OPTARG 1060Sstevel@tonic-gate ;; 1070Sstevel@tonic-gate esac 1080Sstevel@tonic-gate ;; 1090Sstevel@tonic-gate i) 1100Sstevel@tonic-gate case $OPTARG in 1110Sstevel@tonic-gate [Ss0156]) 1120Sstevel@tonic-gate initstate=$OPTARG 1130Sstevel@tonic-gate ;; 1140Sstevel@tonic-gate [234abcqQ]) 1150Sstevel@tonic-gate echo "$0: Initstate $OPTARG is not for system shutdown" 1160Sstevel@tonic-gate exit 1 1170Sstevel@tonic-gate ;; 1180Sstevel@tonic-gate *) 1190Sstevel@tonic-gate echo "$0: $OPTARG is not a valid initstate" 1200Sstevel@tonic-gate usage 1210Sstevel@tonic-gate ;; 1220Sstevel@tonic-gate esac 1230Sstevel@tonic-gate ;; 1240Sstevel@tonic-gate y) 1250Sstevel@tonic-gate askconfirmation= 1260Sstevel@tonic-gate ;; 1270Sstevel@tonic-gate \?) usage 1280Sstevel@tonic-gate ;; 1290Sstevel@tonic-gate esac 1300Sstevel@tonic-gatedone 1310Sstevel@tonic-gateshift `expr $OPTIND - 1` 1320Sstevel@tonic-gate 1330Sstevel@tonic-gateecho '\nShutdown started. \c' 1340Sstevel@tonic-gate/usr/bin/date 1350Sstevel@tonic-gateecho 1360Sstevel@tonic-gate 1370Sstevel@tonic-gateNODENAME=`uname -n` 1380Sstevel@tonic-gate 1390Sstevel@tonic-gatecd / 1400Sstevel@tonic-gate 1410Sstevel@tonic-gatetrap "rm $nologin >/dev/null 2>&1 ;exit 1" 1 2 15 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate# If other users are on the system (and any grace period is given), warn them. 1440Sstevel@tonic-gate 1450Sstevel@tonic-gatefor i in 7200 3600 1800 1200 600 300 120 60 30 10; do 1460Sstevel@tonic-gate if [ ${grace} -gt $i ] 1470Sstevel@tonic-gate then 1480Sstevel@tonic-gate hours=`/usr/bin/expr ${grace} / 3600` 1490Sstevel@tonic-gate minutes=`/usr/bin/expr ${grace} % 3600 / 60` 1500Sstevel@tonic-gate seconds=`/usr/bin/expr ${grace} % 60` 1510Sstevel@tonic-gate time="" 1520Sstevel@tonic-gate if [ ${hours} -gt 1 ] 1530Sstevel@tonic-gate then 1540Sstevel@tonic-gate time="${hours} hours " 1550Sstevel@tonic-gate elif [ ${hours} -eq 1 ] 1560Sstevel@tonic-gate then 1570Sstevel@tonic-gate time="1 hour " 1580Sstevel@tonic-gate fi 1590Sstevel@tonic-gate if [ ${minutes} -gt 1 ] 1600Sstevel@tonic-gate then 1610Sstevel@tonic-gate time="${time}${minutes} minutes " 1620Sstevel@tonic-gate elif [ ${minutes} -eq 1 ] 1630Sstevel@tonic-gate then 1640Sstevel@tonic-gate time="${time}1 minute " 1650Sstevel@tonic-gate fi 1660Sstevel@tonic-gate if [ ${hours} -eq 0 -a ${seconds} -gt 0 ] 1670Sstevel@tonic-gate then 1680Sstevel@tonic-gate if [ ${seconds} -eq 1 ] 1690Sstevel@tonic-gate then 1700Sstevel@tonic-gate time="${time}${seconds} second" 1710Sstevel@tonic-gate else 1720Sstevel@tonic-gate time="${time}${seconds} seconds" 1730Sstevel@tonic-gate fi 1740Sstevel@tonic-gate fi 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate (notify \ 1770Sstevel@tonic-gate"The system ${NODENAME} will be shut down in ${time} 1780Sstevel@tonic-gate$*") & 1790Sstevel@tonic-gate 1800Sstevel@tonic-gatepid1=$! 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate rm $nologin >/dev/null 2>&1 1830Sstevel@tonic-gate cat > $nologin <<-! 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate NO LOGINS: System going down in ${time} 1860Sstevel@tonic-gate $* 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate ! 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate /usr/bin/sleep `/usr/bin/expr ${grace} - $i` 1910Sstevel@tonic-gate grace=$i 1920Sstevel@tonic-gate fi 1930Sstevel@tonic-gatedone 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate# Confirm that we really want to shutdown. 1960Sstevel@tonic-gate 1970Sstevel@tonic-gateif [ ${askconfirmation} ] 1980Sstevel@tonic-gatethen 1990Sstevel@tonic-gate echo "Do you want to continue? (y or n): \c" 2000Sstevel@tonic-gate read b 2010Sstevel@tonic-gate if [ "$b" != "y" ] 2020Sstevel@tonic-gate then 2030Sstevel@tonic-gate notify "False Alarm: The system ${NODENAME} will not be brought down." 2040Sstevel@tonic-gate echo 'Shutdown aborted.' 2050Sstevel@tonic-gate rm $nologin >/dev/null 2>&1 2060Sstevel@tonic-gate exit 1 2070Sstevel@tonic-gate fi 2080Sstevel@tonic-gatefi 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate# Final shutdown message, and sleep away the final 10 seconds (or less). 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate(notify \ 2130Sstevel@tonic-gate"THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! ! 2140Sstevel@tonic-gateLog off now or risk your files being damaged 2150Sstevel@tonic-gate$*") & 2160Sstevel@tonic-gate 2170Sstevel@tonic-gatepid2=$! 2180Sstevel@tonic-gate 2190Sstevel@tonic-gateif [ ${grace} -gt 0 ] 2200Sstevel@tonic-gatethen 2210Sstevel@tonic-gate /usr/bin/sleep ${grace} 2220Sstevel@tonic-gatefi 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate# Go to the requested initstate. 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate 2270Sstevel@tonic-gateecho "Changing to init state $initstate - please wait" 2280Sstevel@tonic-gate 2290Sstevel@tonic-gateif [ "$pid1" ] || [ "$pid2" ] 2300Sstevel@tonic-gatethen 2310Sstevel@tonic-gate /usr/bin/kill $pid1 $pid2 > /dev/null 2>&1 2320Sstevel@tonic-gatefi 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate/sbin/init ${initstate} 235