File: functions

package info (click to toggle)
oldsys-preseed 3.23
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 532 kB
  • sloc: xml: 438; sh: 304; makefile: 4
file content (298 lines) | stat: -rw-r--r-- 7,976 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# Copyright (C) 2005, 2006, 2008, 2009  Martin Michlmayr <tbm@cyrius.com>
# Copyright (C) 2008  Matthew Palmer <mpalmer@debian.org>
# Copyright (C) 2009  Stephen Gran <sgran@debian.org>

# This code is covered by the GNU General Public License (version 2
# or higher)

# Reading

# Check if a file exists and exit if it doesn't
# $1 = file
check_file() {
	if [ ! -e $1 ]; then
		log "$1 does not exist"
		exit
	fi
}

# Returns the mtd device with the specified name (without leading /dev)
# $1 = name of mtd device
get_mtd() {
	grep "\b$1\b\"*$" /proc/mtd | cut -d : -f 1
}

# Returns the mtd block device with the specified name (without leading /dev)
# $1 = name of mtd device
get_mtdblock() {
	echo $(get_mtd "$1") | sed 's/mtd/mtdblock/'
}

# Parsing

# Parse a standard Unix tree (i.e. configs found in /etc)
# $1 = root path
parse_unix_tree() {
	log "Parsing Unix tree at $1"
	ETC=$1/etc
	if [ -e $ETC/network/interfaces ]; then
		parse_network_interfaces $ETC/network/interfaces "eth0"
	fi
	if [ -e $ETC/resolv.conf ]; then
		for i in $(grep "^nameserver" $ETC/resolv.conf | sed 's/^.* //'); do
			var_add NAMESERVERS "$i"
		done
	fi
	if [ -e $ETC/hostname ]; then
		HOSTNAME=$(cat $ETC/hostname | cut -d . -f 1)
	fi
	if [ -e $ETC/domainname ]; then
		DOMAIN=$(cat $ETC/domainname)
	fi
}

# LEAF is a distro based on LRP (Linux Router Project)
# $1 = root path
parse_leaf_tree() {
	log "Parsing LEAF tree at $1"
	ETC=$1/etc
	if [ -e $ETC/resolv.static1 ]; then
		var_add NAMESERVERS "$(grep "^nameserver" $ETC/resolv.static1 | sed 's/^.* //' | head -n 1)"
	fi
	if [ -e $ETC/resolv.static2 ]; then
		var_add NAMESERVERS "$(grep "^nameserver" $ETC/resolv.static2 | sed 's/^.* //' | head -n 1)"
	fi
}

# Parse a /etc/network/interfaces file
# $1 = file
# $2 = interface
parse_network_interfaces() {
	log "Parsing $1 to find network interface $2"

	# Find the interface we're interested in
	if ! $(grep -q "^iface $2\b" $1); then
		return
	fi
	iface=$(grep -n "^iface $2\b" $1)
	if $(echo "$iface" | grep -q "inet static"); then
		n=$(echo "$iface" | cut -d : -f 1) # line number
		NET_CONFIG=static
		stanza=$(tail -n +$(($n+1)) $1)
		# Find the next interface and ignore lines from there on
		n=$(echo "$stanza" | grep -n "^iface\b" | cut -d : -f 1)
		if [ $n ]; then
			stanza=$(echo "$stanza" | head -n $(($n-1)))
		fi
		INTERFACE=$2
		IPADDRESS=$(echo "$stanza" | grep "address" | sed 's/.*address //')
		GATEWAY=$(echo "$stanza" | grep "gateway" | sed 's/.*gateway //')
	fi
}

# Parse a set of ifconfig/route/etc commands
# $1 = ifconfig et al. commands
parse_ifconfig() {
	# UGH!
	IPADDRESS=$(grep "ifconfig [-[:alpha:][:digit:]]* [[:digit:].]" $1 | sed 's/.*ifconfig [-[:alpha:][:digit:]]* \([.[:digit:]]*\) .*/\1/')
	NETMASK=$(grep '\bnetmask\b' $1 | sed 's/.*netmask\s*//' | sed 's/\s.*//')
	GATEWAY=$(grep "route add default gw" $1 | sed 's/.*gw\s*//')
}

# Get the value from a string in the form of var=value
# $1 = string
# $2 = var
get_var() {
	echo "$1" | grep -a "^$2=" | sed "s/^$2=//"
}

# Get the value from a string in the form of var = "value" from a file.
# Named for the sib.conf file on the D-Link DNS-323 that this function
# was originally written for.
# $1 = file to read
# $2 = var to read
get_sib_var() {
	grep "^$2[[:space:]]*=" $1 | sed "s/^$2[[:space:]]*=[[:space:]]*\"\(.*\)\"[[:space:]]*$/\1/"
}

# Add a string to a variable; deals with the fact when a string is empty
# $1 = variable name
# $2 = string
var_add() {
	if [ -n "$2" ]; then
		value="$(eval echo \"$`echo $1`\")"
		if [ -n "$value" ]; then
			x="$value $2"
		else
			x="$2"
		fi
		eval "`echo $1`=\"$x\""
	fi
}

# Return the value of a XML/HTML like <foo>value</foo> staetment.
remove_xml() {
	echo "$1" | sed 's/[^>]*> *//' | sed 's/ *<.*//'
}

