The branch stable/14 has been updated by ivy:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7d88b0e3dbe46da939bd9f95164b2d332e9fd53d

commit 7d88b0e3dbe46da939bd9f95164b2d332e9fd53d
Author:     Lexi Winter <[email protected]>
AuthorDate: 2025-05-14 14:33:36 +0000
Commit:     Lexi Winter <[email protected]>
CommitDate: 2025-06-01 09:14:52 +0000

    rc.subr: remove the dependency on bsdconfig
    
    rc.subr uses sysrc(8) for the 'enable' and 'disable' commands, which
    means the entire rc(8) stack depends on bsdconfig.  Instead, provide a
    minimal amount of rc.conf-editing functionality in rc.subr and use it to
    implement these commands.
    
    Reviewed by:    des, bapt
    Approved by:    des (mentor)
    Differential Revision:  https://reviews.freebsd.org/D50325
    
    (cherry picked from commit f6328f052518d56c01f10e14cd9ef1f2675c01a4)
---
 libexec/rc/rc.subr | 102 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 86 insertions(+), 16 deletions(-)

diff --git a/libexec/rc/rc.subr b/libexec/rc/rc.subr
index 5140f2a1addc..c6bc6d1a1395 100644
--- a/libexec/rc/rc.subr
+++ b/libexec/rc/rc.subr
@@ -53,6 +53,9 @@ PS="/bin/ps -ww"
 JID=0
 CPUSET="/bin/cpuset"
 
+# Cache the services that we loaded with load_rc_config.
+_loaded_services=""
+
 # rc_service provides the path to the service script that we are executing.
 # This is not being set here in an execution context, necessarily, so it's
 # really just a reasonable guess, and it will get overwritten later if
@@ -1102,28 +1105,17 @@ run_rc_command()
                        ;;
 
                enable)
-                       _out=$(/usr/sbin/sysrc -vs "$name" "$rcvar=YES") &&
-                               echo "$name enabled in ${_out%%:*}"
+                       _out=$(write_rcvar "$rcvar" "YES") &&
+                               echo "$name enabled in $_out"
                        ;;
 
                disable)
-                       _out=$(/usr/sbin/sysrc -vs "$name" "$rcvar=NO") &&
-                               echo "$name disabled in ${_out%%:*}"
+                       _out=$(write_rcvar "$rcvar" "NO") &&
+                               echo "$name disabled in $_out"
                        ;;
 
                delete)
-                       _files=
-                       for _file in $(/usr/sbin/sysrc -lEs "$name"); do
-                               _out=$(/usr/sbin/sysrc -Fif $_file "$rcvar") && 
_files="$_files $_file"
-                       done
-                       /usr/sbin/sysrc -x "$rcvar" && echo "$rcvar deleted in 
${_files# }"
-                               # delete file in rc.conf.d if desired and empty.
-                       checkyesno service_delete_empty || _files=
-                       for _file in $_files; do
-                               [ "$_file" = "${_file#*/rc.conf.d/}" ] && 
continue
-                               [ $(/usr/bin/stat -f%z $_file) -gt 0 ] && 
continue
-                               /bin/rm "$_file" && echo "Empty file $_file 
removed"
-                       done
+                       delete_rcvar "$rcvar"
                        ;;
 
                status)
@@ -1540,6 +1532,7 @@ load_rc_config()
        # If a service name was specified, attempt to load
        # service-specific configuration
        if [ -n "$_name" ] ; then
+               _loaded_services="${_loaded_services} ${_name}"
                for _d in /etc ${local_startup}; do
                        _d=${_d%/rc.d}
                        if [ -f ${_d}/rc.conf.d/"$_name" ]; then
@@ -2293,6 +2286,83 @@ _echoonce()
        esac
 }
 
+# _find_rcvar var
+#      Find the rc.conf file (other than /etc/defaults/rc.conf) that sets $var.
+_find_rcvar()
+{
+       local _var _dir _files
+
+       [ -n "$1" ] || return 1
+       _var="$1"; shift
+
+       _files="/etc/rc.conf"
+       for _dir in /etc ${local_startup}; do
+               for _name in $_loaded_services; do
+                       _files="${_dir%/rc.d}/rc.conf.d/${_name} ${_files}"
+               done
+       done
+
+       /usr/bin/grep 2>/dev/null -rl "^${_var}=" $_files | /usr/bin/head -1
+}
+
+# write_rcvar var value
+#      Add or replace the rc var $var with the value $value.
+#      Look for a current setting of $var in /etc/rc.conf or 
/etc/rc.conf.d/$name,
+#      and if found, modify it there; otherwise, append to /etc/rc.conf.
+write_rcvar()
+{
+       local _var _value _file _dir
+
+       [ -n "$1" ] || return 1
+       _var="$1"; shift
+       [ -n "$1" ] || return 1
+       _value="$1"; shift
+
+       _file="$(_find_rcvar "$_var")"
+       if [ -n "$_file" ]; then
+               local _=$'\01'
+               /usr/bin/sed -i '' 
"s${_}^${_var}=.*${_}${_var}=\"$_value\"${_}" "$_file"
+               echo $_file
+               return
+       fi
+
+       for _dir in /etc ${local_startup}; do
+               _file="${_dir%/rc.d}/rc.conf.d/${name}"
+               if [ -f "$_file" ]; then
+                       echo "${_var}=\"${_value}\"" >>"$_file"
+                       echo "$_file"
+                       return
+               fi
+       done
+
+       echo "${_var}=\"${_value}\"" >>/etc/rc.conf
+       echo "/etc/rc.conf"
+}
+
+# delete_rcvar var
+#      Remove the rc var $var.
+#      Look for a current setting of $var in /etc/rc.conf or 
/etc/rc.conf.d/$name,
+#      and if found, remove it.  If service_delete_empty is enabled, and the
+#      resulting file is empty, also delete the file.
+delete_rcvar()
+{
+       local _var _files
+
+       [ -n "$1" ] || return 1
+       _var="$1"; shift
+
+       _file="$(_find_rcvar "$_var")"
+       if [ -n "$_file" ]; then
+               /usr/bin/sed -i '' "/^${_var}=/d" "$_file"
+               echo "$_var deleted in $_file"
+
+               if checkyesno service_delete_empty && [ ! -s "$_file" ]; then
+                       /bin/rm -f "$_file"
+                       echo "Empty file $_file removed"
+               fi
+       fi
+}
+
 # If the loader env variable rc.debug is set, turn on debugging. rc.conf will
 # still override this, but /etc/defaults/rc.conf can't unconditionally set this
 # since it would undo what we've done here.

Reply via email to