Author: dteske
Date: Mon Mar 23 19:25:34 2015
New Revision: 280391
URL: https://svnweb.freebsd.org/changeset/base/280391

Log:
  MFC revisions 268860, 268863, 274068, 274119, 279624:
  r268860: Minor enhancements, bug fixes, man-page adjustments to sysrc(8)
  r268863: Bump date/copyright in man-page
  r274068: Add key+=append syntax
  r279624: Add key-=remove syntax
  r274119: Add EXAMPLES-section entries for new syntax
  
  Reported by:  lme (r268860)
  Reviewed by:  shurd (r274068)
  Thanks to:    seanc (r274068, r279624, r274119)

Modified:
  stable/9/usr.sbin/sysrc/sysrc
  stable/9/usr.sbin/sysrc/sysrc.8
Directory Properties:
  stable/9/usr.sbin/sysrc/   (props changed)

Modified: stable/9/usr.sbin/sysrc/sysrc
==============================================================================
--- stable/9/usr.sbin/sysrc/sysrc       Mon Mar 23 19:12:55 2015        
(r280390)
+++ stable/9/usr.sbin/sysrc/sysrc       Mon Mar 23 19:25:34 2015        
(r280391)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #-
-# Copyright (c) 2010-2013 Devin Teske
+# Copyright (c) 2010-2015 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 #
 # Version information
 #
-SYSRC_VERSION="6.0 Nov-07,2013"
+SYSRC_VERSION="6.3 Mar-4,2015"
 
 #
 # Options
@@ -80,7 +80,7 @@ die()
 #
 usage()
 {
-       f_err "Usage: %s [OPTIONS] name[=value] ...\n" "$pgm"
+       f_err "Usage: %s [OPTIONS] name[[+]=value] ...\n" "$pgm"
        f_err "Try \`%s --help' for more information.\n" "$pgm"
        die
 }
@@ -94,7 +94,7 @@ help()
        local optfmt="\t%-11s%s\n"
        local envfmt="\t%-17s%s\n"
 
-       f_err "Usage: %s [OPTIONS] name[=value] ...\n" "$pgm"
+       f_err "Usage: %s [OPTIONS] name[[+|-]=value] ...\n" "$pgm"
 
        f_err "OPTIONS:\n"
        f_err "$optfmt" "-a" \
@@ -102,7 +102,7 @@ help()
        f_err "$optfmt" "-A" \
              "Dump a list of all configuration variables (incl. defaults)."
        f_err "$optfmt" "-c" \
-             "Check. Return success if no changes needed, else error."
+             "Check. Return success if set or no changes, else error."
        f_err "$optfmt" "-d" \
              "Print a description of the given variable."
        f_err "$optfmt" "-D" \
@@ -134,7 +134,7 @@ help()
        f_err "$optfmt" "-N" \
              "Show only variable names, not their values."
        f_err "$optfmt" "-q" \
-             "Quiet. Ignore previous \`-v' and/or SYSRC_VERBOSE."
+             "Quiet. Disable verbose and hide certain errors."
        f_err "$optfmt" "-R dir" \
              "Operate within the root directory \`dir' rather than \`/'."
        f_err "$optfmt" "-v" \
@@ -152,8 +152,6 @@ help()
              "Override default rc_conf_files (even if set to NULL)."
        f_err "$envfmt" "RC_DEFAULTS" \
              "Location of \`/etc/defaults/rc.conf' file."
-       f_err "$envfmt" "SYSRC_VERBOSE" \
-             "Default verbosity. Set to non-NULL to enable."
 
        die
 }
@@ -527,10 +525,16 @@ fi
 #
 # Process command-line arguments
 #
-costatus=$SUCCESS
+status=$SUCCESS
 while [ $# -gt 0 ]; do
        NAME="${1%%=*}"
 
+       case "$NAME" in
+       *+) mode=APPEND NAME="${NAME%+}" ;;
+       *-) mode=REMOVE NAME="${NAME%-}" ;;
+        *) mode=ASSIGN
+       esac
+
        [ "$DESCRIBE" ] && \
                echo "$NAME: $( f_sysrc_desc "$NAME" )"
 
