Author: dteske
Date: Tue Apr  1 00:19:13 2014
New Revision: 263980
URL: http://svnweb.freebsd.org/changeset/base/263980

Log:
  MFC revisions 260894,260899,262895-262902,262904,262908-262910,262982,
  262984,263133-263137,263139,263141,263144-263150, and (partially) 263249
  (31 revisions; summarized below)...
  r260894: Optimize f_expand_number(), improving performance
  r260899: s/__number/__num/ in f_expand_number()
  r262895: Allow dispatched reswords to carry arguments
  r262896: Add missing local declaration
  r262897: Fix a typo in a comment
  r262898: Fix incorrect return status if var_to_set and var_to_get are same
  r262899: Make f_show_err non-fatal
  r262900: Centralize function name; Update a comment while here
  r262901: s/__num/__number/ in f_expand_number()
  r262902: Comment to go with NL global introduced by previous commit
  r262904: Rewrite groupmgmt -- hooking it into the scripting system
  r262908: Change dispatch words from group* to *Group for backward compat
  r262909: Fix copy/paste error in a comment
  r262910: Take a group name on the command-line if available
  r262982: Whitespace
  r262984: Remove vestigial global, no longer used since r262904
  r263133: Remove indexfile from debug statement (already logged)
  r263134: Add debug statement just before attempting to exec a module
  r263135: Comments
  r263136: Update copyright
  r263137: Fix future namespace issues for functions taking $var_to_set
  r263139: Remove useless NULL string in compound strings
  r263141: Pointy hat! Fix a broken f_isinteger()
  r263144: Fix a code-typo that prevented auto-sizing of a dialog
  r263145: Fix comments and whitespace
  r263146: Reduce the sleep cycle when using dialog(1) [infobox] to 1-second
  r263147: Fix a bug preventing errors from pw(8) from appearing
  r263148: For non-interactive scripts, forgot to check argument
  r263149: Add protection against input containing single-quotes
  r263150: Rewrite usermgmt
  r263249: (partial) Add more obsolete files

Added:
  stable/10/usr.sbin/bsdconfig/usermgmt/share/group.subr
     - copied, changed from r262904, 
head/usr.sbin/bsdconfig/usermgmt/share/group.subr
  stable/10/usr.sbin/bsdconfig/usermgmt/share/user.subr
     - copied unchanged from r263150, 
head/usr.sbin/bsdconfig/usermgmt/share/user.subr
Deleted:
  stable/10/usr.sbin/bsdconfig/usermgmt/groupinput
  stable/10/usr.sbin/bsdconfig/usermgmt/userinput
Modified:
  stable/10/ObsoleteFiles.inc
  stable/10/usr.sbin/bsdconfig/bsdconfig
  stable/10/usr.sbin/bsdconfig/share/common.subr
  stable/10/usr.sbin/bsdconfig/share/device.subr
  stable/10/usr.sbin/bsdconfig/share/dialog.subr
  stable/10/usr.sbin/bsdconfig/share/keymap.subr
  stable/10/usr.sbin/bsdconfig/share/script.subr
  stable/10/usr.sbin/bsdconfig/share/strings.subr
  stable/10/usr.sbin/bsdconfig/share/variable.subr
  stable/10/usr.sbin/bsdconfig/timezone/share/menus.subr
  stable/10/usr.sbin/bsdconfig/usermgmt/Makefile
  stable/10/usr.sbin/bsdconfig/usermgmt/groupadd
  stable/10/usr.sbin/bsdconfig/usermgmt/groupdel
  stable/10/usr.sbin/bsdconfig/usermgmt/groupedit
  stable/10/usr.sbin/bsdconfig/usermgmt/include/messages.subr
  stable/10/usr.sbin/bsdconfig/usermgmt/share/Makefile
  stable/10/usr.sbin/bsdconfig/usermgmt/share/group_input.subr
  stable/10/usr.sbin/bsdconfig/usermgmt/share/user_input.subr
  stable/10/usr.sbin/bsdconfig/usermgmt/useradd
  stable/10/usr.sbin/bsdconfig/usermgmt/userdel
  stable/10/usr.sbin/bsdconfig/usermgmt/useredit
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/ObsoleteFiles.inc
==============================================================================
--- stable/10/ObsoleteFiles.inc Mon Mar 31 21:04:15 2014        (r263979)
+++ stable/10/ObsoleteFiles.inc Tue Apr  1 00:19:13 2014        (r263980)
@@ -75,6 +75,10 @@ OLD_FILES+=usr/include/clang/3.3/xopintr
 OLD_FILES+=usr/share/man/man1/llvm-prof.1.gz
 OLD_FILES+=usr/share/man/man1/llvm-ranlib.1.gz
 OLD_DIRS+=usr/include/clang/3.3
+# 20140314: bsdconfig usermgmt rewrite
+OLD_FILES+=usr/libexec/bsdconfig/070.usermgmt/userinput
+# 20140307: bsdconfig groupmgmt rewrite
+OLD_FILES+=usr/libexec/bsdconfig/070.usermgmt/groupinput
 # 20131109: extattr(2) mlinks fixed
 OLD_FILES+=usr/share/man/man2/extattr_delete_list.2.gz
 OLD_FILES+=usr/share/man/man2/extattr_get_list.2.gz

Modified: stable/10/usr.sbin/bsdconfig/bsdconfig
==============================================================================
--- stable/10/usr.sbin/bsdconfig/bsdconfig      Mon Mar 31 21:04:15 2014        
(r263979)
+++ stable/10/usr.sbin/bsdconfig/bsdconfig      Tue Apr  1 00:19:13 2014        
(r263980)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #-
 # Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -315,8 +315,7 @@ if [ "$pgm" != "bsdconfig" ]; then
        if indexfile=$( f_index_file "$pgm" ) &&
           cmd=$( f_index_menusel_command "$indexfile" "$pgm" )
        then
