]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bsdconfig/bsdconfig
Update libarchive to 3.0.4
[FreeBSD/FreeBSD.git] / usr.sbin / bsdconfig / bsdconfig
1 #!/bin/sh
2 #-
3 # Copyright (c) 2012 Ron McDowell
4 # Copyright (c) 2012 Devin Teske
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27 #
28 # $FreeBSD$
29 #
30 ############################################################ INCLUDES
31
32 BSDCFG_LIBE="/usr/libexec/bsdconfig"
33 . $BSDCFG_LIBE/include/common.subr || exit 1
34 f_include $BSDCFG_LIBE/include/dialog.subr
35 f_include $BSDCFG_LIBE/include/mustberoot.subr
36 f_include $BSDCFG_LIBE/include/strings.subr
37 f_include_lang $BSDCFG_LIBE/include/messages.subr
38
39 ############################################################ FUNCTIONS
40
41 # usage
42 #
43 # display usage and exit
44 #
45 usage()
46 {
47         local index="INDEX" cmd_list=""
48
49         cd $BSDCFG_LIBE
50
51         # Test for language-specific indices
52         f_quietly ls */"$index.${LANG:-$LC_ALL}" &&
53                 index="$index.${LANG:-$LC_ALL}"
54
55         cmd_list=$(
56                 awk '/^menu_selection="/ {
57                         sub(/\|.*/, "")
58                         sub(/^menu_selection="/, "")
59                         print
60                 }' */$index | sort
61         )
62
63         #
64         # Determine the longest command-length (in characters)
65         #
66         local longest_cmd
67         longest_cmd=$( echo "$cmd_list" | f_longest_line_length )
68         f_dprintf "longest_cmd=[$longest_cmd]"
69
70         #
71         # Determine the maximum width of terminal/console
72         #
73         local max_size max_width
74         max_size=$( stty size 2> /dev/null )
75         : ${max_size:="24 80"}
76         max_width="${max_size#*[$IFS]}"
77         f_dprintf "max_width=[$max_width]"
78
79         #
80         # Using the longest command-length as the width of a single column,
81         # determine if we can use more than one column to display commands.
82         #
83         local x=$longest_cmd ncols=1
84         x=$(( $x + 8 )) # Accomodate leading tab character
85         x=$(( $x + 3 + $longest_cmd )) # Preload end of next column
86         while [ $x -lt $max_width ]; do
87                 ncols=$(( $ncols + 1 ))
88                 x=$(( $x + 3 + $longest_cmd ))
89         done
90         f_dprintf "ncols=[$ncols] x=[$x]"
91
92         #
93         # Re-format the command-list into multiple columns
94         #
95         cmd_list=$( eval "$( echo "$cmd_list" |
96                 awk -v ncols=$ncols -v size=$longest_cmd '
97                 BEGIN {
98                         n = 0
99                         row_item[1] = ""
100                 }
101                 function print_row()
102                 {
103                         fmt = "printf \"\\t%-" size "s"
104                         for (i = 1; i < cur_col; i++)
105                                 fmt = fmt "   %-" size "s"
106                         fmt = fmt "\\n\""
107                         printf "%s", fmt
108                         for (i = 1; i <= cur_col; i++)
109                                 printf " \"%s\"", row_item[i]
110                         print ""
111                 }
112                 {
113                         n++
114                         cur_col = (( n - 1 ) % ncols ) + 1
115                         printf "f_dprintf \"row_item[%u]=[%s]\"\n", cur_col, $0
116                         row_item[cur_col] = $0
117                         if ( cur_col == ncols ) print_row()
118                 }
119                 END {
120                         if ( cur_col < ncols ) print_row()
121                 }' )"
122         )
123
124         f_usage $BSDCFG_LIBE/USAGE \
125                 "PROGRAM_NAME" "$pgm" \
126                 "COMMAND_LIST" "$cmd_list"
127 }
128
129 # dialog_menu_main
130 #
131 # Display the dialog(1)-based application main menu.
132 #
133 dialog_menu_main()
134 {
135         local title="$DIALOG_TITLE"
136         local btitle="$DIALOG_BACKTITLE"
137         local prompt="$msg_menu_text"
138         local menu_list size
139
140         menu_list="
141                 'X' '$msg_exit' '$msg_exit_bsdconfig'
142         " # END-QUOTE
143
144         local sanitize_awk="{ gsub(/'/, \"'\\\\''\"); print }"
145
146         local menuitem menu_title menu_help menu_selection index=1
147         for menuitem in $( ls -d [0-9][0-9][0-9].* ); do
148                 [ $index -lt ${#DIALOG_MENU_TAGS} ] || break
149                 tag=$( f_substr "$DIALOG_MENU_TAGS" $index 1 )
150
151                 menu_program=
152                 menu_title=
153                 menu_help=
154                 f_include_lang $menuitem/INDEX
155                 [ "$menu_program" ] || continue
156
157                 case "$menu_program" in
158                 /*) : already fully qualified ;;
159                 *)
160                         menu_program="$menuitem/$menu_program"
161                 esac
162
163                 menu_title=$( echo "$menu_title" | awk "$sanitize_awk" )
164                 menu_help=$( echo "$menu_help" | awk "$sanitize_awk" )
165                 setvar "menu_program$tag" "$menu_program"
166                 menu_list="$menu_list '$tag' '$menu_title' '$menu_help'"
167
168                 index=$(( $index + 1 ))
169         done
170
171         size=$( eval f_dialog_menu_with_help_size \
172                         \"\$title\"  \
173                         \"\$btitle\" \
174                         \"\$prompt\" \
175                         \"\"         \
176                         $menu_list   )
177
178         eval $DIALOG \
179                 --clear                                 \
180                 --title \"\$title\"                     \
181                 --backtitle \"\$btitle\"                \
182                 --item-help                             \
183                 --ok-label \"\$msg_ok\"                 \
184                 --cancel-label \"\$msg_exit_bsdconfig\" \
185                 --menu \"\$prompt\" $size $menu_list    \
186                 2> "$DIALOG_TMPDIR/dialog.menu.$$"
187 }
188
189 ############################################################ MAIN
190
191 #
192 # Process command-line arguments
193 #
194 while getopts hSX flag; do
195         case "$flag" in
196         h|\?) usage;;
197         esac
198 done
199 shift $(( $OPTIND -1 ))
200
201 #
202 # Initialize
203 #
204 f_dialog_init
205 f_dialog_title "$msg_main_menu"
206
207 [ "$SECURE" ] && f_mustberoot_init
208
209 # Incorporate rc-file if it exists
210 [ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
211
212 #
213 # Log our operating environment for debugging purposes
214 #
215 export UNAME_S="$(uname -s)" # Operating System (i.e. FreeBSD)
216 export UNAME_P="$(uname -p)" # Processor Architecture (i.e. i386)
217 export UNAME_R="$(uname -r)" # Release Level (i.e. X.Y-RELEASE)
218 f_dprintf "UNAME_S=[$UNAME_S] UNAME_P=[$UNAME_P] UNAME_R=[$UNAME_R]"
219
220 cd $BSDCFG_LIBE || f_die 1 "$msg_directory_not_found" "$BSDCFG_LIBE"
221
222 #
223 # If a non-option argument was passed, process it as a menuitem selection...
224 #
225 if [ "$1" ]; then
226         #
227         # ...unless it's a long-option for usage.
228         #
229         case "$1" in
230         -help|--help|-\?) usage;;
231         esac
232
233         #
234         # Find the INDEX (possibly i18n) claiming this keyword
235         #
236         lang="${LANG:-$LC_ALL}"
237         if [ "$lang" ]; then
238                 sel=$( grep "^menu_selection=\"$1|" */INDEX.$lang \
239                                 2> /dev/null | tail -1 )
240
241                 # Fall-back to non-i18n sources if nothing was found
242                 [ "$sel" ] ||
243                         sel=$( grep "^menu_selection=\"$1|" */INDEX | tail -1 )
244         else
245                 sel=$( grep "^menu_selection=\"$1|" */INDEX | tail -1 )
246         fi
247
248         #
249         # If no matches, display usage (which shows valid keywords)
250         #
251         if [ ! "$sel" ]; then
252                 f_err "%s: %s: $msg_not_found\n" "$pgm" "$1"
253                 usage
254         fi
255
256         #
257         # The command to execute is after the pipe-character (|) in the
258         # menu_selection property of the INDEX file for the menuitem.
259         #
260         cmd="${sel#*|}"
261         cmd="${cmd%\"}"
262         if [ ! "$cmd" ]; then
263                 echo "$pgm: $1: $msg_not_found"
264                 usage
265         fi
266         shift
267
268         #
269         # If the command pathname is not fully qualified fix-up/force to be
270         # relative to the menuitem directory.
271         #
272         case "$cmd" in
273         /*) : already fully qualified ;;
274         *)
275                 dir="${sel%%/*}"
276                 cmd="$dir/$cmd"
277         esac
278
279         exec $cmd ${USE_XDIALOG:+-X} "$@" || exit 1
280 fi
281
282 [ -f "$HOME/.bsdconfigrc" ] || f_dialog_msgbox "$msg_help_text"
283
284 #
285 # Launch application main menu
286 #
287 while :; do
288         dialog_menu_main
289         retval=$?
290         mtag=$( f_dialog_menutag )
291         f_dprintf "retval=$retval mtag=[$mtag]"
292
293         [ $retval -eq 0 ] || f_die
294
295         case "$mtag" in
296         X) # Exit
297            break
298            ;;
299
300         *) # Dynamically loaded menuitem
301            cmd=$( eval echo \"\$menu_program$mtag\" )
302            f_dprintf "cmd=[$cmd]"
303            $cmd ${USE_XDIALOG:+-X}
304            ;;
305
306         esac
307 done
308
309 exit $SUCCESS
310
311 ################################################################################
312 # END
313 ################################################################################