@@ -558,7 +562,7 @@ while [ $# -gt 0 ]; do
                # desire to set some value
                #
                if [ "$DELETE" ]; then
-                       f_sysrc_delete "$NAME"
+                       f_sysrc_delete "$NAME" || status=$FAILURE
                        shift 1
                        continue
                fi
@@ -568,28 +572,93 @@ while [ $# -gt 0 ]; do
                #
                if [ "$CHECK_ONLY" ]; then
                        if ! IGNORED=$( f_sysrc_get "$NAME?" ); then
-                               costatus=$FAILURE
-                       else
-                               value=$( f_sysrc_get "$NAME" )
-                               [ "$value" = "${1#*=}" ] || costatus=$FAILURE
+                               status=$FAILURE
+                               [ "$SYSRC_VERBOSE" ] &&
+                                       echo "$NAME: not currently set"
+                               shift 1
+                               continue
+                       fi
+                       value=$( f_sysrc_get "$NAME" )
+                       if [ "$value" != "${1#*=}" ]; then
+                               status=$FAILURE
+                               if [ "$SYSRC_VERBOSE" ]; then
+                                       echo -n "$( f_sysrc_find "$NAME" ): "
+                                       echo -n "$NAME: would change from "
+                                       echo "\`$value' to \`${1#*=}'"
+                               fi
+                       elif [ "$SYSRC_VERBOSE" ]; then
+                               echo -n "$( f_sysrc_find "$NAME" ): "
+                               echo "$NAME: already set to \`$value'"
                        fi
                        shift 1
                        continue
                fi
 
                #
-               # If `-N' is passed, simplify the output
+               # Determine both `before' value and appropriate `new' value
                #
-               if [ ! "$SHOW_VALUE" ]; then
-                       echo "$NAME"
-                       f_sysrc_set "$NAME" "${1#*}"
-               else
+               case "$mode" in
+               APPEND)
+                       before=$( f_sysrc_get "$NAME" )
+                       add="${1#*=}"
+                       delim="${add%"${add#?}"}" # first character
+                       oldIFS="$IFS"
+                       case "$delim" in
+                       ""|[$IFS]|[a-zA-Z0-9]) delim=" " ;;
+                       *) IFS="$delim"
+                       esac
+                       new="$before"
+                       for a in $add; do
+                               [ "$a" ] || continue
+                               skip=
+                               for b in $before; do
+                                       [ "$b" = "$a" ] && skip=1 break
+                               done
+                               [ "$skip" ] || new="$new$delim$a"
+                       done
+                       new="${new#"$delim"}" IFS="$oldIFS"
+                       unset add delim oldIFS a skip b
+                       [ "$SHOW_FILE" ] && before=$( f_sysrc_find "$NAME" )
+                       ;;
+               REMOVE)
+                       before=$( f_sysrc_get "$NAME" )
+                       remove="${1#*=}"
+                       delim="${remove%"${remove#?}"}" # first character
+                       oldIFS="$IFS"
+                       case "$delim" in
+                       ""|[$IFS]|[a-zA-Z0-9]) delim=" " ;;
+                       *) IFS="$delim"
+                       esac
+                       new=
+                       for b in $before; do
+                               [ "$b" ] || continue
+                               add=1
+                               for r in $remove; do
+                                       [ "$r" = "$b" ] && add= break
+                               done
+                               [ "$add" ] && new="$new$delim$b"
+                       done
+                       new="${new#"$delim"}" IFS="$oldIFS"
+                       unset remove delim oldIFS b add r
+                       [ "$SHOW_FILE" ] && before=$( f_sysrc_find "$NAME" )
+                       ;;
+               *)
                        if [ "$SHOW_FILE" ]; then
                                before=$( f_sysrc_find "$NAME" )
                        else
                                before=$( f_sysrc_get "$NAME" )
                        fi
-                       if f_sysrc_set "$NAME" "${1#*=}"; then
+                       new="${1#*=}"
+               esac
+
+               #
+               # If `-N' is passed, simplify the output
+               #
+               if [ ! "$SHOW_VALUE" ]; then
+                       echo "$NAME"
+                       f_sysrc_set "$NAME" "$new"
+               else
+                       if f_sysrc_set "$NAME" "$new"; then
                                if [ "$SHOW_FILE" ]; then
                                        after=$( f_sysrc_find "$NAME" )
                                else
