chiark / gitweb /
[PATCH] The following patch fixes a warning when compiling chassis_id
[elogind.git] / extras / cdsymlinks.sh
1 #! /bin/sh -e
2 #
3 # Map cdrom, cdm, cdmrw, cd-r, cdrw, dvd, dvdrw, dvdram to suitable devices.
4 # Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices.
5 # First parameter is the kernel device name.
6 # Second parameter, if present, must be "-d" => output the full mapping.
7 #
8 # Usage:
9 # BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}"
10 # BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}"
11 # BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}"
12 # (this last one is "just in case")
13 #
14 # (c) 2004 Darren Salt <linux@youmustbejoking.demon.co.uk>
15
16 test -e /proc/sys/dev/cdrom/info || exit 0
17
18 # Defaults; it's better that you alter them in /etc/udev/cdsymlinks.conf
19 OUTPUT='CD CDRW DVD DVDRW DVDRAM'
20 NUMBERED_LINKS=1
21
22 test -e /etc/udev/cdsymlinks.conf && . /etc/udev/cdsymlinks.conf
23
24 DEBUG=''
25 test "$2" = '-d' && DEBUG=1
26
27
28 # Array emulation. 'setArray FOO a b c' gives FOO=3 FOO_1=a FOO_2=b FOO_3=c
29 setArray () {
30   local _ARRAY=$1
31   local _INDEX=0
32   shift
33   while test $# -ne 0; do
34     eval ${_ARRAY}_$_INDEX="$1"
35     _INDEX=$(($_INDEX+1))
36     shift
37   done
38   eval $_ARRAY=$_INDEX
39 }
40
41 ix () { eval echo -n \$$1_$2; }
42 ixs () { eval $1_$2="$3"; }
43
44 # Args: variable, value
45 # Returns true if value is not in variable (a whitespace-separated list)
46 notin () {
47   test "$2" = '' && return 0
48   local i
49   for i in `eval echo '$'$1`; do
50     test "$i" != "$2" || return 1
51   done
52 }
53
54
55 # Scan /proc/sys/dev/cdrom/info for details on the present devices
56 setArray DEVICES `sed -re '/^drive name:/I!        d; s/.*://' /proc/sys/dev/cdrom/info`
57 setArray DVDRAMs `sed -re '/^Can write DVD-RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info`
58 setArray DVDRWs  `sed -re '/^Can write DVD-R:/I!   d; s/.*://' /proc/sys/dev/cdrom/info`
59 setArray DVDs    `sed -re '/^Can read DVD:/I!      d; s/.*://' /proc/sys/dev/cdrom/info`
60 setArray CDRWs   `sed -re '/^Can write CD-RW:/I!   d; s/.*://' /proc/sys/dev/cdrom/info`
61 setArray CDRs    `sed -re '/^Can write CD-R:/I!    d; s/.*://' /proc/sys/dev/cdrom/info`
62 setArray CDMRWs  `sed -re '/^Can write MRW:/I!     d; s/.*://' /proc/sys/dev/cdrom/info`
63 setArray CDMs    `sed -re '/^Can read MRW:/I!      d; s/.*://' /proc/sys/dev/cdrom/info`
64
65 # How many devices do we have?
66 NumDevs=$(($DEVICES-1))
67 Count=''
68 i=-1
69 while test $i -ne $NumDevs; do
70   i=$(($i+1));
71   Count="$i${Count:+ }$Count";
72 done
73
74 # Fill in any missing capabilities information (assume not capable)
75 for i in $Count; do
76   test "`ix DVDRAMs $i`" != '' || ixs DVDRAMs $i 0
77   test "`ix DVDRWs $i`"  != '' || ixs DVDRWs $i 0
78   test "`ix DVDs $i`"    != '' || ixs DVDs $i 0
79   test "`ix CDRWs $i`"   != '' || ixs CDRWs $i 0
80   test "`ix CDRs $i`"    != '' || ixs CDRs $i 0
81   test "`ix CDMRWs $i`"  != '' || ixs CDMRWs $i 0
82   test "`ix CDMs $i`"    != '' || ixs CDMs $i 0
83 done
84
85 DVDRAM=''
86 DVDRW=''
87 DVD=''
88 CDRW=''
89 CDR=''
90 CDMRW=''
91 CDM=''
92 CD=''
93
94 # Calculate symlink->device mappings.
95 # We need to be careful about how we assign mappings because we want
96 # read-only devices to have /dev/cdrom and /dev/dvd.
97 # Hot-plugged CD/DVD devices may well cause this scheme some problems.
98 for i in $Count; do
99   test "`ix DVDRAMs $i`" = 1 && DVDRAM="$DVDRAM `ix DEVICES $i`"
100 done
101 for i in $Count; do
102   test "`ix DVDRWs $i`" = 1 &&  DVDRW="$DVDRW `ix DEVICES $i`"
103 done
104 for i in $Count; do
105   test "`ix DVDs $i`" = 1 &&    DVD="$DVD `ix DEVICES $i`"
106 done
107 for i in $Count; do
108   test "`ix CDRWs $i`" = 1 &&   CDRW="$CDRW `ix DEVICES $i`"
109 done
110 for i in $Count; do
111   test "`ix CDRs $i`" = 1 &&    CDR="$CDR `ix DEVICES $i`"
112 done
113 for i in $Count; do
114   test "`ix CDMRWs $i`" = 1 &&  CDMRW="$CDMRW `ix DEVICES $i`"
115 done
116 for i in $Count; do
117   test "`ix CDMs $i`" = 1 &&    CDM="$CDM `ix DEVICES $i`"
118 done
119 for i in $Count; do
120                                 CD="$CD `ix DEVICES $i`"
121 done
122
123 # Debug output
124 if test "$DEBUG" = 1; then
125   echo 'Devices:' `for i in $Count; do ix DEVICES $i; echo -n \ ; done`
126   echo 'DVDRAM :' `for i in $Count; do ix DVDRAMs $i; echo -n \ ; done` $DVDRAM
127   echo 'DVDRW  :' `for i in $Count; do ix DVDRWs  $i; echo -n \ ; done` $DVDRW
128   echo 'DVD    :' `for i in $Count; do ix DVDs    $i; echo -n \ ; done` $DVD
129   echo 'CDRW   :' `for i in $Count; do ix CDRWs   $i; echo -n \ ; done` $CDRW
130   echo 'CD-R   :' `for i in $Count; do ix CDRs    $i; echo -n \ ; done` $CDR
131   echo 'CDMRW  :' `for i in $Count; do ix CDMRWs  $i; echo -n \ ; done` $CDMRW
132   echo 'CDM    :' `for i in $Count; do ix CDMs    $i; echo -n \ ; done` $CDM
133   echo 'CDROM  : (all)' $CD
134 fi
135
136 # Prepare symlink names output
137 output () {
138   test "`eval echo '$'$3`" = '' && return
139   local i
140   local COUNT=''
141   local DEVLS="`ls -dl \"/dev/$2\" \"/dev/$2\"[0-9]* 2>/dev/null`"
142   local PRESENT="`echo "$DEVLS" |
143     sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> [^[:space:]]+$!\1!'`"
144   for i in `eval echo '$'$3`; do
145     # First, we look for existing symlinks to the target device.
146     local DEVPRESENT="`echo "$DEVLS" |
147       sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> '$i'$!\1!; t X; d; :X'`"
148     if test "$DEVPRESENT" != ""; then
149       # Existing symlinks found - don't output a new one.
150       # If the target dev ($1) is the current dev ($i), we output their names.
151       test "$1" = "$i" && echo " $DEVPRESENT" | sed -e 'N; $ s/\n/ /'
152     else
153       # If we found no existing symlinks for the target device...
154       # Find the next available (not present) symlink name.
155       # We always need to do this for reasons of output consistency: if a
156       # symlink is created by udev as a result of use of this program, we
157       # DON'T want different output!
158       until notin PRESENT "$2$COUNT"; do
159         COUNT=$(($COUNT+1))
160       done
161       # If the target dev ($1) is the current dev ($i), we output its name.
162       if test $(($NUMBERED_LINKS)) -ne 0 || test "$COUNT" = ''; then
163         test "$i" = "$1" && echo -n " $2$COUNT"
164       fi
165       # If the link isn't in our "existing links" list, add it and increment
166       # our counter.
167       if test ! -e "/dev/$2$COUNT"; then
168         PRESENT="$PRESENT\n$2$COUNT"
169         COUNT=$(($COUNT+1))
170       fi
171     fi
172   done
173 }
174
175 # And output it
176 notin OUTPUT CD     || echo -n "`output "$1" cdrom CD`"
177 notin OUTPUT CDMRW  || echo -n "`output "$1" cdmrw CDM`"
178 notin OUTPUT CDWMRW || echo -n "`output "$1" cdwmrw CDMRW`"
179 notin OUTPUT CDR    || echo -n "`output "$1" cd-r CDR`"
180 notin OUTPUT CDRW   || echo -n "`output "$1" cdrw CDRW`"
181 notin OUTPUT DVD    || echo -n "`output "$1" dvd DVD`"
182 notin OUTPUT DVDRW  || echo -n "`output "$1" dvdrw DVDRW`"
183 notin OUTPUT DVDRAM || echo -n "`output "$1" dvdram DVDRAM`"
184 echo