-               f_dprintf "pgm=[%s] indexfile=[%s] cmd=[%s]" \
-                         "$pgm" "$indexfile" "$cmd"
+               f_dprintf "pgm=[%s] cmd=[%s] *=[%s]" "$pgm" "$cmd" "$*"
                exec "$cmd" "$@" || exit 1
        else
                f_include $BSDCFG_SHARE/script.subr
@@ -324,7 +323,7 @@ if [ "$pgm" != "bsdconfig" ]; then
                        [ "$pgm" = "$resword" ] || continue
                        # Found a match
                        f_dprintf "pgm=[%s] A valid resWord!" "$pgm"
-                       f_dispatch $resword
+                       f_dispatch $resword $resword "$@"
                        exit $?
                done
        fi
@@ -382,6 +381,7 @@ if [ "$1" ]; then
                # Not reached
        fi
 
+       f_dprintf "cmd=[%s] *=[%s]" "$cmd" "$*"
        shift
        exec $cmd ${USE_XDIALOG:+-X} "$@" || exit 1
        # Not reached

Modified: stable/10/usr.sbin/bsdconfig/share/common.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/common.subr      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/common.subr      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,7 +1,7 @@
 if [ ! "$_COMMON_SUBR" ]; then _COMMON_SUBR=1
 #
 # Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -153,7 +153,7 @@ f_debug_init()
        # Process stored command-line arguments
        #
        set -- $ARGV
-       local OPTIND
+       local OPTIND flag
        f_dprintf "f_debug_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \
                  "$ARGV" "$GETOPTS_STDARGS"
        while getopts "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" flag \
