#!/bin/sh -e RULES_FILE="/etc/udev/rules.d/82-persistent-cd.rules" ############################################################################## lock_rules_file() { RULES_LOCK="/dev/.udev/.lock-${RULES_FILE##*/}" retry=30 while ! mkdir $RULES_LOCK 2> /dev/null; do if [ $retry -eq 0 ]; then echo "Cannot lock $RULES_FILE!" >&2 exit 2 fi sleep 1 retry=$(($retry - 1)) done } unlock_rules_file() { rmdir $RULES_LOCK || true } ############################################################################## find_next_available() { # use echo to convert newlines to spaces local links=`echo $(find_all_symlinks $1)` local basename=${links%%[ 0-9]*} local max=-1 for name in $links; do local num=${name#$basename} [ "$num" ] || num=0 [ $num -gt $max ] && max=$num done max=$(($max + 1)) # "name0" actually is just "name" [ $max -eq 0 ] && return echo "$max" } find_all_symlinks() { local linkre="$1" local match="$2" [ -e $RULES_FILE ] || return local search='.*[[:space:],]SYMLINK+="\('"$linkre"'\)"[[:space:]]*\(,.*\|\\\|\)$' sed -n -e "${match}s/${search}/\1/p" $RULES_FILE } write_rule() { local match="$1" local link="$2" local comment="$3" [ -e "$RULES_FILE" ] || PRINT_HEADER=1 { if [ "$PRINT_HEADER" ]; then PRINT_HEADER= echo "# This file was automatically generated by the $0" echo "# program, probably run by the 83-cdrom.rules rules file." echo "#" echo "# You can modify it, as long as you keep each rule on a single line" echo "# and set the \$GENERATED variable." echo "" fi [ "$comment" ] && echo "# $comment" echo "ACTION==\"add\", SUBSYSTEM==\"block\", $match, ENV{ID_CDROM}==\"1\", SYMLINK+=\"$link\", ENV{GENERATED}=\"1\"" } >> $RULES_FILE SYMLINKS="$SYMLINKS $link" } ############################################################################## if [ -z "$DEVPATH" ]; then echo "Missing \$DEVPATH." >&2 exit 1 fi if [ -z "$ID_CDROM" ]; then echo "$DEVPATH is not a CD reader." >&2 exit 1 fi # Prevent parallel processes from modifying the file at the same time. lock_rules_file link_num=$(find_next_available 'cdrom[0-9]*') #match="ENV{ID_PATH}==\"$ID_PATH\"" #kernel=${DEVPATH##*/} #match="KERNEL==\"$kernel\"" id=${PHYSDEVPATH##*/} match="BUS==\"$PHYSDEVBUS\", ID==\"$id\"" comment="$ID_MODEL ($ID_PATH)" write_rule "$match" "cdrom$link_num" "$comment" [ "$ID_CDROM_CD_RW" ] && write_rule "$match" "cdrw$link_num" [ "$ID_CDROM_DVD" ] && write_rule "$match" "dvd$link_num" [ "$ID_CDROM_DVD_RW" ] && write_rule "$match" "dvdrw$link_num" unlock_rules_file echo $SYMLINKS exit 0