| #!/bin/sh |
| # dhcpcd client configuration script |
| |
| # Handy variables and functions for our hooks to use |
| from=from |
| signature_base="# Generated by dhcpcd" |
| signature="$signature_base $from $interface" |
| signature_base_end="# End of dhcpcd" |
| signature_end="$signature_base_end $from $interface" |
| state_dir=/var/run/dhcpcd |
| |
| # Ensure that all arguments are unique |
| uniqify() |
| { |
| local result= i= |
| for i; do |
| case " $result " in |
| *" $i "*);; |
| *) result="$result $i";; |
| esac |
| done |
| echo "${result# *}" |
| } |
| |
| # List interface config files in a dir |
| # If dhcpcd is running as a single instance then it will have a list of |
| # interfaces in the preferred order. |
| # Otherwise we just use what we have. |
| list_interfaces() |
| { |
| local i= x= ifaces= |
| for i in $interface_order; do |
| [ -e "$1/$i" ] && ifaces="$ifaces${ifaces:+ }$i" |
| done |
| for x in "$1"/*; do |
| [ -e "$x" ] || continue |
| for i in $interface_order; do |
| if [ $i = "${x##*/}" ]; then |
| unset x |
| break |
| fi |
| done |
| [ -n "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}" |
| done |
| echo "$ifaces" |
| } |
| |
| # We normally use sed to extract values using a key from a list of files |
| # but sed may not always be available at the time. |
| key_get_value() |
| { |
| local key="$1" value= x= line= |
| |
| shift |
| if type sed >/dev/null 2>&1; then |
| sed -n "s/^$key//p" $@ |
| else |
| for x; do |
| while read line; do |
| case "$line" in |
| "$key"*) echo "${line##$key}";; |
| esac |
| done < "$x" |
| done |
| fi |
| } |
| |
| # We normally use sed to remove markers from a configuration file |
| # but sed may not always be available at the time. |
| remove_markers() |
| { |
| local m1="$1" m2="$2" x= line= in_marker=0 |
| |
| shift; shift |
| if type sed >/dev/null 2>&1; then |
| sed "/^$m1/,/^$m2/d" $@ |
| else |
| for x; do |
| while read line; do |
| case "$line" in |
| "$m1"*) in_marker=1;; |
| "$m2"*) in_marker=0;; |
| *) [ $in_marker = 0 ] && echo "$line";; |
| esac |
| done < "$x" |
| done |
| fi |
| } |
| |
| # Compare two files |
| # If different, replace first with second otherwise remove second |
| change_file() |
| { |
| if type cmp >/dev/null 2>&1; then |
| cmp -s "$1" "$2" |
| elif type diff >/dev/null 2>&1; then |
| diff -q "$1" "$2" >/dev/null |
| else |
| # Hopefully we're only working on small text files ... |
| [ "$(cat "$1")" = "$(cat "$2")" ] |
| fi |
| if [ $? -eq 0 ]; then |
| rm -f "$2" |
| return 1 |
| fi |
| cat "$2" > "$1" |
| rm -f "$2" |
| return 0 |
| } |
| |
| # Save a config file |
| save_conf() |
| { |
| if [ -f "$1" ]; then |
| rm -f "$1-pre.$interface" |
| cat "$1" > "$1-pre.$interface" |
| fi |
| } |
| |
| # Restore a config file |
| restore_conf() |
| { |
| [ -f "$1-pre.$interface" ] || return 1 |
| cat "$1-pre.$interface" > "$1" |
| rm -f "$1-pre.$interface" |
| } |
| |
| # Write a syslog entry |
| syslog() |
| { |
| local lvl="$1" |
| |
| [ -n "$lvl" ] && shift |
| if [ -n "$@" ]; then |
| if type logger >/dev/null 2>&1; then |
| logger -t dhcpcd -p daemon."$lvl" -s "$@" |
| fi |
| fi |
| } |
| |
| |
| # We source each script into this one so that scripts run earlier can |
| # remove variables from the environment so later scripts don't see them. |
| # Thus, the user can create their dhcpcd.enter/exit-hook script to configure |
| # /etc/resolv.conf how they want and stop the system scripts ever updating it. |
| for hook in \ |
| @SYSCONFDIR@/dhcpcd.enter-hook \ |
| @HOOKDIR@/* \ |
| @SYSCONFDIR@/dhcpcd.exit-hook |
| do |
| for skip in $skip_hooks; do |
| case "$hook" in |
| */"$skip") continue 2;; |
| */[0-9][0-9]"-$skip") continue 2;; |
| */[0-9][0-9]"-$skip.sh") continue 2;; |
| esac |
| done |
| if [ -f "$hook" ]; then |
| . "$hook" |
| fi |
| done |