@@ -270,9 +270,9 @@ f_getvar()
 {
        local __var_to_get="$1" __var_to_set="$2"
        [ "$__var_to_set" ] || local value
-       eval ${__var_to_set:-value}=\"\${$__var_to_get}\"
        eval [ \"\${$__var_to_get+set}\" ]
        local __retval=$?
+       eval ${__var_to_set:-value}=\"\${$__var_to_get}\"
        eval f_dprintf '"f_getvar: var=[%s] value=[%s] r=%u"' \
                \"\$__var_to_get\" \"\$${__var_to_set:-value}\" \$__retval
        [ "$__var_to_set" ] || { [ "$value" ] && echo "$value"; }
@@ -368,13 +368,10 @@ f_show_msg()
 # f_show_err $format [$arguments ...]
 #
 # Display a message in a dialog box with ``Error'' i18n title (overridden by
-# setting msg_error) using printf(1) syntax. If running non-interactively,
-# the process will terminate (using [above] f_die()).
+# setting msg_error) using printf(1) syntax.
 #
 f_show_err()
 {
-       [ "$nonInteractive" ] && f_die
-
        local msg
        msg=$( printf "$@" )
 
@@ -523,7 +520,7 @@ f_include_lang()
 #      f_usage $file "FOO" "BAR"
 #
 # Will cause instances of "@FOO@" appearing in $file to be replaced with the
-# text "BAR" before bering printed to the screen.
+# text "BAR" before being printed to the screen.
 #
 # This function is a two-parter. Below is the awk(1) portion of the function,
 # afterward is the sh(1) function which utilizes the below awk script.

Modified: stable/10/usr.sbin/bsdconfig/share/device.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/device.subr      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/device.subr      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,6 +1,6 @@
 if [ ! "$_DEVICE_SUBR" ]; then _DEVICE_SUBR=1
 #
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -170,11 +170,10 @@ f_device_reset()
        for dev in $DEVICES; do
                f_device_shutdown $dev
 
-               #
-               # XXX this potentially leaks $dev->private if it's being
+               # XXX This potentially leaks $dev->private if it's being
                # used to point to something dynamic, but you're not supposed
                # to call this routine at such times that some open instance
-               # has its private member pointing somewhere anyway. XXX
+               # has its private member pointing somewhere anyway.
                #
                f_struct_free device_$dev
        done
@@ -325,8 +324,7 @@ f_device_get_all()
 
                case "$diskname" in
                cd*)
-                       # XXX
-                       #  Due to unknown reasons, kern.disks returns SCSI
+                       # XXX Due to unknown reasons, kern.disks returns SCSI
                        # CDROM as a valid disk. This will prevent bsdconfig
                        # from presenting SCSI CDROMs as available disks in
                        # various menus. Why GEOM treats SCSI CDROM as a disk

Modified: stable/10/usr.sbin/bsdconfig/share/dialog.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/dialog.subr      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/dialog.subr      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,6 +1,6 @@
 if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1
 #
-# Copyright (c) 2006-2013 Devin Teske
+# Copyright (c) 2006-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -469,16 +469,17 @@ f_dialog_menu_constrain()
        # Print debug warnings if any given (non-NULL) argument are invalid
        # NOTE: Don't change the name of $__{var,min,}{height,width,rows}
        #
-       local __height __width __rows
+       local __height_menu_constrain __width_menu_constrain
+       local __rows_menu_constrain
        local __arg __cp __fname=f_dialog_menu_constrain 
        for __arg in height width rows; do
                debug= f_getvar __var_$__arg __cp
                [ "$__cp" ] || continue
-               if ! debug= f_getvar "$__cp" __$__arg; then
+               if ! debug= f_getvar "$__cp" __${__arg}_menu_constrain; then
                        f_dprintf "%s: var_%s variable \`%s' not set" \
                                  $__fname $__arg "$__cp"
                        __retval=$FAILURE
-               elif ! eval f_isinteger \$__$__arg; then
+               elif ! eval f_isinteger \$__${__arg}_menu_constrain; then
                        f_dprintf "%s: var_%s variable value not a number" \
                                  $__fname $__arg
                        __retval=$FAILURE
@@ -502,9 +503,11 @@ f_dialog_menu_constrain()
 
        # Adjust height if desired
        if [ "$__var_height" ]; then
-               if [ $__height -lt ${__min_height:-0} ]; then
+               if [ $__height_menu_constrain -lt ${__min_height:-0} ]; then
                        setvar "$__var_height" $__min_height
-               elif [ $__height -gt $__max_height_menu_constrain ]; then
+               elif [ $__height_menu_constrain -gt \
+                      $__max_height_menu_constrain ]
+               then
                        setvar "$__var_height" $__max_height_menu_constrain
                fi
        fi
@@ -516,9 +519,11 @@ f_dialog_menu_constrain()
                else
                        : ${__min_width:=${DIALOG_MIN_WIDTH:-24}}
                fi
-               if [ $__width -lt $__min_width ]; then
+               if [ $__width_menu_constrain -lt $__min_width ]; then
                        setvar "$__var_width" $__min_width
-               elif [ $__width -gt $__max_width_menu_constrain ]; then
+               elif [ $__width_menu_constrain -gt \
+                      $__max_width_menu_constrain ]
+               then
                        setvar "$__var_width" $__max_width_menu_constrain
                fi
        fi
@@ -531,16 +536,20 @@ f_dialog_menu_constrain()
                        : ${__min_rows:=0}
                fi
 
-               local __max_rows=$(( $__max_height_menu_constrain - 7 ))
+               local __max_rows_menu_constrain=$((
+                       $__max_height_menu_constrain - 7
+               ))
                # If prompt_len is zero (no prompt), bump the max-rows by 1
                # Default assumption is (if no argument) that there's no prompt
-               [ ${__prompt_len:-0} -gt 0 ] ||
-                       __max_rows=$(( $__max_rows + 1 ))
+               [ ${__prompt_len:-0} -gt 0 ] || __max_rows_menu_constrain=$((
+                       $__max_rows_menu_constrain + 1
+               ))
 
-               if [ $__rows -lt $__min_rows ]; then
+               if [ $__rows_menu_constrain -lt $__min_rows ]; then
                        setvar "$__var_rows" $__min_rows
-               elif [ $__rows -gt $__max_rows ]; then
-                       setvar "$__var_rows" $__max_rows
+               elif [ $__rows_menu_constrain -gt $__max_rows_menu_constrain ]
+               then
+                       setvar "$__var_rows" $__max_rows_menu_constrain
                fi
        fi
 
@@ -1100,19 +1109,20 @@ f_dialog_radiolist_size()
        # longest item-length (both used to bump the width), and the number of
        # rows (used to bump the height).
        #
-       local __longest_tag=0 __longest_item=0 __rows=0
+       local __longest_tag=0 __longest_item=0 __rows_rlist_size=0
        while [ $# -ge 3 ]; do
                local __tag="$1" __item="$2"
                shift 3 # tag/item/status
                [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
                [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
-               __rows=$(( $__rows + 1 ))
+               __rows_rlist_size=$(( $__rows_rlist_size + 1 ))
        done
 
        # Adjust rows early (for up-coming height calculation)
        if [ "$__var_height" -o "$__var_rows" ]; then
                # Add a row for visual aid if using Xdialog(1)
-               [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 ))
+               [ "$USE_XDIALOG" ] &&
+                       __rows_rlist_size=$(( $__rows_rlist_size + 1 ))
        fi
 
        # Adjust height if desired
@@ -1120,10 +1130,12 @@ f_dialog_radiolist_size()
                # Add rows to height
                if [ "$USE_XDIALOG" ]; then
                        __height_rlist_size=$((
-                               $__height_rlist_size + $__rows + 7 ))
+                               $__height_rlist_size + $__rows_rlist_size + 7
+                       ))
                else
                        __height_rlist_size=$((
-                               $__height_rlist_size + $__rows + 4 ))
+                               $__height_rlist_size + $__rows_rlist_size + 4
+                       ))
                fi
                setvar "$__var_height" $__height_rlist_size
        fi
@@ -1140,7 +1152,7 @@ f_dialog_radiolist_size()
        fi
 
        # Store adjusted rows if desired
-       [ "$__var_rows" ] && setvar "$__var_rows" $__rows
+       [ "$__var_rows" ] && setvar "$__var_rows" $__rows_rlist_size
 
        # Constrain height, width, and rows to sensible minimum/maximum values
        # Return success if no-constrain, else return status from constrain
@@ -1220,20 +1232,26 @@ f_dialog_radiolist_with_help_size()
        # all used to bump the width -- and the number of rows (used to bump
        # the height).
        #
-       local __longest_tag=0 __longest_item=0 __longest_help=0 __rows=0
+       local __longest_tag=0 __longest_item=0 __longest_help=0
+       local __rows_rlist_with_help_size=0
        while [ $# -ge 4 ]; do
                local __tag="$1" __item="$2" __status="$3" __help="$4"
                shift 4 # tag/item/status/help
                [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
                [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
                [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help}
-               __rows=$(( $__rows + 1 ))
+               __rows_rlist_with_help_size=$((
+                       $__rows_rlist_with_help_size + 1
+               ))
        done
 
        # Adjust rows early (for up-coming height calculation)
        if [ "$__var_height" -o "$__var_rows" ]; then
                # Add a row for visual aid if using Xdialog(1)
-               [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 ))
+               [ "$USE_XDIALOG" ] &&
+                       __rows_rlist_with_help_size=$((
+                               $__rows_rlist_with_help_size + 1
+                       ))
        fi
 
        # Adjust height if desired
@@ -1241,10 +1259,14 @@ f_dialog_radiolist_with_help_size()
                # Add rows to height
                if [ "$USE_XDIALOG" ]; then
                        __height_rlist_with_help_size=$((
-                               $__height_rlist_with_help_size + $__rows + 7 ))
+                               $__height_rlist_with_help_size +
+                               $__rows_rlist_with_help_size + 7
+                       ))
                else
                        __height_rlist_with_help_size=$((
-                               $__height_rlist_with_help_size + $__rows + 4 ))
+                               $__height_rlist_with_help_size +
+                               $__rows_rlist_with_help_size + 4
+                       ))
                fi
                setvar "$__var_height" $__height
        fi
