README: document the need for autoreconf
[dahdi/tools.git] / dahdi_span_types
1 #! /bin/sh
2 #
3 # /usr/sbin/dahdi_span_types
4 #
5 # This script can be used both from udev and
6 # from the command line to manage PRI spans
7 # type (E1/T1/J1).
8 #
9 # Span types can be set only *BEFORE* span are assigned.
10 #
11 # It uses a configuration file: $DAHDICONFDIR/span-types.conf
12 # (default DAHDICONFDIR=/etc/dahdi)
13 # (the format is documented inside that file)
14 #
15 # The first argument is an action:
16 #   "set"        - actually write the setting to the driver
17 #   "list"       - human-readable list of E1/T1/J1 types
18 #   "dumpconfig" - dump current assignments in a /etc/dahdi/span-types.conf
19 #                  compatible format
20 #
21 # Without further arguments, it operates on all existing spans
22 # With one or more sysfs dahdi_devices it is limited to those.
23 #
24 # We may use alternative "keys" for device matching:
25 # * Available keys:
26 #   - "hwid"       - Hardware id attribute from sysfs
27 #   - "@location"  - Location attribute from sysfs (embeded inside '<>')
28 #   - "/devpath"   - The sysfs absolute devpath
29 #
30 # * Wildcard are allowed in the configuration file:
31 #   - In the device specifiers (keys)
32 #   - In the span numbers
33 #   - Example for "match-all":    *   *:T1
34 #
35 # * During "set":
36 #   - If there are multiple matches, for a span, all are applied
37 #   - They are always applied in their order in the configuration file
38 #   - This means the last match wins
39 #   - Example:
40 #         *                   *:T1        # All span on all devices are T1
41 #         usb:X1234567        [34]:E1      # Except spans 3,4 on specific device
42 #
43 # * During "dumpconfig", for each device we take the first available key:
44 #   - The preference is: "hwid" or else "@location" or else "/devpath"
45 #   - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable
46 #     or the '{-k|--key} key' command line option.
47 #
48 # Command line options:
49 #  - The '-h|--help' show a usage message.
50 #  - The '-v|--verbose' show debugging messages (on stderr)
51 #  - The '-n|--dry-run' During "set", only show what would be done
52 #  - The '-k <key>|--key <key>' overrides the SPAN_ASSIGNMENTS_KEY environment
53 #    variable.
54 #
55 # Examples:
56 #    dahdi_span_types list
57 #    dahdi_span_types set            # all devices
58 #    dahdi_span_types set /sys/bus/dahdi_devices/devices/astribanks:xbus-00
59 #    dahdi_span_types -k location dumpconfig
60 #
61
62
63 devbase='/sys/bus/dahdi_devices/devices'
64 DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}"
65 DAHDISPANTYPESCONF="${DAHDISPANTYPESCONF:-"${DAHDICONFDIR}/span-types.conf"}"
66 SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid}
67
68 usage() {
69         echo >&2 "Usage: $0 [options] action [devpath ...]"
70         echo >&2 "       action:"
71         echo >&2 "         set        - set spans to E1/T1 according to /etc/dahdi/span-types.conf"
72         echo >&2 "         list       - human-readable list of all spans"
73         echo >&2 "         dumpconfig - dump current state in /etc/dahdi/span-types.conf format"
74         echo >&2 ""
75         echo >&2 "       options:"
76         echo >&2 "         -h|--help      - Show this help"
77         echo >&2 "         -v|--verbose'  - Show debugging messages (on stderr)"
78         echo >&2 "         -n|--dry-run'  - During 'set', only show what would be done"
79         echo >&2 "         -k|--key <k>   - Override prefered key during dumpconfig action"
80         echo >&2 "         --line-mode <m> - Set default line mode to <m> (E1/T1/J1)"
81         exit 1
82 }
83
84 # Parse command line options
85 TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key:,line-mode: -n "$0" -- "$@"`
86 if [ $? != 0 ]; then
87         echo >&2 "Bad options"
88         usage
89 fi
90
91 # Note the quotes around `$TEMP': they are essential!
92 eval set -- "$TEMP"
93
94 while true ; do
95         case "$1" in
96         -h|--help)
97                 usage
98                 ;;
99         -n|--dry-run)
100                 shift
101                 dry_run=true
102                 ;;
103         -v|--verbose)
104                 shift
105                 verbose=true
106                 ;;
107         -k|--key)
108                 SPAN_ASSIGNMENTS_KEY="$2"
109                 shift
110                 shift
111                 ;;
112         --line-mode)
113                 DEFAULT_LINE_MODE="$2"
114                 shift
115                 shift
116                 ;;
117         --)
118                 shift
119                 break
120                 ;;
121         *)
122                 echo "Internal error!"
123                 exit 1
124                 ;;
125         esac
126 done
127
128 if [ "$#" -eq 0 ]; then
129         echo >&2 "Missing action argument"
130         usage
131 fi
132 action="$1"
133 shift
134
135 # Validate SPAN_ASSIGNMENTS_KEY
136 case "$SPAN_ASSIGNMENTS_KEY" in
137 hwid|location|devpath)
138         ;;
139 *)
140         echo >&2 "Bad --key='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)"
141         usage
142         ;;
143 esac
144
145 # Validate DEFAULT_LINE_MODE
146 case "$DEFAULT_LINE_MODE" in
147 E1|T1|J1|'')
148         ;;
149 *)
150         echo >&2 "Bad --line-mode='$DEFAULT_LINE_MODE' (should be: E1|T1|J1)"
151         usage
152         ;;
153 esac
154
155 if [ ! -d "$devbase" ]; then
156         echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)"
157         exit 1
158 fi
159
160 # Use given devices or otherwise, all existing devices
161 if [ "$#" -gt 0 ]; then
162         DEVICES="$@"
163 else
164         DEVICES=`ls -d $devbase/* 2>/dev/null`
165 fi
166
167 # Beware of special characters in attributes
168 attr_clean() {
169         cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_'
170 }
171
172 show_spantypes() {
173         echo "# PRI span types (E1/T1/J1)"
174         for device in $DEVICES
175         do
176                 devpath=`cd "$device" && pwd -P`
177                 location='@'`attr_clean "$device/location"`
178                 hardware_id=`attr_clean "$device/hardware_id"`
179                 cat "$device/spantype" | while read st; do
180                         case "$st" in
181                         *:[ETJ]1)
182                                 printf "%-10s %-20s %-30s %s\n" \
183                                         "$st" "[$hardware_id]" "$location" \
184                                         "$devpath"
185                                 ;;
186                         esac
187                 done
188         done
189 }
190
191 list_pri_spantypes() {
192         find $DEVICES -follow -maxdepth 1 -name spantype | \
193                 xargs cat | \
194                 sed -n '/:[ETJ]1$/s/^.*://p' | \
195                 sort -u | \
196                 tr '\n' ' ' | \
197                 sed -e 's/^ *//' -e 's/ *$//'
198 }
199
200 dump_config() {
201         pri_spantypes=`list_pri_spantypes`
202         num_spantypes=`echo "$pri_spantypes" | wc -w`
203         gen_default=''
204         echo '#'
205         echo "# Autogenerated by $0 on `date`"
206         echo "# Map PRI DAHDI devices to span types for E1/T1/J1"
207         echo "#"
208
209         echo "# Summary:"
210         if [ "$DEFAULT_LINE_MODE" != '' ]; then
211                 gen_default="$DEFAULT_LINE_MODE"
212                 echo "#  * Generating wildcard match of $gen_default."
213                 echo "#    - Was run with '--line-mode=$DEFAULT_LINE_MODE'"
214         elif [ "$num_spantypes" -eq 1 ]; then
215                 gen_default="$pri_spantypes"
216                 echo "#  * Generating wildcard match of $gen_default."
217                 echo "#    - Spans were $pri_spantypes"
218         else
219                 echo "#  * Not generating wildcard match."
220                 echo "#    - Was run without '--line-mode' option and span were of mixed types [$pri_spantypes]"
221         fi
222         echo "#"
223         if [ "$num_spantypes" -eq 1 ]; then
224                 echo "#  * Generating a list of commented out configurations for spans."
225                 echo "#    - Spans were $pri_spantypes"
226                 echo "#    - Uncomment for specific overrides"
227         else
228                 echo "#  * Generating a list of specific span configurations."
229                 echo "#    - Spans were of mixed types: $pri_spantypes"
230         fi
231         echo "#"
232         echo ''
233
234         fmt="%-65s %s"
235         printf "$fmt\n" '# @location/hardware_id' 'span_type'
236
237         if [ "$gen_default" != '' ]; then
238                 printf "$fmt\t\t# Wildcard line-mode" "*" "*:$gen_default"
239                 echo ""
240         fi
241         echo ""
242         for device in $DEVICES
243         do
244                 devpath=`cd "$device" && pwd -P`
245                 location=`attr_clean "$device/location"`
246                 hardware_id=`attr_clean "$device/hardware_id"`
247                 if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then
248                         id="$hardware_id"
249                 elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then
250                         id="@$location"
251                 else
252                         id="$devpath"
253                 fi
254                 echo "# Device: [$hardware_id] @$location $devpath"
255                 cat "$device/spantype" | while read st; do
256                         case "$st" in
257                         *:[ETJ]1)
258                                 if [ "$num_spantypes" -eq 1 ]; then
259                                         printf "#$fmt\n" "$id" "$st"
260                                 else
261                                         printf "$fmt\n" "$id" "$st"
262                                 fi
263                                 ;;
264                         *)
265                                 #echo "#    Skipped local span `echo $st | sed 's/:/ -- /'`"
266                                 ;;
267                         esac
268                 done | sort -n
269                 echo ''
270         done
271 }
272
273 # Allow comments and empty lines in config file
274 filter_conf() {
275         sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISPANTYPESCONF"
276 }
277
278 handle_span() {
279         device="$1"
280         spantype="$2"
281         attr_file="$device/spantype"
282         devpath=`cd "$device" && pwd -P`
283         devname=`echo "$device" | sed "s,$devbase/,,"`
284         location='@'`attr_clean "$device/location"`
285         hardware_id=`attr_clean "$device/hardware_id"`
286         spanno=`echo "$spantype" | cut -d: -f1`
287         #echo >&2 "DEBUG: $device $spanno ($spantype)"
288         filter_conf | while read id span_spec; do
289                         sn=`echo "$span_spec" | cut -d: -f1`
290                         val=`echo "$span_spec" | cut -d: -f2`
291                         case "$spanno" in
292                         $sn)
293                                 ;;
294                         *)
295                                 #echo >&2 "no-match($device $spanno): $sn"
296                                 continue
297                                 ;;
298                         esac
299                         found=no
300                         # GLOBBING
301                         case "$location" in
302                         $id)
303                                 #echo >&2 "match($id): $span_spec"
304                                 found=yes
305                                 ;;
306                         esac
307                         case "$hardware_id" in
308                         $id)
309                                 #echo >&2 "match([$id]): $span_spec"
310                                 found=yes
311                                 ;;
312                         esac
313                         case "$devpath" in
314                         $id)
315                                 #echo >&2 "match([$id]): $span_spec"
316                                 found=yes
317                                 ;;
318                         esac
319                         if [ "$found" = 'yes' ]; then
320                                 if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then
321                                         echo >&2 "Set $devname span $spanno = $val"
322                                 fi
323                                 if [ "$dry_run" != 'true' ]; then
324                                         echo "$spanno:$val" > "$attr_file"
325                                 fi
326                         fi
327                 done
328 }
329
330 set_all_devices() {
331         if [ ! -f "$DAHDISPANTYPESCONF" ]; then
332                 echo >&2 "$0: Missing configuration '$DAHDISPANTYPESCONF'"
333                 exit 1
334         fi
335         for device in $DEVICES
336         do
337                 devname=`echo "$device" | sed "s,$devbase/,,"`
338                 cat "$device/spantype" | while read spantype; do
339                         case "$spantype" in
340                         *:[ETJ]1)
341                                 handle_span "$device" "$spantype"
342                                 ;;
343                         *)
344                                 if [ "$dry_run" = 'true' -o "$verbose" = 'true' ]; then
345                                         echo >&2 "Skipping non-E1/T1/J1 span ($devname -- $spantype)"
346                                 fi
347                                 ;;
348                         esac
349                 done
350         done
351 }
352
353 case "$action" in
354 list)
355         show_spantypes
356         ;;
357 dumpconfig)
358         dump_config
359         ;;
360 set)
361         set_all_devices
362         ;;
363 *)
364         usage
365         ;;
366 esac