xref: /onnv-gate/usr/src/cmd/svc/shell/net_include.sh (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!/bin/sh
2*0Sstevel@tonic-gate#
3*0Sstevel@tonic-gate# CDDL HEADER START
4*0Sstevel@tonic-gate#
5*0Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*0Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only
7*0Sstevel@tonic-gate# (the "License").  You may not use this file except in compliance
8*0Sstevel@tonic-gate# with the License.
9*0Sstevel@tonic-gate#
10*0Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*0Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
12*0Sstevel@tonic-gate# See the License for the specific language governing permissions
13*0Sstevel@tonic-gate# and limitations under the License.
14*0Sstevel@tonic-gate#
15*0Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
16*0Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*0Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
18*0Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
19*0Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
20*0Sstevel@tonic-gate#
21*0Sstevel@tonic-gate# CDDL HEADER END
22*0Sstevel@tonic-gate#
23*0Sstevel@tonic-gate#
24*0Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
25*0Sstevel@tonic-gate# Use is subject to license terms.
26*0Sstevel@tonic-gate#
27*0Sstevel@tonic-gate#ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate#
29*0Sstevel@tonic-gate# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
30*0Sstevel@tonic-gate# All rights reserved.
31*0Sstevel@tonic-gate#
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate#
34*0Sstevel@tonic-gate# shcat file
35*0Sstevel@tonic-gate#   Simulates cat in sh so it doesn't need to be on the root filesystem.
36*0Sstevel@tonic-gate#
37*0Sstevel@tonic-gateshcat() {
38*0Sstevel@tonic-gate        while [ $# -ge 1 ]; do
39*0Sstevel@tonic-gate                while read i; do
40*0Sstevel@tonic-gate                        echo "$i"
41*0Sstevel@tonic-gate                done < $1
42*0Sstevel@tonic-gate                shift
43*0Sstevel@tonic-gate        done
44*0Sstevel@tonic-gate}
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate#
47*0Sstevel@tonic-gate# Inet_list, list of IPv4 interfaces.
48*0Sstevel@tonic-gate# Inet_plumbed, list of plumbed IPv4 interfaces.
49*0Sstevel@tonic-gate# Inet_failed, list of IPv4 interfaces that failed to plumb.
50*0Sstevel@tonic-gate# Inet6_list, list of IPv6 interfaces.
51*0Sstevel@tonic-gate# Inet6_plumbed, list of plumbed IPv6 interfaces.
52*0Sstevel@tonic-gate# Inet6_failed, list of IPv6 interfaces that failed to plumb.
53*0Sstevel@tonic-gate#
54*0Sstevel@tonic-gateunset inet_list inet_plumbed inet_failed \
55*0Sstevel@tonic-gate	inet6_list inet6_plumbed inet6_failed
56*0Sstevel@tonic-gate#
57*0Sstevel@tonic-gate# get_physical interface
58*0Sstevel@tonic-gate#
59*0Sstevel@tonic-gate# Return physical interface corresponding to the given logical
60*0Sstevel@tonic-gate# interface.
61*0Sstevel@tonic-gate#
62*0Sstevel@tonic-gateget_physical()
63*0Sstevel@tonic-gate{
64*0Sstevel@tonic-gate	ORIGIFS="$IFS"
65*0Sstevel@tonic-gate	IFS="${IFS}:"
66*0Sstevel@tonic-gate	set -- $1
67*0Sstevel@tonic-gate	IFS="$ORIGIFS"
68*0Sstevel@tonic-gate
69*0Sstevel@tonic-gate	echo $1
70*0Sstevel@tonic-gate}
71*0Sstevel@tonic-gate
72*0Sstevel@tonic-gate#
73*0Sstevel@tonic-gate# get_logical interface
74*0Sstevel@tonic-gate#
75*0Sstevel@tonic-gate# Return logical interface number.  Zero will be returned
76*0Sstevel@tonic-gate# if there is no explicit logical device number.
77*0Sstevel@tonic-gate#
78*0Sstevel@tonic-gateget_logical()
79*0Sstevel@tonic-gate{
80*0Sstevel@tonic-gate	ORIGIFS="$IFS"
81*0Sstevel@tonic-gate	IFS="${IFS}:"
82*0Sstevel@tonic-gate	set -- $1
83*0Sstevel@tonic-gate	IFS="$ORIGIFS"
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate	if [ -z "$2" ]; then
86*0Sstevel@tonic-gate		echo 0
87*0Sstevel@tonic-gate	else
88*0Sstevel@tonic-gate		echo $2
89*0Sstevel@tonic-gate	fi
90*0Sstevel@tonic-gate}
91*0Sstevel@tonic-gate
92*0Sstevel@tonic-gate#
93*0Sstevel@tonic-gate# if_comp if1 if2
94*0Sstevel@tonic-gate#
95*0Sstevel@tonic-gate# Compare Interfaces.  Do the physical interface names and logical interface
96*0Sstevel@tonic-gate# numbers match?
97*0Sstevel@tonic-gate#
98*0Sstevel@tonic-gateif_comp()
99*0Sstevel@tonic-gate{
100*0Sstevel@tonic-gate	[ "`get_physical $1`" = "`get_physical $2`" ] && \
101*0Sstevel@tonic-gate		[ `get_logical $1` -eq `get_logical $2` ]
102*0Sstevel@tonic-gate}
103*0Sstevel@tonic-gate
104*0Sstevel@tonic-gate#
105*0Sstevel@tonic-gate# physical_comp if1 if2
106*0Sstevel@tonic-gate#
107*0Sstevel@tonic-gate# Do the two devices share a physical interface?
108*0Sstevel@tonic-gate#
109*0Sstevel@tonic-gatephysical_comp()
110*0Sstevel@tonic-gate{
111*0Sstevel@tonic-gate	[ "`get_physical $1`" = "`get_physical $2`" ]
112*0Sstevel@tonic-gate}
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate#
115*0Sstevel@tonic-gate# in_list op item list
116*0Sstevel@tonic-gate#
117*0Sstevel@tonic-gate# Is "item" in the given list?  Use "op" to do the test, applying it to
118*0Sstevel@tonic-gate# "item" and each member of the list in turn until it returns success.
119*0Sstevel@tonic-gate#
120*0Sstevel@tonic-gatein_list()
121*0Sstevel@tonic-gate{
122*0Sstevel@tonic-gate	op=$1
123*0Sstevel@tonic-gate	item=$2
124*0Sstevel@tonic-gate	shift 2
125*0Sstevel@tonic-gate
126*0Sstevel@tonic-gate	while [ $# -gt 0 ]; do
127*0Sstevel@tonic-gate		$op $item $1 && return 0
128*0Sstevel@tonic-gate		shift
129*0Sstevel@tonic-gate	done
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate	return 1
132*0Sstevel@tonic-gate}
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gate#
135*0Sstevel@tonic-gate# get_group_from_hostname interface type
136*0Sstevel@tonic-gate#
137*0Sstevel@tonic-gate# Return all group settings from hostname file for a given interface.
138*0Sstevel@tonic-gate#
139*0Sstevel@tonic-gate# Example:
140*0Sstevel@tonic-gate#	get_group_from_hostname  hme0 inet
141*0Sstevel@tonic-gate#
142*0Sstevel@tonic-gateget_group_from_hostname()
143*0Sstevel@tonic-gate{
144*0Sstevel@tonic-gate	case "$2" in
145*0Sstevel@tonic-gate		inet) file=/etc/hostname.$1
146*0Sstevel@tonic-gate			;;
147*0Sstevel@tonic-gate		inet6) file=/etc/hostname6.$1
148*0Sstevel@tonic-gate			;;
149*0Sstevel@tonic-gate		*)
150*0Sstevel@tonic-gate			return
151*0Sstevel@tonic-gate			;;
152*0Sstevel@tonic-gate	esac
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate	[ -r "$file" ] || return
155*0Sstevel@tonic-gate
156*0Sstevel@tonic-gate	#
157*0Sstevel@tonic-gate	# Read through the hostname file looking for group settings
158*0Sstevel@tonic-gate	# There may be several group settings in the file.  It is up
159*0Sstevel@tonic-gate	# to the caller to pick the right one (i.e. the last one).
160*0Sstevel@tonic-gate	#
161*0Sstevel@tonic-gate	while read line; do
162*0Sstevel@tonic-gate		[ -z "$line" ] && continue
163*0Sstevel@tonic-gate		/sbin/ifparse -s "$2" $line
164*0Sstevel@tonic-gate	done < "$file" | while read one two three; do
165*0Sstevel@tonic-gate		[ "$one" = "group" ] && echo "$two"
166*0Sstevel@tonic-gate	done
167*0Sstevel@tonic-gate}
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gate#
170*0Sstevel@tonic-gate# get_group_for_type interface type list
171*0Sstevel@tonic-gate#
172*0Sstevel@tonic-gate# Look through the set of hostname files associated with the same physical
173*0Sstevel@tonic-gate# interface as "interface", and determine which group they would configure.
174*0Sstevel@tonic-gate# Only hostname files associated with the physical interface or logical
175*0Sstevel@tonic-gate# interface zero are allowed to set the group.
176*0Sstevel@tonic-gate#
177*0Sstevel@tonic-gateget_group_for_type()
178*0Sstevel@tonic-gate{
179*0Sstevel@tonic-gate	physical=`get_physical $1`
180*0Sstevel@tonic-gate
181*0Sstevel@tonic-gate	type=$2
182*0Sstevel@tonic-gate	group=""
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate	#
185*0Sstevel@tonic-gate	# The last setting of the group is the one that counts, which is
186*0Sstevel@tonic-gate	# the reason for the second while loop.
187*0Sstevel@tonic-gate	#
188*0Sstevel@tonic-gate	shift 2
189*0Sstevel@tonic-gate	while [ $# -gt 0 ]; do
190*0Sstevel@tonic-gate		if if_comp "$physical" $1; then
191*0Sstevel@tonic-gate			get_group_from_hostname $1 $type
192*0Sstevel@tonic-gate		fi
193*0Sstevel@tonic-gate		shift
194*0Sstevel@tonic-gate	done | while :; do
195*0Sstevel@tonic-gate		read next || {
196*0Sstevel@tonic-gate			echo "$group"
197*0Sstevel@tonic-gate			break
198*0Sstevel@tonic-gate		}
199*0Sstevel@tonic-gate		group="$next"
200*0Sstevel@tonic-gate	done
201*0Sstevel@tonic-gate}
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gate#
204*0Sstevel@tonic-gate# get_group interface [ configured | failed ]
205*0Sstevel@tonic-gate#
206*0Sstevel@tonic-gate# If there is both an inet and inet6 version of an interface, the group
207*0Sstevel@tonic-gate# could be set in either set of hostname files.
208*0Sstevel@tonic-gate#
209*0Sstevel@tonic-gate# Inet6 is configured after inet, so if the group is set in both
210*0Sstevel@tonic-gate# sets of hostname files, the inet6 file wins.
211*0Sstevel@tonic-gate#
212*0Sstevel@tonic-gate# The "configured" argument should be used to get the group for
213*0Sstevel@tonic-gate# an interface that has been plumbed into the stack and configured.  Use
214*0Sstevel@tonic-gate# the "failed" argument to get the group for an interface that failed to
215*0Sstevel@tonic-gate# plumb.
216*0Sstevel@tonic-gate#
217*0Sstevel@tonic-gateget_group()
218*0Sstevel@tonic-gate{
219*0Sstevel@tonic-gate	group=""
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate	case "$2" in
222*0Sstevel@tonic-gate		configured)
223*0Sstevel@tonic-gate			group=`get_group_for_type $1 inet6 $inet6_plumbed`
224*0Sstevel@tonic-gate			;;
225*0Sstevel@tonic-gate		failed)
226*0Sstevel@tonic-gate			group=`get_group_for_type $1 inet6 $inet6_list`
227*0Sstevel@tonic-gate			;;
228*0Sstevel@tonic-gate		*)
229*0Sstevel@tonic-gate			return
230*0Sstevel@tonic-gate			;;
231*0Sstevel@tonic-gate	esac
232*0Sstevel@tonic-gate
233*0Sstevel@tonic-gate	if [ -z "$group" ]; then
234*0Sstevel@tonic-gate		if [ "$2" = configured ]; then
235*0Sstevel@tonic-gate			group=`get_group_for_type $1 inet $inet_plumbed`
236*0Sstevel@tonic-gate		else
237*0Sstevel@tonic-gate			group=`get_group_for_type $1 inet $inet_list`
238*0Sstevel@tonic-gate		fi
239*0Sstevel@tonic-gate	fi
240*0Sstevel@tonic-gate
241*0Sstevel@tonic-gate	echo $group
242*0Sstevel@tonic-gate}
243*0Sstevel@tonic-gate
244*0Sstevel@tonic-gate#
245*0Sstevel@tonic-gate# get_standby_from_hostname interface type
246*0Sstevel@tonic-gate#
247*0Sstevel@tonic-gate# Return any "standby" or "-standby" flags in the hostname file.
248*0Sstevel@tonic-gate#
249*0Sstevel@tonic-gate# Example:
250*0Sstevel@tonic-gate#	get_standby_from_hostname hme0 inet6
251*0Sstevel@tonic-gate#
252*0Sstevel@tonic-gate#
253*0Sstevel@tonic-gateget_standby_from_hostname()
254*0Sstevel@tonic-gate{
255*0Sstevel@tonic-gate	case "$2" in
256*0Sstevel@tonic-gate		inet) file=/etc/hostname.$1
257*0Sstevel@tonic-gate			;;
258*0Sstevel@tonic-gate		inet6) file=/etc/hostname6.$1
259*0Sstevel@tonic-gate			;;
260*0Sstevel@tonic-gate		*)
261*0Sstevel@tonic-gate			return
262*0Sstevel@tonic-gate			;;
263*0Sstevel@tonic-gate	esac
264*0Sstevel@tonic-gate
265*0Sstevel@tonic-gate	[ -r "$file" ] || return
266*0Sstevel@tonic-gate
267*0Sstevel@tonic-gate	#
268*0Sstevel@tonic-gate	# There may be several instances of the "standby" and
269*0Sstevel@tonic-gate	# "-standby" flags in the hostname file.  It is up to
270*0Sstevel@tonic-gate	# the caller to pick the correct one.
271*0Sstevel@tonic-gate	#
272*0Sstevel@tonic-gate	while read line; do
273*0Sstevel@tonic-gate		[ -z "$line" ] && continue
274*0Sstevel@tonic-gate		/sbin/ifparse -s "$2" $line
275*0Sstevel@tonic-gate	done < "$file" | while read one two; do
276*0Sstevel@tonic-gate		[ "$one" = "standby" ] || [ "$one" = "-standby" ] \
277*0Sstevel@tonic-gate			&& echo "$one"
278*0Sstevel@tonic-gate	done
279*0Sstevel@tonic-gate}
280*0Sstevel@tonic-gate
281*0Sstevel@tonic-gate#
282*0Sstevel@tonic-gate# get_standby_for_type interface type plumbed_list
283*0Sstevel@tonic-gate#
284*0Sstevel@tonic-gate# Look through the set of hostname files associated with the same physical
285*0Sstevel@tonic-gate# interface as "interface", and determine whether they would configure
286*0Sstevel@tonic-gate# the interface as a standby interface.
287*0Sstevel@tonic-gate#
288*0Sstevel@tonic-gateget_standby_for_type()
289*0Sstevel@tonic-gate{
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate	physical=`get_physical $1`
292*0Sstevel@tonic-gate	type=$2
293*0Sstevel@tonic-gate
294*0Sstevel@tonic-gate	final=""
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate	#
297*0Sstevel@tonic-gate	# The last "standby" or "-standby" flag is the one that counts,
298*0Sstevel@tonic-gate	# which is the reason for the second while loop.
299*0Sstevel@tonic-gate	#
300*0Sstevel@tonic-gate	shift 2
301*0Sstevel@tonic-gate	while [ $# -gt 0 ]; do
302*0Sstevel@tonic-gate		if [ "`get_physical $1`" = "$physical" ]; then
303*0Sstevel@tonic-gate			get_standby_from_hostname $1 $type
304*0Sstevel@tonic-gate		fi
305*0Sstevel@tonic-gate		shift
306*0Sstevel@tonic-gate	done | while :; do
307*0Sstevel@tonic-gate		read next || {
308*0Sstevel@tonic-gate			echo "$final"
309*0Sstevel@tonic-gate			break
310*0Sstevel@tonic-gate		}
311*0Sstevel@tonic-gate		final="$next"
312*0Sstevel@tonic-gate	done
313*0Sstevel@tonic-gate}
314*0Sstevel@tonic-gate
315*0Sstevel@tonic-gate#
316*0Sstevel@tonic-gate# is_standby interface
317*0Sstevel@tonic-gate#
318*0Sstevel@tonic-gate# Determine whether a configured interface is a standby interface.
319*0Sstevel@tonic-gate#
320*0Sstevel@tonic-gate# Both the inet and inet6 hostname file sets must be checked.
321*0Sstevel@tonic-gate# If "standby" or "-standby" is set in the inet6 hostname file set,
322*0Sstevel@tonic-gate# don't bother looking at the inet set.
323*0Sstevel@tonic-gate#
324*0Sstevel@tonic-gateis_standby()
325*0Sstevel@tonic-gate{
326*0Sstevel@tonic-gate	standby=`get_standby_for_type $1 inet6 $inet6_plumbed`
327*0Sstevel@tonic-gate
328*0Sstevel@tonic-gate	if [ -z "$standby" ]; then
329*0Sstevel@tonic-gate		standby=`get_standby_for_type $1 inet $inet_plumbed`
330*0Sstevel@tonic-gate	fi
331*0Sstevel@tonic-gate
332*0Sstevel@tonic-gate	# The return value is the value of the following test.
333*0Sstevel@tonic-gate	[ "$standby" = "standby" ]
334*0Sstevel@tonic-gate}
335*0Sstevel@tonic-gate
336*0Sstevel@tonic-gate#
337*0Sstevel@tonic-gate# get_alternate interface plumbed_list
338*0Sstevel@tonic-gate#
339*0Sstevel@tonic-gate# Look for a plumbed interface in the same group as "interface".
340*0Sstevel@tonic-gate# A standby interface is preferred over a non-standby interface.
341*0Sstevel@tonic-gate#
342*0Sstevel@tonic-gate# Example:
343*0Sstevel@tonic-gate#	get_alternate hme0 $inet_plumbed
344*0Sstevel@tonic-gate#
345*0Sstevel@tonic-gateget_alternate()
346*0Sstevel@tonic-gate{
347*0Sstevel@tonic-gate	mygroup=`get_group $1 failed`
348*0Sstevel@tonic-gate	[ -z "$mygroup" ] && return
349*0Sstevel@tonic-gate
350*0Sstevel@tonic-gate	maybe=""
351*0Sstevel@tonic-gate
352*0Sstevel@tonic-gate	shift
353*0Sstevel@tonic-gate	while [ $# -gt 0 ]; do
354*0Sstevel@tonic-gate		group=`get_group $1 configured`
355*0Sstevel@tonic-gate		if [ "$group" = "$mygroup" ]; then
356*0Sstevel@tonic-gate			if is_standby $1; then
357*0Sstevel@tonic-gate				get_physical $1
358*0Sstevel@tonic-gate				return
359*0Sstevel@tonic-gate			else
360*0Sstevel@tonic-gate				[ -z "$maybe" ] && maybe=$1
361*0Sstevel@tonic-gate			fi
362*0Sstevel@tonic-gate		fi
363*0Sstevel@tonic-gate		shift
364*0Sstevel@tonic-gate	done
365*0Sstevel@tonic-gate
366*0Sstevel@tonic-gate	get_physical $maybe
367*0Sstevel@tonic-gate}
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gate#
370*0Sstevel@tonic-gate# doDHCPhostname interface
371*0Sstevel@tonic-gate# Pass to this function the name of an interface.  It will return
372*0Sstevel@tonic-gate# true if one should enable the use of DHCP client-side host name
373*0Sstevel@tonic-gate# requests on the interface, and false otherwise.
374*0Sstevel@tonic-gate#
375*0Sstevel@tonic-gatedoDHCPhostname()
376*0Sstevel@tonic-gate{
377*0Sstevel@tonic-gate	if [ -f /etc/dhcp.$1 ] && [ -f /etc/hostname.$1 ]; then
378*0Sstevel@tonic-gate                set -- `shcat /etc/hostname.$1`
379*0Sstevel@tonic-gate                [ $# -eq 2 -a "$1" = "inet" ]
380*0Sstevel@tonic-gate                return $?
381*0Sstevel@tonic-gate        fi
382*0Sstevel@tonic-gate        return 1
383*0Sstevel@tonic-gate}
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gate#
386*0Sstevel@tonic-gate# inet_process_hostname processor [ args ]
387*0Sstevel@tonic-gate#
388*0Sstevel@tonic-gate# Process an inet hostname file.  The contents of the file
389*0Sstevel@tonic-gate# are taken from standard input. Each line is passed
390*0Sstevel@tonic-gate# on the command line to the "processor" command.
391*0Sstevel@tonic-gate# Command line arguments can be passed to the processor.
392*0Sstevel@tonic-gate#
393*0Sstevel@tonic-gate# Examples:
394*0Sstevel@tonic-gate#	inet_process_hostname /sbin/ifconfig hme0 < /etc/hostname.hme0
395*0Sstevel@tonic-gate#
396*0Sstevel@tonic-gate#	inet_process_hostname /sbin/ifparse -f < /etc/hostname.hme0
397*0Sstevel@tonic-gate#
398*0Sstevel@tonic-gate# If there is only line in an hostname file we assume it contains
399*0Sstevel@tonic-gate# the old style address which results in the interface being brought up
400*0Sstevel@tonic-gate# and the netmask and broadcast address being set.
401*0Sstevel@tonic-gate#
402*0Sstevel@tonic-gate# If there are multiple lines we assume the file contains a list of
403*0Sstevel@tonic-gate# commands to the processor with neither the implied bringing up of the
404*0Sstevel@tonic-gate# interface nor the setting of the default netmask and broadcast address.
405*0Sstevel@tonic-gate#
406*0Sstevel@tonic-gate# Return non-zero if any command fails so that the caller may alert
407*0Sstevel@tonic-gate# users to errors in the configuration.
408*0Sstevel@tonic-gate#
409*0Sstevel@tonic-gateinet_process_hostname()
410*0Sstevel@tonic-gate{
411*0Sstevel@tonic-gate	if doDHCPhostname $2; then
412*0Sstevel@tonic-gate		:
413*0Sstevel@tonic-gate	else
414*0Sstevel@tonic-gate		#
415*0Sstevel@tonic-gate		# Redirecting input from a file results in a sub-shell being
416*0Sstevel@tonic-gate		# used, hence this outer loop surrounding the "multiple_lines"
417*0Sstevel@tonic-gate		# and "ifcmds" variables.
418*0Sstevel@tonic-gate		#
419*0Sstevel@tonic-gate		while :; do
420*0Sstevel@tonic-gate			multiple_lines=false
421*0Sstevel@tonic-gate			ifcmds=""
422*0Sstevel@tonic-gate			retval=0
423*0Sstevel@tonic-gate
424*0Sstevel@tonic-gate			while read line; do
425*0Sstevel@tonic-gate				if [ -n "$ifcmds" ]; then
426*0Sstevel@tonic-gate					#
427*0Sstevel@tonic-gate					# This handles the first N-1
428*0Sstevel@tonic-gate					# lines of a N-line hostname file.
429*0Sstevel@tonic-gate					#
430*0Sstevel@tonic-gate					$* $ifcmds || retval=$?
431*0Sstevel@tonic-gate					multiple_lines=true
432*0Sstevel@tonic-gate				fi
433*0Sstevel@tonic-gate				ifcmds="$line"
434*0Sstevel@tonic-gate			done
435*0Sstevel@tonic-gate
436*0Sstevel@tonic-gate			#
437*0Sstevel@tonic-gate			# If the hostname file is empty or consists of only
438*0Sstevel@tonic-gate			# blank lines, break out of the outer loop without
439*0Sstevel@tonic-gate			# configuring the newly plumbed interface.
440*0Sstevel@tonic-gate			#
441*0Sstevel@tonic-gate			[ -z "$ifcmds" ] && return $retval
442*0Sstevel@tonic-gate			if [ $multiple_lines = false ]; then
443*0Sstevel@tonic-gate				# The traditional single-line hostname file.
444*0Sstevel@tonic-gate				ifcmds="$ifcmds netmask + broadcast + up"
445*0Sstevel@tonic-gate			fi
446*0Sstevel@tonic-gate
447*0Sstevel@tonic-gate			#
448*0Sstevel@tonic-gate			# This handles either the single-line case or
449*0Sstevel@tonic-gate			# the last line of the N-line case.
450*0Sstevel@tonic-gate			#
451*0Sstevel@tonic-gate			$* $ifcmds || return $?
452*0Sstevel@tonic-gate			return $retval
453*0Sstevel@tonic-gate		done
454*0Sstevel@tonic-gate	fi
455*0Sstevel@tonic-gate}
456*0Sstevel@tonic-gate
457*0Sstevel@tonic-gate#
458*0Sstevel@tonic-gate# inet6_process_hostname processor [ args ]
459*0Sstevel@tonic-gate#
460*0Sstevel@tonic-gate# Process an inet6 hostname file.  The contents of the file
461*0Sstevel@tonic-gate# are taken from standard input. Each line is passed
462*0Sstevel@tonic-gate# on the command line to the "processor" command.
463*0Sstevel@tonic-gate# Command line arguments can be passed to the processor.
464*0Sstevel@tonic-gate#
465*0Sstevel@tonic-gate# Examples:
466*0Sstevel@tonic-gate#	inet6_process_hostname /sbin/ifconfig hme0 inet6 < /etc/hostname6.hme0
467*0Sstevel@tonic-gate#
468*0Sstevel@tonic-gate#	inet6_process_hostname /sbin/ifparse -f inet6 < /etc/hostname6.hme0
469*0Sstevel@tonic-gate#
470*0Sstevel@tonic-gate# Return non-zero if any of the commands fail so that the caller may alert
471*0Sstevel@tonic-gate# users to errors in the configuration.
472*0Sstevel@tonic-gate#
473*0Sstevel@tonic-gateinet6_process_hostname()
474*0Sstevel@tonic-gate{
475*0Sstevel@tonic-gate    	retval=0
476*0Sstevel@tonic-gate	while read ifcmds; do
477*0Sstevel@tonic-gate		if [ -n "$ifcmds" ]; then
478*0Sstevel@tonic-gate			$* $ifcmds || retval=$?
479*0Sstevel@tonic-gate		fi
480*0Sstevel@tonic-gate	done
481*0Sstevel@tonic-gate	return $retval
482*0Sstevel@tonic-gate}
483*0Sstevel@tonic-gate
484*0Sstevel@tonic-gate#
485*0Sstevel@tonic-gate# Process interfaces that failed to plumb.  Find an alternative
486*0Sstevel@tonic-gate# interface to host the addresses.  For IPv6, only static addresses
487*0Sstevel@tonic-gate# defined in hostname6 files are moved, autoconfigured addresses are
488*0Sstevel@tonic-gate# not moved.
489*0Sstevel@tonic-gate#
490*0Sstevel@tonic-gate# Example:
491*0Sstevel@tonic-gate#	move_addresses inet6
492*0Sstevel@tonic-gate#
493*0Sstevel@tonic-gatemove_addresses()
494*0Sstevel@tonic-gate{
495*0Sstevel@tonic-gate	type="$1"
496*0Sstevel@tonic-gate	eval "failed=\"\$${type}_failed\""
497*0Sstevel@tonic-gate	eval "plumbed=\"\$${type}_plumbed\""
498*0Sstevel@tonic-gate	eval "list=\"\$${type}_list\""
499*0Sstevel@tonic-gate	process_hostname="${type}_process_hostname"
500*0Sstevel@tonic-gate	processed=""
501*0Sstevel@tonic-gate
502*0Sstevel@tonic-gate	if [ "$type" = inet ]; then
503*0Sstevel@tonic-gate		echo "moving addresses from failed IPv4 interfaces:\c"
504*0Sstevel@tonic-gate		zaddr="0.0.0.0"
505*0Sstevel@tonic-gate		hostpfx="/etc/hostname"
506*0Sstevel@tonic-gate	else
507*0Sstevel@tonic-gate		echo "moving addresses from failed IPv6 interfaces:\c"
508*0Sstevel@tonic-gate		zaddr="::"
509*0Sstevel@tonic-gate		hostpfx="/etc/hostname6"
510*0Sstevel@tonic-gate	fi
511*0Sstevel@tonic-gate
512*0Sstevel@tonic-gate	set -- $failed
513*0Sstevel@tonic-gate	while [ $# -gt 0 ]; do
514*0Sstevel@tonic-gate		in_list if_comp $1 $processed && { shift; continue; }
515*0Sstevel@tonic-gate
516*0Sstevel@tonic-gate		alternate="`get_alternate $1 $plumbed`"
517*0Sstevel@tonic-gate		if [ -z "$alternate" ]; then
518*0Sstevel@tonic-gate			in_list physical_comp $1 $processed || {
519*0Sstevel@tonic-gate				echo " $1 (couldn't move, no" \
520*0Sstevel@tonic-gate					"alternative interface)\c"
521*0Sstevel@tonic-gate				processed="$processed $1"
522*0Sstevel@tonic-gate			}
523*0Sstevel@tonic-gate			shift
524*0Sstevel@tonic-gate			continue
525*0Sstevel@tonic-gate		fi
526*0Sstevel@tonic-gate		#
527*0Sstevel@tonic-gate		# The hostname files are processed twice.  In the first
528*0Sstevel@tonic-gate		# pass, we are looking for all commands that apply
529*0Sstevel@tonic-gate		# to the non-additional interface address.  These may be
530*0Sstevel@tonic-gate		# scattered over several files.  We won't know
531*0Sstevel@tonic-gate		# whether the address represents a failover address
532*0Sstevel@tonic-gate		# or not until we've read all the files associated with the
533*0Sstevel@tonic-gate		# interface.
534*0Sstevel@tonic-gate
535*0Sstevel@tonic-gate		# In the first pass through the hostname files, all
536*0Sstevel@tonic-gate		# additional logical interface commands are removed.
537*0Sstevel@tonic-gate		# The remaining commands are concatenated together and
538*0Sstevel@tonic-gate		# passed to ifparse to determine whether the
539*0Sstevel@tonic-gate		# non-additional logical interface address is a failover
540*0Sstevel@tonic-gate		# address.  If it as a failover address, the
541*0Sstevel@tonic-gate		# address may not be the first item on the line,
542*0Sstevel@tonic-gate		# so we can't just substitute "addif" for "set".
543*0Sstevel@tonic-gate		# We prepend an "addif $zaddr" command, and let
544*0Sstevel@tonic-gate		# the embedded "set" command set the address later.
545*0Sstevel@tonic-gate		#
546*0Sstevel@tonic-gate		/sbin/ifparse -f $type `
547*0Sstevel@tonic-gate				for item in $list; do
548*0Sstevel@tonic-gate					if_comp $1 $item && \
549*0Sstevel@tonic-gate					$process_hostname /sbin/ifparse \
550*0Sstevel@tonic-gate					$type < $hostpfx.$item
551*0Sstevel@tonic-gate					done  | while read three four; do
552*0Sstevel@tonic-gate					[ "$three" != addif ] && \
553*0Sstevel@tonic-gate						echo "$three $four \c"
554*0Sstevel@tonic-gate				done` | while read one two; do
555*0Sstevel@tonic-gate					[ -z "$one" ] && continue
556*0Sstevel@tonic-gate					line="addif $zaddr $one $two"
557*0Sstevel@tonic-gate					/sbin/ifconfig $alternate $type \
558*0Sstevel@tonic-gate						-standby $line >/dev/null
559*0Sstevel@tonic-gate				done
560*0Sstevel@tonic-gate
561*0Sstevel@tonic-gate		#
562*0Sstevel@tonic-gate		# In the second pass, look for the the "addif" commands
563*0Sstevel@tonic-gate		# that configure additional failover addresses.  Addif
564*0Sstevel@tonic-gate		# commands are not valid in logical interface hostname
565*0Sstevel@tonic-gate		# files.
566*0Sstevel@tonic-gate		#
567*0Sstevel@tonic-gate		if [ "$1" = "`get_physical $1`" ]; then
568*0Sstevel@tonic-gate			$process_hostname /sbin/ifparse -f $type \
569*0Sstevel@tonic-gate			<$hostpfx.$1 | while read one two; do
570*0Sstevel@tonic-gate			[ "$one" = addif ] && \
571*0Sstevel@tonic-gate				/sbin/ifconfig $alternate $type -standby \
572*0Sstevel@tonic-gate				    addif $two >/dev/null
573*0Sstevel@tonic-gate			done
574*0Sstevel@tonic-gate		fi
575*0Sstevel@tonic-gate
576*0Sstevel@tonic-gate		in_list physical_comp $1 $processed || {
577*0Sstevel@tonic-gate			echo " $1 (moved to $alternate)\c"
578*0Sstevel@tonic-gate			processed="$processed $1"
579*0Sstevel@tonic-gate		}
580*0Sstevel@tonic-gate		shift
581*0Sstevel@tonic-gate	done
582*0Sstevel@tonic-gate	echo "."
583*0Sstevel@tonic-gate}
584