@@ -1270,7 +1292,7 @@ f_dialog_radiolist_with_help_size()
        fi
 
        # Store adjusted rows if desired
-       [ "$__var_rows" ] && setvar "$__var_rows" $__rows
+       [ "$__var_rows" ] && setvar "$__var_rows" $__rows_rlist_with_help_size
 
        # Constrain height, width, and rows to sensible minimum/maximum values
        # Return success if no-constrain, else return status from constrain

Modified: stable/10/usr.sbin/bsdconfig/share/keymap.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/keymap.subr      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/keymap.subr      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -165,7 +165,7 @@ f_keymap_get_all()
                        marks[keym] = mark
                        name = keym
                        gsub(/[^[:alnum:]_]/, "_", name)
-                       gsub(/'\''/, "'\''\\'\'''\''", desc);
+                       gsub(/'\''/, "'\''\\'\'\''", desc);
                        printf "f_keymap_checkfile %s && " \
                               "f_keymap_register %s '\'%s\'' %s %u\n",
                               keym, name, desc, keym, mark

Modified: stable/10/usr.sbin/bsdconfig/share/script.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/script.subr      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/script.subr      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,6 +1,6 @@
 if [ ! "$_SCRIPT_SUBR" ]; then _SCRIPT_SUBR=1
 #
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,8 @@ f_include $BSDCFG_SHARE/media/tcpip.subr
 f_include $BSDCFG_SHARE/mustberoot.subr
 f_include $BSDCFG_SHARE/networking/services.subr
 f_include $BSDCFG_SHARE/packages/packages.subr
+f_include $BSDCFG_SHARE/usermgmt/group.subr
+f_include $BSDCFG_SHARE/usermgmt/user.subr
 f_include $BSDCFG_SHARE/variable.subr
 
 ############################################################ GLOBALS
@@ -50,25 +52,23 @@ RESWORDS=
 # Create a new `reserved' word for scripting purposes. Reswords call pre-
 # defined functions but differ from those functions in the following ways:
 #
-#      + Reswords do not take arguments but instead get all their data from
-#        the environment variable namespace.
 #      + Unless noError is set (must be non-NULL), if calling the resword
 #        results in failure, the application will terminate prematurely.
 #      + noError is unset after each/every resword is called.
 #
 # Reswords should not be used in bsdconfig itself (hence the name `reserved
