packages/olsrd: use new service functions
[openwrt/svn-archive/archive.git] / net / olsrd / files / olsrd.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008-2011 OpenWrt.org
3 # Copyright (C) 2008 Alina Friedrichsen <x-alina@gmx.net>
4 # Special thanks to bittorf wireless ))
5
6 START=65
7
8 SERVICE_DAEMONIZE=1
9 SERVICE_WRITE_PID=1
10
11 OLSRD_OLSRD_SCHEMA='ignore:internal config_file:internal DebugLevel=0 AllowNoInt=yes'
12 OLSRD_IPCCONNECT_SCHEMA='ignore:internal Host:list Net:list2'
13 OLSRD_LOADPLUGIN_SCHEMA='ignore:internal library:internal Host4:list Net4:list2 Host:list Net:list2 Host6:list Net6:list2 Ping:list redistribute:list NonOlsrIf:list name:list lat lon latlon_infile HNA:list2 hosts:list2'
14 OLSRD_INTERFACE_SCHEMA='ignore:internal interface:internal AutoDetectChanges:bool'
15 OLSRD_INTERFACE_DEFAULTS_SCHEMA='AutoDetectChanges:bool'
16
17 T=' '
18 N='
19 '
20
21 validate_varname() {
22 local varname="$1"
23 [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
24 return 0
25 }
26
27 validate_ifname() {
28 local ifname="$1"
29 [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
30 return 0
31 }
32
33 validate_olsrd_option() {
34 local str="$1"
35 [ -z "$str" -o "$str" != "${str%%[! 0-9A-Za-z./|:_-]*}" ] && return 1
36 return 0
37 }
38
39 get_ifname() {
40 IFNAME=
41 local interface="$1"
42 validate_varname "$interface" || return 1
43 local ifname
44
45 config_get ifname "$interface" ifname
46 validate_ifname "$ifname" || return 1
47 IFNAME="$ifname"
48
49 return 0
50 }
51
52 system_config() {
53 local cfg="$1"
54 local cfgt
55 local hostname
56 local latlon
57
58 config_get cfgt "$cfg" TYPE
59
60 if [ "$cfgt" = "system" ]; then
61 config_get hostname "$cfg" hostname
62 hostname="${hostname:-OpenWrt}"
63 SYSTEM_HOSTNAME="$hostname"
64 fi
65
66 if [ -z "$SYSTEM_LAT" -o -z "$SYSTEM_LON" ]; then
67 config_get latlon "$cfg" latlon
68 IFS=" ${T}${N},"
69 set -- $latlon
70 unset IFS
71 SYSTEM_LAT="$1"
72 SYSTEM_LON="$2"
73 fi
74
75 if [ -z "$SYSTEM_LAT" -o -z "$SYSTEM_LON" ]; then
76 config_get latlon "$cfg" latitude
77 SYSTEM_LAT="$latlon"
78 config_get latlon "$cfg" longitude
79 SYSTEM_LON="$latlon"
80 fi
81 }
82
83 olsrd_find_config_file() {
84 local cfg="$1"
85 validate_varname "$cfg" || return 0
86
87 config_get_bool ignore "$cfg" ignore 0
88 [ "$ignore" -ne 0 ] && return 0
89 config_get OLSRD_CONFIG_FILE "$cfg" config_file
90
91 return 0
92 }
93
94 warning_invalid_value() {
95 local package="$1"
96 validate_varname "$package" || package=
97 local config="$2"
98 validate_varname "$config" || config=
99 local option="$3"
100 validate_varname "$option" || option=
101
102 echo -n "Warning: Invalid value" 1>&2
103
104 if [ -n "$package" -a -n "$config" ]; then
105 echo -n " in option '$package.$config${option:+.}$option'" 1>&2
106 fi
107
108 echo ", skipped" 1>&2
109
110 return 0
111 }
112
113 olsrd_write_option() {
114 local param="$1"
115 local cfg="$2"
116 validate_varname "$cfg" || return 1
117 local option="$3"
118 validate_varname "$option" || return 1
119 local value="$4"
120 local option_type="$5"
121
122 if [ "$option_type" = bool ]; then
123 case "$value" in
124 1|on|true|enabled|yes) value=yes;;
125 0|off|false|disabled|no) value=no;;
126 *) warning_invalid_value olsrd "$cfg" "$option"; return 1;;
127 esac
128 fi
129
130 if ! validate_olsrd_option "$value"; then
131 warning_invalid_value olsrd "$cfg" "$option"
132 return 1
133 fi
134
135 if [ "$value" != "${value%%[G-Zg-z_-]*}" ]; then
136 if [ "$option" != "Ip6AddrType" -a "$option" != "LinkQualityMult" -a "$value" != "yes" -a "$value" != "no" ]; then
137 value="\"$value\""
138 fi
139 fi
140
141 echo -n "${N}$param$option $value"
142
143 return 0
144 }
145
146 olsrd_write_plparam() {
147 local param="$1"
148 local cfg="$2"
149 validate_varname "$cfg" || return 1
150 local option="$3"
151 validate_varname "$option" || return 1
152 local value="$4"
153 local option_type="$5"
154 local _option
155
156 if [ "$option_type" = bool ]; then
157 case "$value" in
158 1|on|true|enabled|yes) value=yes;;
159 0|off|false|disabled|no) value=no;;
160 *) warning_invalid_value olsrd "$cfg" "$option"; return 1;;
161 esac
162 fi
163
164 if ! validate_olsrd_option "$value"; then
165 warning_invalid_value olsrd "$cfg" "$option"
166 return 1
167 fi
168
169 IFS='-_'
170 set -- $option
171 option="$*"
172 unset IFS
173 _option="$option"
174 if [ "$option" = 'hosts' ]; then
175 set -- $value
176 option="$1"
177 shift
178 value="$*"
179 fi
180 if [ "$option" = 'NonOlsrIf' ]; then
181 if validate_varname "$value"; then
182 if get_ifname "$value"; then
183 ifname="$IFNAME"
184 echo "Info: mdns Interface '$value' ifname '$ifname' found" 1>&2
185 else
186 echo "Warning: mdns Interface '$value' not found, skipped" 1>&2
187 fi
188 else
189 warning_invalid_value olsrd "$cfg" "NonOlsrIf"
190 fi
191 [ -z "$ifname" ] || value=$ifname
192 fi
193
194 echo -n "${N}${param}PlParam \"$option\" \"$value\""
195
196 return 0
197 }
198
199 config_update_schema() {
200 unset IFS
201 local schema_varname="$1"
202 validate_varname "$schema_varname" || return 1
203 local command="$2"
204 validate_varname "$command" || return 1
205 local option="$3"
206 validate_varname "$option" || return 1
207 local value="$4"
208 local schema
209 local cur_option
210
211 case "$varname" in
212 *_LENGTH) return 0;;
213 *_ITEM*) return 0;;
214 esac
215
216 eval "export -n -- \"schema=\${$schema_varname}\""
217
218 for cur_option in $schema; do
219 [ "${cur_option%%[:=]*}" = "$option" ] && return 0
220 done
221
222 if [ "$command" = list ]; then
223 set -- $value
224 if [ "$#" -ge "3" ]; then
225 schema_entry="$option:list3"
226 elif [ "$#" -ge "2" ]; then
227 schema_entry="$option:list2"
228 else
229 schema_entry="$option:list"
230 fi
231 else
232 schema_entry="$option"
233 fi
234
235 append "$schema_varname" "$schema_entry"
236
237 return 0
238 }
239
240 config_write_options() {
241 unset IFS
242 local schema="$1"
243 local cfg="$2"
244 validate_varname "$cfg" || return 1
245 local write_func="$3"
246 [ -z "$write_func" ] && output_func=echo
247 local write_param="$4"
248 local schema_entry
249 local option
250 local option_length
251 local option_type
252 local default
253 local value
254 local list_size
255 local list_item
256 local list_value
257 local i
258 local position
259
260 for schema_entry in $schema; do
261 default="${schema_entry#*[=]}"
262 [ "$default" = "$schema_entry" ] && default=
263 option="${schema_entry%%[=]*}"
264 IFS=':'
265 set -- $option
266 unset IFS
267 option="$1"
268 option_type="$2"
269 validate_varname "$option" || continue
270 [ -z "$option_type" ] || validate_varname "$option_type" || continue
271 [ "$option_type" = internal ] && continue
272 config_get value "$cfg" "$option"
273
274 if [ -z "$value" ]; then
275 IFS='+'
276 set -- $default
277 unset IFS
278 value=$*
279 elif [ "$value" = '-' -a -n "$default" ]; then
280 continue
281 fi
282
283 [ -z "$value" ] && continue
284
285 case "$option_type" in
286 list) list_size=1;;
287 list2) list_size=2;;
288 list3) list_size=3;;
289 *) list_size=0;;
290 esac
291
292 if [ "$list_size" -gt 0 ]; then
293 config_get option_length "$cfg" "${option}_LENGTH"
294 if [ -n "$option_length" ]; then
295 i=1
296 while [ "$i" -le "$option_length" ]; do
297 config_get list_value "$cfg" "${option}_ITEM$i"
298 "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break
299 i=$((i + 1))
300 done
301 else
302 list_value=
303 i=0
304 for list_item in $value; do
305 append "list_value" "$list_item"
306 i=$((i + 1))
307 position=$((i % list_size))
308 if [ "$position" -eq 0 ]; then
309 "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type" || break
310 list_value=
311 fi
312 done
313 [ "$position" -ne 0 ] && "$write_func" "$write_param" "$cfg" "$option" "$list_value" "$option_type"
314 fi
315 else
316 "$write_func" "$write_param" "$cfg" "$option" "$value" "$option_type"
317 fi
318 done
319
320 return 0
321 }
322
323 olsrd_write_olsrd() {
324 local cfg="$1"
325 validate_varname "$cfg" || return 0
326 local ignore
327 local ipversion
328
329 config_get_bool ignore "$cfg" ignore 0
330 [ "$ignore" -ne 0 ] && return 0
331
332 [ "$OLSRD_COUNT" -gt 0 ] && return 0
333
334 config_get ipversion "$cfg" IpVersion
335 if [ "$ipversion" = "6and4" ]; then
336 OLSRD_IPVERSION_6AND4=1
337 config_set "$cfg" IpVersion '6'
338 fi
339
340 config_write_options "$OLSRD_OLSRD_SCHEMA" "$cfg" olsrd_write_option
341 echo
342 OLSRD_COUNT=$((OLSRD_COUNT + 1))
343
344 return 0
345 }
346
347 olsrd_write_ipcconnect() {
348 local cfg="$1"
349 validate_varname "$cfg" || return 0
350 local ignore
351
352 config_get_bool ignore "$cfg" ignore 0
353 [ "$ignore" -ne 0 ] && return 0
354
355 [ "$IPCCONNECT_COUNT" -gt 0 ] && return 0
356
357 echo -n "${N}IpcConnect${N}{"
358 config_write_options "$OLSRD_IPCCONNECT_SCHEMA" "$cfg" olsrd_write_option "${T}"
359 echo "${N}}"
360 IPCCONNECT_COUNT=$((IPCCONNECT_COUNT + 1))
361
362 return 0
363 }
364
365 olsrd_write_hna4() {
366 local cfg="$1"
367 validate_varname "$cfg" || return 0
368 local ignore
369
370 config_get_bool ignore "$cfg" ignore 0
371 [ "$ignore" -ne 0 ] && return 0
372
373 config_get netaddr "$cfg" netaddr
374 if ! validate_olsrd_option "$netaddr"; then
375 warning_invalid_value olsrd "$cfg" "netaddr"
376 return 0
377 fi
378
379 config_get netmask "$cfg" netmask
380 if ! validate_olsrd_option "$netmask"; then
381 warning_invalid_value olsrd "$cfg" "netmask"
382 return 0
383 fi
384
385 [ "$HNA4_COUNT" -le 0 ] && echo -n "${N}Hna4${N}{"
386 echo -n "${N}${T}${T}$netaddr $netmask"
387 HNA4_COUNT=$((HNA4_COUNT + 1))
388
389 return 0
390 }
391
392 olsrd_write_hna6() {
393 local cfg="$1"
394 validate_varname "$cfg" || return 0
395 local ignore
396
397 config_get_bool ignore "$cfg" ignore 0
398 [ "$ignore" -ne 0 ] && return 0
399
400 config_get netaddr "$cfg" netaddr
401 if ! validate_olsrd_option "$netaddr"; then
402 warning_invalid_value olsrd "$cfg" "netaddr"
403 return 0
404 fi
405
406 config_get prefix "$cfg" prefix
407 if ! validate_olsrd_option "$prefix"; then
408 warning_invalid_value olsrd "$cfg" "prefix"
409 return 0
410 fi
411
412 [ "$HNA6_COUNT" -le 0 ] && echo -n "${N}Hna6${N}{"
413 echo -n "${N}${T}${T}$netaddr $prefix"
414 HNA6_COUNT=$((HNA6_COUNT + 1))
415
416 return 0
417 }
418
419 olsrd_write_loadplugin() {
420 local cfg="$1"
421 validate_varname "$cfg" || return 0
422 local ignore
423 local name
424 local suffix
425 local lat
426 local lon
427 local latlon_infile
428
429 config_get_bool ignore "$cfg" ignore 0
430 [ "$ignore" -ne 0 ] && return 0
431
432 config_get library "$cfg" library
433 if ! validate_olsrd_option "$library"; then
434 warning_invalid_value olsrd "$cfg" "library"
435 return 0
436 fi
437 if ! [ -x "/lib/$library" -o -x "/usr/lib/$library" -o -x "/usr/local/lib/$library" ]; then
438 echo "Warning: Plugin library '$library' not found, skipped" 1>&2
439 return 0
440 fi
441
442 case "$library" in
443 olsrd_nameservice.*)
444 config_get name "$cfg" name
445 [ -z "$name" ] && config_set "$cfg" name $SYSTEM_HOSTNAME
446
447 config_get suffix "$cfg" suffix
448 [ -z "$suffix" ] && config_set "$cfg" suffix '.olsr'
449
450 config_get lat "$cfg" lat
451 config_get lon "$cfg" lon
452 config_get latlon_infile "$cfg" latlon_infile
453 if [ \( -z "$lat" -o -z "$lat" \) -a -z "$latlon_infile" ]; then
454 if [ -f '/var/run/latlon.txt' ]; then
455 config_set "$cfg" lat ''
456 config_set "$cfg" lon ''
457 config_set "$cfg" latlon_infile '/var/run/latlon.txt'
458 else
459 config_set "$cfg" lat "$SYSTEM_LAT"
460 config_set "$cfg" lon "$SYSTEM_LON"
461 fi
462 fi
463
464 config_get latlon_file "$cfg" latlon_file
465 [ -z "$latlon_file" ] && config_set "$cfg" latlon_file '/var/run/latlon.js'
466 ;;
467 esac
468
469 echo -n "${N}LoadPlugin \"$library\"${N}{"
470 config_write_options "$OLSRD_LOADPLUGIN_SCHEMA" "$cfg" olsrd_write_plparam "${T}"
471 echo "${N}}"
472
473 return 0
474 }
475
476 olsrd_write_interface() {
477 local cfg="$1"
478 validate_varname "$cfg" || return 0
479 local ignore
480 local interfaces
481 local interface
482 local ifnames
483
484 config_get_bool ignore "$cfg" ignore 0
485 [ "$ignore" -ne 0 ] && return 0
486
487 ifnames=
488 config_get interfaces "$cfg" interface
489 for interface in $interfaces; do
490 if validate_varname "$interface"; then
491 if get_ifname "$interface"; then
492 ifnames="$ifnames \"$IFNAME\""
493 else
494 echo "Warning: Interface '$interface' not found, skipped" 1>&2
495 fi
496 else
497 warning_invalid_value olsrd "$cfg" "interface"
498 fi
499 done
500
501 [ -z "$ifnames" ] && return 0
502
503 echo -n "${N}Interface$ifnames${N}{"
504 config_write_options "$OLSRD_INTERFACE_SCHEMA" "$cfg" olsrd_write_option "${T}"
505 echo "${N}}"
506 INTERFACES_COUNT=$((INTERFACES_COUNT + 1))
507
508 return 0
509 }
510
511 olsrd_write_interface_defaults() {
512 local cfg="$1"
513 validate_varname "$cfg" || return 0
514
515 echo -n "${N}InterfaceDefaults$ifnames${N}{"
516 config_write_options "$OLSRD_INTERFACE_DEFAULTS_SCHEMA" "$cfg" olsrd_write_option "${T}"
517 echo "${N}}"
518
519 return 1
520 }
521
522 olsrd_update_schema() {
523 local command="$1"
524 validate_varname "$command" || return 0
525 local varname="$2"
526 validate_varname "$varname" || return 0
527 local value="$3"
528 local cfg="$CONFIG_SECTION"
529 local cfgt
530 local cur_varname
531
532 config_get cfgt "$cfg" TYPE
533 case "$cfgt" in
534 olsrd) config_update_schema OLSRD_OLSRD_SCHEMA "$command" "$varname" "$value";;
535 IpcConnect) config_update_schema OLSRD_IPCCONNECT_SCHEMA "$command" "$varname" "$value";;
536 LoadPlugin) config_update_schema OLSRD_LOADPLUGIN_SCHEMA "$command" "$varname" "$value";;
537 Interface) config_update_schema OLSRD_INTERFACE_SCHEMA "$command" "$varname" "$value";;
538 InterfaceDefaults) config_update_schema OLSRD_INTERFACE_DEFAULTS_SCHEMA "$command" "$varname" "$value";;
539 esac
540
541 return 0
542 }
543
544 olsrd_write_config() {
545 OLSRD_IPVERSION_6AND4=0
546 OLSRD_COUNT=0
547 config_foreach olsrd_write_olsrd olsrd
548 IPCCONNECT_COUNT=0
549 config_foreach olsrd_write_ipcconnect IpcConnect
550 HNA4_COUNT=0
551 config_foreach olsrd_write_hna4 Hna4
552 [ "$HNA4_COUNT" -gt 0 ] && echo "${N}}"
553 HNA6_COUNT=0
554 config_foreach olsrd_write_hna6 Hna6
555 [ "$HNA6_COUNT" -gt 0 ] && echo "${N}}"
556 config_foreach olsrd_write_loadplugin LoadPlugin
557 INTERFACES_COUNT=0
558 config_foreach olsrd_write_interface_defaults InterfaceDefaults
559 config_foreach olsrd_write_interface Interface
560 echo
561
562 return 0
563 }
564
565 start() {
566 SYSTEM_HOSTNAME=
567 SYSTEM_LAT=
568 SYSTEM_LON=
569 config_load system
570 config_foreach system_config system
571
572 option_cb() {
573 olsrd_update_schema "option" "$@"
574 }
575
576 list_cb() {
577 olsrd_update_schema "list" "$@"
578 }
579
580 include /lib/network
581 scan_interfaces
582 config_load olsrd
583 reset_cb
584
585 OLSRD_CONFIG_FILE=
586 config_foreach olsrd_find_config_file olsrd
587
588 if [ -z "$OLSRD_CONFIG_FILE" ]; then
589 mkdir -p -- /var/etc/
590 olsrd_write_config > /var/etc/olsrd.conf
591 if [ "$INTERFACES_COUNT" -gt 0 -a "$OLSRD_COUNT" -gt 0 ]; then
592 OLSRD_CONFIG_FILE=/var/etc/olsrd.conf
593 fi
594 fi
595
596 [ -z "$OLSRD_CONFIG_FILE" ] && return 1
597
598 local bindv6only='0'
599 if [ "$OLSRD_IPVERSION_6AND4" -ne 0 ]; then
600 bindv6only="$(sysctl -n net.ipv6.bindv6only)"
601 sysctl -w net.ipv6.bindv6only=1
602 sed -e 's/^\t\t[0-9.]*[ ][0-9.]*$//' < "$OLSRD_CONFIG_FILE" > /var/etc/olsrd.conf.ipv6
603 sed -i '/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/d' /var/etc/olsrd.conf.ipv6
604 service_start /usr/sbin/olsrd -f /var/etc/olsrd.conf.ipv6 -nofork
605 sed -e 's/^IpVersion[ ][ ]*6$/IpVersion 4/' -e 's/^\t\t[A-Fa-f0-9.:]*[:][A-Fa-f0-9.:]*[ ][0-9]*$//' < "$OLSRD_CONFIG_FILE" > /var/etc/olsrd.conf.ipv4
606 service_start /usr/sbin/olsrd -f /var/etc/olsrd.conf.ipv4 -nofork
607 sleep 3
608 sysctl -w net.ipv6.bindv6only="$bindv6only"
609 else
610 service_start /usr/sbin/olsrd -f "$OLSRD_CONFIG_FILE" -nofork
611 fi
612 }
613
614 stop() {
615 service_stop /usr/sbin/olsrd
616 }