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