-# word') but instead only in scripts loaded through f_script_load()).
+# word') but instead only in scripts loaded through f_script_load().
 #
 f_resword_new()
 {
        local resword="$1" func="$2"
        [ "$resword" ] || return $FAILURE
        f_dprintf "script.subr: New resWord %s -> %s" "$resword" "$func"
-       eval $resword\(\){ f_dispatch $func $resword\; }
+       eval $resword\(\){ f_dispatch $func $resword \"\$@\"\; }
        RESWORDS="$RESWORDS${RESWORDS:+ }$resword"
 }
 
-# f_dispatch $func [$resword]
+# f_dispatch $func $resword
 #
 # Wrapper function used by `reserved words' (reswords) to call other functions.
 # If $noError is set and non-NULL, a failure result from $func is ignored,
@@ -78,9 +78,10 @@ f_resword_new()
 #
 f_dispatch()
 {
-       local func="$1" resword="${2:-$1}"
+       local func="$1" resword="$2"
+       shift 2 # func resword
        f_dprintf "f_dispatch: calling resword \`%s'" "$resword"
-       eval $func
+       eval $func "$@"
        local retval=$?
        if [ $retval -ne $SUCCESS ]; then
                local _ignore_this_error
@@ -96,7 +97,7 @@ f_dispatch()
 # Load a script (usually filled with reswords). If $file is missing or NULL,
 # use one of the following instead (in order):
 #
-#      $configFile
+#      $configFile (global)
 #      install.cfg
 #      /stand/install.fg
 #      /tmp/install.cfg
@@ -108,9 +109,10 @@ f_dispatch()
 #
 f_script_load()
 {
+       local funcname=f_script_load
        local script="$1" config_file retval=$SUCCESS
 
-       f_dprintf "f_script_load: script=[%s]" "$script"
+       f_dprintf "$funcname: script=[%s]" "$script"
        if [ ! "$script" ]; then
                f_getvar $VAR_CONFIG_FILE config_file
                for script in \
@@ -130,11 +132,11 @@ f_script_load()
        setvar $VAR_NONINTERACTIVE yes
 
        if [ "$script" = "-" ]; then
-               f_dprintf "f_script_load: Loading script from stdin"
+               f_dprintf "$funcname: Loading script from stdin"
                eval "$( cat )"
                retval=$?
        else
-               f_dprintf "f_script_load: Loading script \`%s'" "$script"
+               f_dprintf "$funcname: Loading script \`%s'" "$script"
                if [ ! -e "$script" ]; then
                        f_show_msg "$msg_unable_to_open" "$script"
                        return $FAILURE
@@ -198,6 +200,16 @@ f_resword_new packageAdd   f_package_add
 f_resword_new packageDelete    f_package_delete
 f_resword_new packageReinstall f_package_reinstall
 
+# usermgmt/group.subr
+f_resword_new addGroup         f_group_add
+f_resword_new deleteGroup      f_group_delete
+f_resword_new editGroup                f_group_edit
+
+# usermgmt/user.subr
+f_resword_new addUser          f_user_add
+f_resword_new deleteUser       f_user_delete
+f_resword_new editUser         f_user_edit
+
 # variable.subr
 f_resword_new installVarDefaults       f_variable_set_defaults
 f_resword_new dumpVariables            f_dump_variables

Modified: stable/10/usr.sbin/bsdconfig/share/strings.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/strings.subr     Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/strings.subr     Tue Apr  1 00:19:13 
2014        (r263980)
@@ -34,6 +34,12 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 ############################################################ GLOBALS
 
 #
+# A Literal newline (for use with f_replace_all(), or IFS, or whatever)
+#
+NL="
+" # END-QUOTE
+
+#
 # Valid characters that can appear in an sh(1) variable name
 #
 # Please note that the character ranges A-Z and a-z should be avoided because
@@ -189,7 +195,7 @@ f_number_of_lines()
 f_isinteger()
 {
        local arg="${1#-}"
-       [ "${arg:-x}" = "${arg#[!0-9]*}" ]
+       [ "${arg:-x}" = "${arg%[!0-9]*}" ]
 }
 
 # f_uriencode [$text]
@@ -265,6 +271,9 @@ f_uridecode()
 # capturing in a sub-shell (which is less recommended due to performance
 # degradation).
 #
+# To replace newlines or a sequence containing the newline character, use $NL
+# as `\n' is not supported.
+#
 f_replaceall()
 {
        local __left="" __right="$1"
@@ -372,14 +381,13 @@ f_expand_number()
        local __cp __num __bshift __maxinput
 
        # Remove any leading non-digits
-       while :; do
-               __cp="$__string"
-               __string="${__cp#[!0-9]}"
-               [ "$__string" = "$__cp" ] && break
-       done
+       __string="${__string#${__string%%[0-9]*}}"
+
+       # Store the numbers (no trailing suffix)
+       __num="${__string%%[!0-9]*}"
 
        # Produce `-1' if string didn't contain any digits
-       if [ ! "$__string" ]; then
+       if [ ! "$__num" ]; then
                if [ "$__var_to_set" ]; then
                        setvar "$__var_to_set" -1
                else
@@ -388,25 +396,8 @@ f_expand_number()
                return 1 # 1 = "Given $string contains no digits"
        fi
 
-       # Store the numbers
-       __num="${__string%%[!0-9]*}"
-
-       # Shortcut
-       if [ $__num -eq 0 ]; then
-               if [ "$__var_to_set" ]; then
-                       setvar "$__var_to_set" 0
-               else
-                       echo 0
-               fi
-               return $SUCCESS
-       fi
-
        # Remove all the leading numbers from the string to get at the prefix
-       while :; do
-               __cp="$__string"
-               __string="${__cp#[0-9]}"
-               [ "$__string" = "$__cp" ] && break
-       done
+       __string="${__string#"$__num"}"
 
        #
        # Test for invalid prefix (and determine bitshift length)

Modified: stable/10/usr.sbin/bsdconfig/share/variable.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/variable.subr    Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/share/variable.subr    Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,6 +1,6 @@
 if [ ! "$_VARIABLE_SUBR" ]; then _VARIABLE_SUBR=1
 #
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -241,6 +241,10 @@ f_variable_new VAR_FTP_PORT                ftpPort
 f_variable_new VAR_FTP_STATE           ftpState
 f_variable_new VAR_FTP_USER            ftpUser
 f_variable_new VAR_GATEWAY             defaultrouter
+f_variable_new VAR_GROUP               group
+f_variable_new VAR_GROUP_GID           groupGid
+f_variable_new VAR_GROUP_MEMBERS       groupMembers
+f_variable_new VAR_GROUP_PASSWORD      groupPassword
 f_variable_new VAR_HOSTNAME            hostname
 f_variable_new VAR_HTTP_DIR            httpDirectory
 f_variable_new VAR_HTTP_FTP_MODE       httpFtpMode
@@ -279,6 +283,21 @@ f_variable_new VAR_SLOW_ETHER              slowEther
 f_variable_new VAR_TRY_DHCP            tryDHCP
 f_variable_new VAR_TRY_RTSOL           tryRTSOL
 f_variable_new VAR_UFS_PATH            ufs
+f_variable_new VAR_USER                        user
+f_variable_new VAR_USER_ACCOUNT_EXPIRE userAccountExpire
+f_variable_new VAR_USER_DOTFILES_CREATE        userDotfilesCreate
+f_variable_new VAR_USER_GECOS          userGecos
+f_variable_new VAR_USER_GID            userGid
+f_variable_new VAR_USER_GROUPS         userGroups
+f_variable_new VAR_USER_GROUP_DELETE   userGroupDelete
+f_variable_new VAR_USER_HOME           userHome
+f_variable_new VAR_USER_HOME_CREATE    userHomeCreate
+f_variable_new VAR_USER_HOME_DELETE    userHomeDelete
+f_variable_new VAR_USER_LOGIN_CLASS    userLoginClass
+f_variable_new VAR_USER_PASSWORD       userPassword
+f_variable_new VAR_USER_PASSWORD_EXPIRE        userPasswordExpire
+f_variable_new VAR_USER_SHELL          userShell
+f_variable_new VAR_USER_UID            userUid
 f_variable_new VAR_ZFSINTERACTIVE      zfsInteractive
 
 #

Modified: stable/10/usr.sbin/bsdconfig/timezone/share/menus.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/timezone/share/menus.subr      Mon Mar 31 
21:04:15 2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/timezone/share/menus.subr      Tue Apr  1 
00:19:13 2014        (r263980)
@@ -104,7 +104,7 @@ f_make_menus_awk='
 function add_zone_n_to_country_menu(tlc, n)
 {
        zone_title = ENVIRON["country_" tlc "_descr_" n]
-       gsub(/'\''/, "'\''\\'\'''\''", zone_title)
+       gsub(/'\''/, "'\''\\'\'\''", zone_title)
        country_menu_list[tlc] = country_menu_list[tlc] \
                ( length(country_menu_list[tlc]) > 0 ? "\n" : "" ) \
                n " '\''" zone_title "'\''"
@@ -121,7 +121,7 @@ BEGIN {
        {
                tlc = countries[cp]
                title = ENVIRON["country_" tlc "_name"]
-               gsub(/'\''/, "'\''\\'\'''\''", title)
+               gsub(/'\''/, "'\''\\'\'\''", title)
                nzones = ENVIRON["country_" tlc "_nzones"]
                if (!nzones)
                {

Modified: stable/10/usr.sbin/bsdconfig/usermgmt/Makefile
==============================================================================
--- stable/10/usr.sbin/bsdconfig/usermgmt/Makefile      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/Makefile      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -8,8 +8,7 @@ FILESDIR=       ${LIBEXECDIR}/bsdconfig/070.us
 FILES=         INDEX USAGE
 
 SCRIPTSDIR=    ${FILESDIR}
-SCRIPTS=       groupadd groupdel groupedit groupinput \
-               useradd userdel useredit userinput usermgmt
+SCRIPTS=       groupadd groupdel groupedit useradd userdel useredit usermgmt
 
 beforeinstall:
        mkdir -p ${DESTDIR}${FILESDIR}

Modified: stable/10/usr.sbin/bsdconfig/usermgmt/groupadd
==============================================================================
--- stable/10/usr.sbin/bsdconfig/usermgmt/groupadd      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/groupadd      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #-
 # Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,11 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 . $BSDCFG_SHARE/common.subr || exit 1
 f_dprintf "%s: loading includes..." "$0"
 f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/mustberoot.subr
+f_include $BSDCFG_SHARE/usermgmt/group.subr
 
 BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
+f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
 
 f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
        pgm="${ipgm:-$pgm}"
@@ -55,9 +58,19 @@ done
 shift $(( $OPTIND - 1 ))
 
 #
-# Chain-load to groupinput to centralize code and minimize duplication
+# Initialize
 #
-$BSDCFG_LIBE/$APP_DIR/groupinput ${USE_XDIALOG:+-X} mode="Add"
+f_dialog_title "$msg_add $msg_group"
+f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
+f_mustberoot_init
+
+#
+# Add a group
+#
+# NB: If given an argument on the command-line use it; otherwise fall-back to
+#     environment variable $group (handle $VAR_GROUP).
+#
+f_group_add ${1:+"$1"}
 
 
################################################################################
 # END

Modified: stable/10/usr.sbin/bsdconfig/usermgmt/groupdel
==============================================================================
--- stable/10/usr.sbin/bsdconfig/usermgmt/groupdel      Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/groupdel      Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #-
 # Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 f_dprintf "%s: loading includes..." "$0"
 f_include $BSDCFG_SHARE/dialog.subr
 f_include $BSDCFG_SHARE/mustberoot.subr
+f_include $BSDCFG_SHARE/usermgmt/group.subr
 f_include $BSDCFG_SHARE/usermgmt/group_input.subr
 
 BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
@@ -65,9 +66,17 @@ f_dialog_backtitle "${ipgm:+bsdconfig }$
 f_mustberoot_init
 
 #
+# If given a group name, operate on it and exit
+#
+if [ "$1" ]; then
+       f_group_delete "$1"
+       exit $SUCCESS
+fi
+
+#
 # Loop until the user Exits, Cancels or presses ESC
 #
-defaultitem=""
+defaultitem=
 while :; do
        f_dialog_menu_group_list "$defaultitem"
        retval=$?
@@ -81,8 +90,7 @@ while :; do
 
        # Anything else is a group name
 
-       $BSDCFG_LIBE/$APP_DIR/groupinput \
-               ${USE_XDIALOG:+-X} mode="Delete" group="$mtag"
+       f_group_delete "$mtag"
 done
 
 exit $SUCCESS

Modified: stable/10/usr.sbin/bsdconfig/usermgmt/groupedit
==============================================================================
--- stable/10/usr.sbin/bsdconfig/usermgmt/groupedit     Mon Mar 31 21:04:15 
2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/groupedit     Tue Apr  1 00:19:13 
2014        (r263980)
@@ -1,7 +1,7 @@
 #!/bin/sh
 #-
 # Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
 f_dprintf "%s: loading includes..." "$0"
 f_include $BSDCFG_SHARE/dialog.subr
 f_include $BSDCFG_SHARE/mustberoot.subr
+f_include $BSDCFG_SHARE/usermgmt/group.subr
 f_include $BSDCFG_SHARE/usermgmt/group_input.subr
 
 BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
@@ -65,9 +66,17 @@ f_dialog_backtitle "${ipgm:+bsdconfig }$
 f_mustberoot_init
 
 #
-# Loop until the user Exits, Cancels or presses ESC
+# If given a group name, operate on it and exit
 #
-defaultitem=""
+if [ "$1" ]; then
+       f_group_edit "$1"
+       exit $SUCCESS
+fi
+
+#
+# Present a list of groups and loop until user Exits, Cancels or presses ESC
+#
+defaultitem=
 while :; do
        f_dialog_menu_group_list "$defaultitem"
        retval=$?
@@ -81,8 +90,7 @@ while :; do
 
        # Anything else is a group name
 
-       $BSDCFG_LIBE/$APP_DIR/groupinput \
-               ${USE_XDIALOG:+-X} mode="Edit/View" group="$mtag"
+       f_group_edit "$mtag"
 done
 
 exit $SUCCESS

Modified: stable/10/usr.sbin/bsdconfig/usermgmt/include/messages.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/usermgmt/include/messages.subr Mon Mar 31 
21:04:15 2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/include/messages.subr Tue Apr  1 
00:19:13 2014        (r263980)
@@ -1,5 +1,5 @@
 # Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2013 Devin Teske
+# Copyright (c) 2012-2014 Devin Teske
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@ hline_arrows_tab_enter="Press arrows, TA
 hline_num_arrows_tab_enter="Use numbers, arrows, TAB or ENTER"
 hline_num_tab_enter="Use numbers, TAB or ENTER"
 msg_account_does_not_expire="Account does not expire"
-msg_account_expires_in_how_many_days="Account expires in how many days?"
+msg_account_expire_manual_edit="Enter account expiration time. Format is one 
of:\n\n a) decimal for UNIX time since %s\n b) dd-mmm-yy[yy] for day, month, 
and 2- or 4-digit year\n c) +n[mhdwoy] for relative time from current 
date\n\nNOTE: Value of zero disables expiration."
 msg_account_expires_on="Account Expires on"
 msg_add="Add"
 msg_add_group="Add Group"
@@ -56,6 +56,7 @@ msg_edit_group="Edit/View Group"
 msg_edit_login="Edit/View Login"
 msg_edit_view="Edit/View"
 msg_enter_group_members_manually="Enter Group Members manually"
+msg_enter_groups_manually="Enter Groups manually"
 msg_enter_number_of_days_into_the_future="Enter number of days into the future"
 msg_enter_value_manually="Edit value manually"
 msg_error="ERROR!"
@@ -74,9 +75,8 @@ msg_group_not_found="%s: Group not found
 msg_group_password="Group Password"
 msg_group_passwords_do_not_match="Group Passwords do not match."
 msg_group_updated="Group Updated"
+msg_groups="Groups"
 msg_home_directory="Home Directory"
-msg_invalid_number_of_days="Invalid number of days."
-msg_invalid_number_of_seconds="Invalid number of seconds."
 msg_login="Login"
 msg_login_added="Login Added"
 msg_login_already_used="%s: Login is already used."
@@ -85,23 +85,28 @@ msg_login_deleted="Login Deleted"
 msg_login_is_empty="Login is empty."
 msg_login_management="Login/Group Management"
 msg_login_must_start_with_letter="Login must start with a letter."
-msg_login_not_found="Login not found."
+msg_login_not_found="%s: Login not found."
 msg_login_updated="Login Updated"
 msg_member_of_groups="Member of Groups"
 msg_n_a="N/A"
 msg_no="No"
+msg_no_group_specified="No group specified!"
+msg_no_user_specified="No user specified!"
 msg_number_of_seconds_since_epoch="Number of seconds since the Epoch\n(1 = 
%s)\nNULL or zero to disable:"
 msg_ok="OK"
 msg_password="Password"
 msg_password_does_not_expire="Password does not expire"
-msg_password_expires_in_how_many_days="Password expires in how many days?"
+msg_password_expire_manual_edit="Enter password expiration time. Format is one 
of:\n\n a) decimal for UNIX time since %s\n b) dd-mmm-yy[yy] for day, month, 
and 2- or 4-digit year\n c) +n[mhdwoy] for relative time from current 
date\n\nNOTE: Value of zero disables expiration."
 msg_password_expires_on="Password Expires on"
 msg_passwords_do_not_match="Passwords do not match."
+msg_please_enter_a_group_name="Please enter a group name!"
+msg_please_enter_a_user_name="Please enter a user name!"
 msg_reenter_group_password="Re-enter Group Password"
 msg_reenter_password="Re-enter Password"
 msg_save="Save"
 msg_save_exit_or_cancel="Choose Save/Exit when finished or Cancel."
 msg_select_group_members_from_list="Select Group Members from a list"
+msg_select_groups_from_list="Select Groups from a list"
 msg_select_login_shell="Select Login Shell"
 msg_separated_by_commas="Separated by commas"
 msg_shell="Shell"

Modified: stable/10/usr.sbin/bsdconfig/usermgmt/share/Makefile
==============================================================================
--- stable/10/usr.sbin/bsdconfig/usermgmt/share/Makefile        Mon Mar 31 
21:04:15 2014        (r263979)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/share/Makefile        Tue Apr  1 
00:19:13 2014        (r263980)
@@ -3,7 +3,7 @@
 NO_OBJ=
 
 FILESDIR=      ${SHAREDIR}/bsdconfig/usermgmt
-FILES=         group_input.subr user_input.subr
+FILES=         group.subr group_input.subr user.subr user_input.subr
 
 beforeinstall:
        mkdir -p ${DESTDIR}${FILESDIR}

Copied and modified: stable/10/usr.sbin/bsdconfig/usermgmt/share/group.subr 
(from r262904, head/usr.sbin/bsdconfig/usermgmt/share/group.subr)
==============================================================================
--- head/usr.sbin/bsdconfig/usermgmt/share/group.subr   Fri Mar  7 20:44:19 
2014        (r262904, copy source)
+++ stable/10/usr.sbin/bsdconfig/usermgmt/share/group.subr      Tue Apr  1 
00:19:13 2014        (r263980)
@@ -96,6 +96,10 @@ f_group_add()
                [ "$group_name" ] ||
                        f_show_err "$msg_please_enter_a_group_name"
        done
+       if [ ! "$group_name" ]; then
+               f_show_err "$msg_no_group_specified"
+               return $FAILURE
+       fi
 
        local group_password group_gid group_members
        f_getvar $VAR_GROUP_PASSWORD    group_password
@@ -152,10 +156,17 @@ f_group_add()
 
                        case "$mtag" in
                        X) # Add/Exit
