1# functions used by the udev rule generator 2 3# Copyright (C) 2006 Marco d'Itri <md@Linux.IT> 4 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 2 of the License, or 8# (at your option) any later version. 9 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18PATH='/sbin:/bin' 19# 20 21PATH='/sbin:/bin' 22 23# Read a single line from file $1 in the $DEVPATH directory. 24# The function must not return an error even if the file does not exist. 25sysread() { 26 local file="$1" 27 [ -e "/sys$DEVPATH/$file" ] || return 0 28 local value 29 read value < "/sys$DEVPATH/$file" || return 0 30 echo "$value" 31} 32 33sysreadlink() { 34 local file="$1" 35 [ -e "/sys$DEVPATH/$file" ] || return 0 36 readlink -f /sys$DEVPATH/$file 2> /dev/null || true 37} 38 39# Return true if a directory is writeable. 40writeable() { 41 if ln -s test-link $1/.is-writeable 2> /dev/null; then 42 rm -f $1/.is-writeable 43 return 0 44 else 45 return 1 46 fi 47} 48 49# Create a lock file for the current rules file. 50lock_rules_file() { 51 RUNDIR="/run/udev/" 52 53 RULES_LOCK="$RUNDIR/.lock-${RULES_FILE##*/}" 54 55 retry=30 56 while ! mkdir $RULES_LOCK 2> /dev/null; do 57 if [ $retry -eq 0 ]; then 58 echo "Cannot lock $RULES_FILE!" >&2 59 exit 2 60 fi 61 sleep 1 62 retry=$(($retry - 1)) 63 done 64} 65 66unlock_rules_file() { 67 [ "$RULES_LOCK" ] || return 0 68 rmdir $RULES_LOCK || true 69} 70 71# Choose the real rules file if it is writeable or a temporary file if not. 72# Both files should be checked later when looking for existing rules. 73choose_rules_file() { 74 RUNDIR="/run/udev/" 75 76 local tmp_rules_file="$RUNDIR/tmp-rules--${RULES_FILE##*/}" 77 [ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1 78 79 [ -d "${RULES_FILE%/*}" ] || if writeable ${RULES_FILE%/rules.d/*}; then 80 mkdir -p "${RULES_FILE%/*}" 81 fi 82 83 if writeable ${RULES_FILE%/*}; then 84 RO_RULES_FILE='/dev/null' 85 else 86 RO_RULES_FILE=$RULES_FILE 87 RULES_FILE=$tmp_rules_file 88 fi 89} 90 91# Return the name of the first free device. 92raw_find_next_available() { 93 local links="$1" 94 95 local basename=${links%%[ 0-9]*} 96 local max=-1 97 for name in $links; do 98 local num=${name#$basename} 99 [ "$num" ] || num=0 100 [ $num -gt $max ] && max=$num 101 done 102 103 local max=$(($max + 1)) 104 # "name0" actually is just "name" 105 [ $max -eq 0 ] && return 106 echo "$max" 107} 108 109# Find all rules matching a key (with action) and a pattern. 110find_all_rules() { 111 local key="$1" 112 local linkre="$2" 113 local match="$3" 114 115 local search='.*[[:space:],]'"$key"'"('"$linkre"')".*' 116 echo $(sed -n -r -e 's/^#.*//' -e "${match}s/${search}/\1/p" \ 117 $RO_RULES_FILE \ 118 $([ -e $RULES_FILE ] && echo $RULES_FILE) \ 119 2>/dev/null) 120} 121