# Parse the sib.conf file, as found in the D-Link DNS-323
# $1 = path to sib.conf
parse_sib_conf() {
	if [ "$(get_sib_var "$1" "CF-IP-DHCP-ENABLE")" = "0" ]; then
		NET_CONFIG=static
	fi
	IPADDRESS="$(get_sib_var "$1" "CF-IP-STATIC-IP")"
	NETMASK="$(get_sib_var "$1" "CF-IP-STATIC-IP-NETMASK")"
	GATEWAY="$(get_sib_var "$1" "CF-IP-STATIC-IP-GATEWAY")"
	var_add NAMESERVERS "$(get_sib_var "$1" "CF-IP-DNS1")"
	var_add NAMESERVERS "$(get_sib_var "$1" "CF-IP-DNS2")"
	HOSTNAME="$(get_sib_var "$1" "CF-SYS-MODEL-STR")"
}

# Generating

# Output a variable to a preseed file if the variable has a value
# $1 = file name (stdout if this is empty)
# $2 = debconf variable name
# $3 = debconf variable type
# $4 = variable
add() {
	if [ -n "$4" -o "$3" = "note" ]; then
		if [ -n "$1" ]; then
			echo "d-i $2 $3 $4" | sed 's/ *$//' >> "$1"
		else
			echo "d-i $2 $3 $4" | sed 's/ *$//'
		fi
	fi
}

# Output a variable to a preseed file or, iv the variable is empty, mark
# the debconf variable as seen.
# $1 = file name (stdout if this is empty)
# $2 = debconf variable name
# $3 = debconf variable type
# $4 = variable
add_or_set_seen() {
	if [ -z "$4" -a "$NONINTERACTIVE" = "yes" ]; then
		add "$1" "$2" "seen" "true"
	else
		add "$1" "$2" "$3" "$4"
	fi
}

# Write a static network configuration to the preseed file
# $1 = file name (stdout if this is empty)
write_static_network() {
	add "$1" "netcfg/get_ipaddress" "string" "$IPADDRESS"
	add_or_set_seen "$1" "netcfg/get_netmask" "string" "$NETMASK"
	if [ -z "$GATEWAY" ]; then
		GATEWAY=none
	fi
	add "$1" "netcfg/get_gateway" "string" "$GATEWAY"
	add "$1" "netcfg/get_nameservers" "string" "$NAMESERVERS"
}

# Fall back to a static address if DHCP fails
# $1 = file name (stdout if this is empty)
dhcp_fallback() {
	add "$1" "netcfg/dhcp_failed" "note"
	add "$1" "netcfg/dhcp_options" "select" "Configure network manually"
	write_static_network "$1"
}

# Generate a preseed file
# $1 = filename
generate_preseed_file() {
	add "$1" "netcfg/choose_interface" "select" "$INTERFACE"
	if [ "$NET_CONFIG" = "static" ]; then
		write_static_network "$1"
		add "$1" "netcfg/confirm_static" "boolean" "true"
		add "$1" "netcfg/disable_autoconfig" "boolean" "true"
	else
		add "$1" "netcfg/use_dhcp" "boolean" "true"
	fi
	if [ "$NONINTERACTIVE" = "yes" -o "$HOSTNAME" != "$DEFAULT_HOSTNAME" ]; then
		if verify_hostname "$HOSTNAME"; then
			add "$1" "netcfg/get_hostname" "string" "$HOSTNAME"
		fi
	fi
	add "$1" "netcfg/get_domain" "string" "$DOMAIN"
}


# Misc

# Unset a variable if it has a particular value
# $1 = variable
# $2 = value
unset_matching_var() {
	if [ "$(eval echo $`echo $1`)" = "$2" ]; then
		unset $1
	fi
}


# Check the hostname for RFC 1123 compliance.
verify_hostname() {
	t=$(echo "$1" | tr -d 'a-zA-Z0-9.-')
	if [ -n "$t" ]; then
		return 1
	fi
	if echo "$1" | grep -q "^-"; then
		return 1
	fi
	if echo "$1" | grep -q -- "-$"; then
		return 1
	fi
	l=$(($(echo "$1" | wc -c) - 1))
	if [ $l -lt 2 -o $l -gt 63 ]; then
		return 1
	fi
	return 0
}

# Convert an IP address (like 127.0.0.1) to bits.
make_bit_address () {
	addr=$1

	first=$(( $(echo $addr | cut -d. -f1) << 24))
	second=$(( $(echo $addr | cut -d. -f2) << 16))
	third=$(( $(echo $addr | cut -d. -f3) << 8))
	fourth=$(echo $addr | cut -d. -f4)
	echo $(( $first + $second + $third + $fourth ))
}

# Check if two IP addresses are on the same network.
address_is_in () {
	addr=$1
	addr2=$2
	netmask=$3

	bitaddr=$(make_bit_address $addr)
	bitaddr2=$(make_bit_address $addr2)
	bitmask=$(make_bit_address $netmask)

	[ "$(( $bitaddr & $bitmask ))" = "$(( $bitaddr2 & $bitmask))" ]
}

# Sanity checks for static IP configuration
sanity_check_static_config() {
	# netcfg will prompt for an IP address and nameserver if they are
	# not set, so use DHCP in that case.
	if [ "$NONINTERACTIVE" = "yes" ] && [ -z "$IPADDRESS" -o -z "$NAMESERVERS" ]; then
		NET_CONFIG=dhcp
	fi
	# Replicate the "gateway is unreachable" check from netcfg.
	if [ -n "$IPADDRESS" -a -n "$GATEWAY" ]; then
		if [ -n "$NETMASK" ]; then
			LOCAL_NETMASK="$NETMASK"
		else
			# Use same default as netcfg.
			LOCAL_NETMASK=255.255.255.0
		fi
		if ! address_is_in "$IPADDRESS" "$GATEWAY" "$LOCAL_NETMASK"; then
			NET_CONFIG=dhcp
		fi
	fi
}