-                          local cmd="pw groupadd -n '$group_name'"
-                          [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
+                          local var
+                          for var in gid members name; do
+                               local _group_$var
+                               eval f_shell_escape \
+                                       \"\$group_$var\" _group_$var
+                          done
+
+                          local cmd="pw groupadd -n '$_group_name'"
+                          [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
                           [ "$group_members" ] &&
-                               cmd="$cmd -M '$group_members'"
+                               cmd="$cmd -M '$_group_members'"
 
                           # Execute the command (break on success)
                           if [ "$group_password_disable" ]; then
@@ -163,7 +174,7 @@ f_group_add()
                           elif [ "$group_password" ]; then
                                echo "$group_password" |
                                        f_eval_catch $funcname \
-                                       pw '%s -h 0' "$cmd"
+                                               pw '%s -h 0' "$cmd"
                           else
                                f_eval_catch $funcname pw '%s' "$cmd"
                           fi && break
@@ -192,18 +203,24 @@ f_group_add()
                        esac
                done
        else
+               local var
+               for var in gid members name; do
+                       local _group_$var
+                       eval f_shell_escape \"\$group_$var\" _group_$var
+               done
+
                # Form the command
-               local cmd="pw groupadd -n '$group_name'"
-               [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
-               [ "$group_members" ] && cmd="$cmd -M '$group_members'"
+               local cmd="pw groupadd -n '$_group_name'"
+               [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
+               [ "$group_members" ] && cmd="$cmd -M '$_group_members'"
 
                # Execute the command
                local retval err
                if [ "$group_password_disable" ]; then
                        f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
                elif [ "$group_password" ]; then
-                       echo "$group_password" | f_eval_catch -k err \
-                               $funcname pw '%s -h 0' "$cmd"
+                       err=$( echo "$group_password" | f_eval_catch -de \
+                               $funcname pw '%s -h 0' "$cmd" 2>&1 )
                else
                        f_eval_catch -k err $funcname pw '%s' "$cmd"
                fi
@@ -217,7 +234,7 @@ f_group_add()
        f_dialog_title "$title"
        $alert "$msg_group_added"
        f_dialog_title_restore
-       [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2
+       [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
 
        return $SUCCESS
 }
@@ -272,8 +289,10 @@ f_group_delete()
 
                        case "$mtag" in
                        X) # Delete/Exit
+                          local _group_name
+                          f_shell_escape "$group_name" _group_name
                           f_eval_catch $funcname pw 'pw groupdel "%s"' \
-                                       "$group_name" && break
+                                       "$_group_name" && break
                           ;;
                        1) # Group Name (select different group from list)
                           f_dialog_menu_group_list "$group_name" || continue
@@ -292,9 +311,10 @@ f_group_delete()
                        esac
                done
        else
-               local retval err
+               local retval err _group_name
+               f_shell_escape "$group_name" _group_name
                f_eval_catch -k err $funcname pw \
-                       'pw groupdel "%s"' "$group_name"
+                       "pw groupdel '%s'" "$_group_name"
                retval=$?
                if [ $retval -ne $SUCCESS ]; then
                        f_show_err "%s" "$err"
@@ -305,7 +325,7 @@ f_group_delete()
         f_dialog_title "$title"
        $alert "$msg_group_deleted"
        f_dialog_title_restore
-       [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2
+       [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
 
        return $SUCCESS
 }
@@ -324,7 +344,9 @@ f_group_delete()
 #              unchanged.
 #      VAR_GROUP_MEMBERS [Optional]
 #              Comma separated list of users that are a member of this group.
-#              If NULL or unset, group membership is unmodified.
+#              If set but NULL, group memberships are reset (no users will be
+#              a member of this group). If unset, group membership is
+#              unmodified.
 #      VAR_GROUP_PASSWORD [Optional]
 #              newgrp(1) password to set for the group. If unset, the password
 #              is unmodified. If NULL, the newgrp(1) password is disabled.
@@ -400,18 +422,24 @@ f_group_edit()
 
                        case "$mtag" in
                        X) # Save/Exit
-                          local cmd="pw groupmod -n '$group_name'"
-                          [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
+                          local var
+                          for var in gid members name; do
+                               local _group_$var
+                               eval f_shell_escape \
+                                       \"\$group_$var\" _group_$var
+                          done
+
+                          local cmd="pw groupmod -n '$_group_name'"
+                          [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
                           [ "$group_members" -o "$null_members" ] &&
-                               cmd="$cmd -M '$group_members'"
+                               cmd="$cmd -M '$_group_members'"
 
                           # Execute the command (break on success)
                           if [ "$group_password_disable" ]; then
                                f_eval_catch $funcname pw '%s -h -' "$cmd"
                           elif [ "$group_password" ]; then
-                               echo "$group_password" |
-                                       f_eval_catch $funcname \
-                                               pw '%s -h 0' "$cmd"
+                               echo "$group_password" | f_eval_catch \
+                                       $funcname pw '%s -h 0' "$cmd"
                           else
                                f_eval_catch $funcname pw '%s' "$cmd"
                           fi && break
@@ -424,7 +452,7 @@ f_group_edit()
 
                           if ! f_input_group "$mtag"; then
                                f_show_err "$msg_group_not_found" "$mtag"
-                               # Attempt to fall back to prevoius selection
+                               # Attempt to fall back to previous selection
                                f_input_group "$input" || return $FAILURE
                           else
                                input="$mtag"
@@ -446,19 +474,25 @@ f_group_edit()
                        esac

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
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