199ca880aSopenharmony_ci# functions used by the udev rule generator 299ca880aSopenharmony_ci 399ca880aSopenharmony_ci# Copyright (C) 2006 Marco d'Itri <md@Linux.IT> 499ca880aSopenharmony_ci 599ca880aSopenharmony_ci# This program is free software: you can redistribute it and/or modify 699ca880aSopenharmony_ci# it under the terms of the GNU General Public License as published by 799ca880aSopenharmony_ci# the Free Software Foundation, either version 2 of the License, or 899ca880aSopenharmony_ci# (at your option) any later version. 999ca880aSopenharmony_ci 1099ca880aSopenharmony_ci# This program is distributed in the hope that it will be useful, 1199ca880aSopenharmony_ci# but WITHOUT ANY WARRANTY; without even the implied warranty of 1299ca880aSopenharmony_ci# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1399ca880aSopenharmony_ci# GNU General Public License for more details. 1499ca880aSopenharmony_ci 1599ca880aSopenharmony_ci# You should have received a copy of the GNU General Public License 1699ca880aSopenharmony_ci# along with this program. If not, see <http://www.gnu.org/licenses/>. 1799ca880aSopenharmony_ci 1899ca880aSopenharmony_ciPATH='/sbin:/bin' 1999ca880aSopenharmony_ci# 2099ca880aSopenharmony_ci 2199ca880aSopenharmony_ciPATH='/sbin:/bin' 2299ca880aSopenharmony_ci 2399ca880aSopenharmony_ci# Read a single line from file $1 in the $DEVPATH directory. 2499ca880aSopenharmony_ci# The function must not return an error even if the file does not exist. 2599ca880aSopenharmony_cisysread() { 2699ca880aSopenharmony_ci local file="$1" 2799ca880aSopenharmony_ci [ -e "/sys$DEVPATH/$file" ] || return 0 2899ca880aSopenharmony_ci local value 2999ca880aSopenharmony_ci read value < "/sys$DEVPATH/$file" || return 0 3099ca880aSopenharmony_ci echo "$value" 3199ca880aSopenharmony_ci} 3299ca880aSopenharmony_ci 3399ca880aSopenharmony_cisysreadlink() { 3499ca880aSopenharmony_ci local file="$1" 3599ca880aSopenharmony_ci [ -e "/sys$DEVPATH/$file" ] || return 0 3699ca880aSopenharmony_ci readlink -f /sys$DEVPATH/$file 2> /dev/null || true 3799ca880aSopenharmony_ci} 3899ca880aSopenharmony_ci 3999ca880aSopenharmony_ci# Return true if a directory is writeable. 4099ca880aSopenharmony_ciwriteable() { 4199ca880aSopenharmony_ci if ln -s test-link $1/.is-writeable 2> /dev/null; then 4299ca880aSopenharmony_ci rm -f $1/.is-writeable 4399ca880aSopenharmony_ci return 0 4499ca880aSopenharmony_ci else 4599ca880aSopenharmony_ci return 1 4699ca880aSopenharmony_ci fi 4799ca880aSopenharmony_ci} 4899ca880aSopenharmony_ci 4999ca880aSopenharmony_ci# Create a lock file for the current rules file. 5099ca880aSopenharmony_cilock_rules_file() { 5199ca880aSopenharmony_ci RUNDIR="/run/udev/" 5299ca880aSopenharmony_ci 5399ca880aSopenharmony_ci RULES_LOCK="$RUNDIR/.lock-${RULES_FILE##*/}" 5499ca880aSopenharmony_ci 5599ca880aSopenharmony_ci retry=30 5699ca880aSopenharmony_ci while ! mkdir $RULES_LOCK 2> /dev/null; do 5799ca880aSopenharmony_ci if [ $retry -eq 0 ]; then 5899ca880aSopenharmony_ci echo "Cannot lock $RULES_FILE!" >&2 5999ca880aSopenharmony_ci exit 2 6099ca880aSopenharmony_ci fi 6199ca880aSopenharmony_ci sleep 1 6299ca880aSopenharmony_ci retry=$(($retry - 1)) 6399ca880aSopenharmony_ci done 6499ca880aSopenharmony_ci} 6599ca880aSopenharmony_ci 6699ca880aSopenharmony_ciunlock_rules_file() { 6799ca880aSopenharmony_ci [ "$RULES_LOCK" ] || return 0 6899ca880aSopenharmony_ci rmdir $RULES_LOCK || true 6999ca880aSopenharmony_ci} 7099ca880aSopenharmony_ci 7199ca880aSopenharmony_ci# Choose the real rules file if it is writeable or a temporary file if not. 7299ca880aSopenharmony_ci# Both files should be checked later when looking for existing rules. 7399ca880aSopenharmony_cichoose_rules_file() { 7499ca880aSopenharmony_ci RUNDIR="/run/udev/" 7599ca880aSopenharmony_ci 7699ca880aSopenharmony_ci local tmp_rules_file="$RUNDIR/tmp-rules--${RULES_FILE##*/}" 7799ca880aSopenharmony_ci [ -e "$RULES_FILE" -o -e "$tmp_rules_file" ] || PRINT_HEADER=1 7899ca880aSopenharmony_ci 7999ca880aSopenharmony_ci [ -d "${RULES_FILE%/*}" ] || if writeable ${RULES_FILE%/rules.d/*}; then 8099ca880aSopenharmony_ci mkdir -p "${RULES_FILE%/*}" 8199ca880aSopenharmony_ci fi 8299ca880aSopenharmony_ci 8399ca880aSopenharmony_ci if writeable ${RULES_FILE%/*}; then 8499ca880aSopenharmony_ci RO_RULES_FILE='/dev/null' 8599ca880aSopenharmony_ci else 8699ca880aSopenharmony_ci RO_RULES_FILE=$RULES_FILE 8799ca880aSopenharmony_ci RULES_FILE=$tmp_rules_file 8899ca880aSopenharmony_ci fi 8999ca880aSopenharmony_ci} 9099ca880aSopenharmony_ci 9199ca880aSopenharmony_ci# Return the name of the first free device. 9299ca880aSopenharmony_ciraw_find_next_available() { 9399ca880aSopenharmony_ci local links="$1" 9499ca880aSopenharmony_ci 9599ca880aSopenharmony_ci local basename=${links%%[ 0-9]*} 9699ca880aSopenharmony_ci local max=-1 9799ca880aSopenharmony_ci for name in $links; do 9899ca880aSopenharmony_ci local num=${name#$basename} 9999ca880aSopenharmony_ci [ "$num" ] || num=0 10099ca880aSopenharmony_ci [ $num -gt $max ] && max=$num 10199ca880aSopenharmony_ci done 10299ca880aSopenharmony_ci 10399ca880aSopenharmony_ci local max=$(($max + 1)) 10499ca880aSopenharmony_ci # "name0" actually is just "name" 10599ca880aSopenharmony_ci [ $max -eq 0 ] && return 10699ca880aSopenharmony_ci echo "$max" 10799ca880aSopenharmony_ci} 10899ca880aSopenharmony_ci 10999ca880aSopenharmony_ci# Find all rules matching a key (with action) and a pattern. 11099ca880aSopenharmony_cifind_all_rules() { 11199ca880aSopenharmony_ci local key="$1" 11299ca880aSopenharmony_ci local linkre="$2" 11399ca880aSopenharmony_ci local match="$3" 11499ca880aSopenharmony_ci 11599ca880aSopenharmony_ci local search='.*[[:space:],]'"$key"'"('"$linkre"')".*' 11699ca880aSopenharmony_ci echo $(sed -n -r -e 's/^#.*//' -e "${match}s/${search}/\1/p" \ 11799ca880aSopenharmony_ci $RO_RULES_FILE \ 11899ca880aSopenharmony_ci $([ -e $RULES_FILE ] && echo $RULES_FILE) \ 11999ca880aSopenharmony_ci 2>/dev/null) 12099ca880aSopenharmony_ci} 121