@@ -604,10 +673,10 @@ while [ $# -gt 0 ]; do
                ;;
        *)
                if ! IGNORED=$( f_sysrc_get "$NAME?" ); then
-                       [ "$IGNORE_UNKNOWNS" ] ||
+                       [ "$IGNORE_UNKNOWNS" -o "$QUIET" ] ||
                                echo "$pgm: unknown variable '$NAME'"
                        shift 1
-                       costatus=$FAILURE
+                       status=$FAILURE
                        continue
                fi
 
@@ -631,7 +700,7 @@ while [ $# -gt 0 ]; do
                # If `-x' or `-X' is passed, delete the variable
                #
                if [ "$DELETE" ]; then
-                       f_sysrc_delete "$NAME"
+                       f_sysrc_delete "$NAME" || status=$FAILURE
                        shift 1
                        continue
                fi
@@ -667,7 +736,7 @@ while [ $# -gt 0 ]; do
        shift 1
 done
 
-[ ! "$CHECK_ONLY" ] || exit $costatus
+exit $status # $SUCCESS unless error occurred with either `-c' or `-x'
 
 
################################################################################
 # END

Modified: stable/9/usr.sbin/sysrc/sysrc.8
==============================================================================
--- stable/9/usr.sbin/sysrc/sysrc.8     Mon Mar 23 19:12:55 2015        
(r280390)
+++ stable/9/usr.sbin/sysrc/sysrc.8     Mon Mar 23 19:25:34 2015        
(r280391)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2011-2013 Devin Teske
+.\" Copyright (c) 2011-2015 Devin Teske
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Nov 20, 2013
+.Dd March 4, 2015
 .Dt SYSRC 8
 .Os
 .Sh NAME
@@ -35,7 +35,7 @@
 .Op Fl cdDeFhinNqvx
 .Op Fl f Ar file
 .Op Fl j Ar jail | Fl R Ar dir
-.Ar name Ns Op = Ns Ar value
+.Ar name Ns Op Ns Oo +|- Oc Ns = Ns Ar value
 .Ar ...
 .Nm
 .Op Fl cdDeFhinNqvx
@@ -58,11 +58,14 @@ Dump a list of all non-default configura
 Dump a list of all configuration variables
 .Pq incl. defaults .
 .It Fl c
-Check if the value will change when assigning a new value.
+Check only.
+For querying, return success if all requested variables are set
+.Pq even if NULL ,
+otherwise return error status.
+For assignments, return success if no changes are required, otherwise failure.
 If verbose
 .Pq see Dq Fl v
-prints a message stating whether a change would occur.
-Exits with success if no change is necessary, else returns error status.
+prints a message stating whether variables are set and/or changes are required.
 .It Fl d
 Print a description of the given variable.
 .It Fl D
@@ -108,14 +111,12 @@ Show only variable values, not their nam
 Show only variable names, not their values.
 .It Fl q
 Quiet.
-Ignore previous occurrences of
-.Fl v
-flag.
+Disable verbose and hide certain errors.
 .It Fl R Ar dir
 Operate within the root directory
-.Pq Sq Ar dir
+.Sq Ar dir
 rather than
-.Pq Sq / .
+.Sq / .
 .It Fl v
 Verbose.
 Print the pathname of the specific
@@ -127,13 +128,22 @@ Print version information to stdout and 
 Remove variable(s) from specified file(s).
 .El
 .Pp
-This utility works similar to
+This utility has a similar syntax to
 .Xr sysctl 8 .
 It shares the `-e' and `-n' options
 .Pq detailed above
 and also has the same
 .Ql name[=value]
-syntax for querying/setting configuration options.
+syntax for making queries/assignments.
+In addition
+.Pq but unlike Xr sysctl 8 ,
+.Ql name+=value
+is supported for adding items to values
+.Pq see APPENDING VALUES
+and
+.Ql name-=value
+is supported for removing items from values
+.Pq see SUBTRACTING VALUES .
 .Pp
 However, while
 .Xr sysctl 8
@@ -182,6 +192,115 @@ modifying these integral files (yet taki
 grow unwieldy should
 .Nm
 be called repeatedly).
+.Sh APPENDING VALUES
+When using the
+.Ql key+=value
+syntax to add items to existing values,
+the first character of the value is taken as the delimiter separating items
+.Pq usually Qo \  Qc or Qo , Qc .
+For example, in the following statement:
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces+=" gif0"
+.El
+.Pp
+the first character is a space, informing
+.Nm
+that existing values are to be considered separated by whitespace.
+If
+.Ql gif0
+is not found in the existing value for
+.Va cloned_interfaces ,
+it is added
+.Pq with delimiter only if existing value is non-NULL .
+.Pp
+For convenience, if the first character is alpha-numeric
+.Pq letters A-Z, a-z, or numbers 0-9 ,
+.Nm
+uses the default setting of whitespace as separator.
+For example, the above and below statements are equivalent since
+.Dq gif0
+starts with an alpha-numeric character
+.Pq the letter Li g :
+.Pp
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces+=gif0
+.El
+.Pp
+Take the following sequence for example:
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces= # start with NULL
+.It \ 
+.Nm
+cloned_interfaces+=gif0
+.Dl # NULL -> `gif0' Pq NB: no preceding delimiter
+.It \ 
+.Nm
+cloned_interfaces+=gif0 # no change
+.It \ 
+.Nm
+cloned_interfaces+="tun0 gif0"
+.Dl # `gif0' -> `gif0 tun0' Pq NB: no duplication
+.El
+.Pp
+.Nm
+prevents the same value from being added if already there.
+.Sh SUBTRACTING VALUES
+When using the
+.Ql key-=value
+syntax to remove items from existing values,
+the first character of the value is taken as the delimiter separating items
+.Pq usually Qo \  Qc or Qo , Qc .
+For example, in the following statement:
+.Pp
+.Dl Nm cloned_interfaces-=" gif0"
+.Pp
+the first character is a space, informing
+.Nm
+that existing values are to be considered separated by whitespace.
+If
+.Ql gif0
+is found in the existing value for
+.Va cloned_interfaces ,
+it is removed
+.Pq extra delimiters removed .
+.Pp
+For convenience, if the first character is alpha-numeric
+.Pq letters A-Z, a-z, or numbers 0-9 ,
+.Nm
+uses the default setting of whitespace as separator.
+For example, the above and below statements are equivalent since
+.Dq gif0
+starts with an alpha-numeric character
+.Pq the letter Li g :
+.Pp
+.Bl -tag -width indent+
+.It \ 
+.Nm
+cloned_interfaces-=gif0
+.El
+.Pp
+Take the following sequence for example:
+.Bl -tag -width indent+
+.It \ 
+.Nm
+foo="bar baz" # start
+.It \ 
+.Nm
+foo-=bar # `bar baz' -> `baz'
+.It \ 
+.Nm
+foo-=baz # `baz' -> NULL
+.El
+.Pp
+.Nm
+removes all occurrences of all items provided
+and collapses extra delimiters between items.
 .Sh ENVIRONMENT
 The following environment variables are referenced by
 .Nm :
@@ -242,6 +361,16 @@ Working on other files, such as
 -f /etc/crontab MAILTO
 .Dl returns the value of the MAILTO setting Pq if configured .
 .Pp
+Appending to existing values:
+.Pp
+.Nm
+\&cloned_interfaces+=gif0
+.Dl appends Qo gif0 Qc to $cloned_interfaces Pq see APPENDING VALUES .
+.Pp
+.Nm
+\&cloned_interfaces-=gif0
+.Dl removes Qo gif0 Qc from $cloned_interfaces Pq see SUBTRACTING VALUES .
+.Pp
 In addition to the above syntax,
 .Nm
 also supports inline
@@ -304,5 +433,5 @@ utility first appeared in
 .An Devin Teske Aq dte...@freebsd.org
 .Sh THANKS TO
 Brandon Gooch, Garrett Cooper, Julian Elischer, Pawel Jakub Dawidek,
-Cyrille Lefevre, Ross West, Stefan Esser, Marco Steinbach, and Jilles Tjoelker
-for suggestions and help.
+Cyrille Lefevre, Ross West, Stefan Esser, Marco Steinbach, Jilles Tjoelker,
+Allan Jude, and Lars Engels for suggestions, help, and testing.
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to