1if [ ! "$_SYSRC_SUBR" ]; then _SYSRC_SUBR=1 2# 3# Copyright (c) 2006-2015 Devin Teske 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# 28############################################################ INCLUDES 29 30BSDCFG_SHARE="/usr/share/bsdconfig" 31[ "$_COMMON_SUBR" ] || . $BSDCFG_SHARE/common.subr || exit 1 32 33BSDCFG_LIBE="/usr/libexec/bsdconfig" 34if [ ! "$_SYSRC_JAILED" ]; then 35 f_dprintf "%s: loading includes..." sysrc.subr 36 f_include_lang $BSDCFG_LIBE/include/messages.subr 37fi 38 39############################################################ CONFIGURATION 40 41# 42# Standard pathnames (inherit values from shell if available) 43# 44: ${RC_DEFAULTS:="/etc/defaults/rc.conf"} 45 46############################################################ GLOBALS 47 48# 49# Global exit status variables 50# 51SUCCESS=0 52FAILURE=1 53 54# 55# Valid characters that can appear in an sh(1) variable name 56# 57# Please note that the character ranges A-Z and a-z should be avoided because 58# these can include accent characters (which are not valid in a variable name). 59# For example, A-Z matches any character that sorts after A but before Z, 60# including A and Z. Although ASCII order would make more sense, that is not 61# how it works. 62# 63VALID_VARNAME_CHARS="0-9ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" 64 65############################################################ FUNCTIONS 66 67# f_clean_env [ --except $varname ... ] 68# 69# Unset all environment variables in the current scope. An optional list of 70# arguments can be passed, indicating which variables to avoid unsetting; the 71# `--except' is required to enable the exclusion-list as the remainder of 72# positional arguments. 73# 74# Be careful not to call this in a shell that you still expect to perform 75# $PATH expansion in, because this will blow $PATH away. This is best used 76# within a sub-shell block "(...)" or "$(...)" or "`...`". 77# 78f_clean_env() 79{ 80 local var arg except= 81 82 # 83 # Should we process an exclusion-list? 84 # 85 if [ "$1" = "--except" ]; then 86 except=1 87 shift 1 88 fi 89 90 # 91 # Loop over a list of variable names from set(1) built-in. 92 # 93 for var in $( set | awk -F= \ 94 '/^[[:alpha:]_][[:alnum:]_]*=/ {print $1}' \ 95 | grep -v '^except$' 96 ); do 97 # 98 # In POSIX bourne-shell, attempting to unset(1) OPTIND results 99 # in "unset: Illegal number:" and causes abrupt termination. 100 # 101 [ "$var" = OPTIND ] && continue 102 103 # 104 # Process the exclusion-list? 105 # 106 if [ "$except" ]; then 107 for arg in "$@" ""; do 108 [ "$var" = "$arg" ] && break 109 done 110 [ "$arg" ] && continue 111 fi 112 113 unset "$var" 114 done 115} 116 117# f_sysrc_get $varname 118# 119# Get a system configuration setting from the collection of system- 120# configuration files (in order: /etc/defaults/rc.conf /etc/rc.conf and 121# /etc/rc.conf.local) 122# 123# NOTE: Additional shell parameter-expansion formats are supported. For 124# example, passing an argument of "hostname%%.*" (properly quoted) will 125# return the hostname up to (but not including) the first `.' (see sh(1), 126# "Parameter Expansion" for more information on additional formats). 127# 128f_sysrc_get() 129{ 130 # Sanity check 131 [ -f "$RC_DEFAULTS" -a -r "$RC_DEFAULTS" ] || return $FAILURE 132 133 # Taint-check variable name 134 case "$1" in 135 [0-9]*) 136 # Don't expand possible positional parameters 137 return $FAILURE ;; 138 *) 139 [ "$1" ] || return $FAILURE 140 esac 141 142 ( # Execute within sub-shell to protect parent environment 143 144 # 145 # Clear the environment of all variables, preventing the 146 # expansion of normals such as `PS1', `TERM', etc. 147 # 148 f_clean_env --except IFS RC_CONFS RC_DEFAULTS 149 150 . "$RC_DEFAULTS" > /dev/null 2>&1 151 152 unset RC_DEFAULTS 153 # no longer needed 154 155 # 156 # If the query is for `rc_conf_files' then store the value that 157 # we inherited from sourcing RC_DEFAULTS (above) so that we may 158 # conditionally restore this value after source_rc_confs in the 159 # event that RC_CONFS does not customize the value. 160 # 161 if [ "$1" = "rc_conf_files" ]; then 162 _rc_conf_files="$rc_conf_files" 163 fi 164 165 # 166 # If RC_CONFS is defined, set $rc_conf_files to an explicit 167 # value, modifying the default behavior of source_rc_confs(). 168 # 169 if [ "${RC_CONFS+set}" ]; then 170 rc_conf_files="$RC_CONFS" 171 _rc_confs_set=1 172 fi 173 174 source_rc_confs > /dev/null 2>&1 175 176 # 177 # If the query was for `rc_conf_files' AND after calling 178 # source_rc_confs the value has not changed, then we should 179 # restore the value to the one inherited from RC_DEFAULTS 180 # before performing the final query (preventing us from 181 # returning what was set via RC_CONFS when the intent was 182 # instead to query the value from the file(s) specified). 183 # 184 if [ "$1" = "rc_conf_files" -a \ 185 "$_rc_confs_set" -a \ 186 "$rc_conf_files" = "$RC_CONFS" \ 187 ]; then 188 rc_conf_files="$_rc_conf_files" 189 unset _rc_conf_files 190 unset _rc_confs_set 191 fi 192 193 unset RC_CONFS 194 # no longer needed 195 196 # 197 # This must be the last functional line for both the sub-shell 198 # and the function to preserve the return status from formats 199 # such as "${varname?}" and "${varname:?}" (see "Parameter 200 # Expansion" in sh(1) for more information). 201 # 202 eval printf "'%s\\n'" '"${'"$1"'}"' 2> /dev/null 203 ) 204} 205 206# f_sysrc_service_configs [-a|-p] $name [$var_to_set] 207# 208# Get a list of optional `rc.conf.d' entries sourced by system `rc.d' script 209# $name (see rc.subr(8) for additional information on `rc.conf.d'). If $name 210# exists in `/etc/rc.d' or $local_startup directories and is an rc(8) script 211# the result is a space separated list of `rc.conf.d' entries sourced by the 212# $name `rc.d' script. Otherwise, if $name exists as a binary `rc.d' script, 213# the result is ``/etc/rc.conf.d/$name /usr/local/etc/rc.conf.d/$name''. The 214# result is NULL if $name does not exist. 215# 216# If $var_to_set is missing or NULL, output is to standard out. Returns success 217# if $name was found, failure otherwise. 218# 219# If `-a' flag is given and $var_to_set is non-NULL, append result to value of 220# $var_to_set rather than overwriting current contents. 221# 222# If `-p' flag is given and $var_to_set is non-NULL, prepend result to value of 223# $var_to_set rather than overwriting current contents. 224# 225# NB: The `-a' and `-p' option flags are mutually exclusive. 226# 227f_sysrc_service_configs() 228{ 229 local OPTIND=1 OPTARG __flag __append= __prepend= 230 local __local_startup __dir __spath __stype __names= 231 232 while getopts ap __flag; do 233 case "$__flag" in 234 a) __append=1 __prepend= ;; 235 p) __prepend=1 __append= ;; 236 esac 237 done 238 shift $(( $OPTIND - 1 )) 239 240 [ $# -gt 0 ] || return $FAILURE 241 local __sname="$1" __var_to_set="$2" 242 243 __local_startup=$( f_sysrc_get local_startup ) 244 for __dir in /etc/rc.d $__local_startup; do 245 __spath="$__dir/$__sname" 246 [ -f "$__spath" -a -x "$__spath" ] || __spath= continue 247 break 248 done 249 [ "$__spath" ] || return $FAILURE 250 251 __stype=$( file -b "$__spath" 2> /dev/null ) 252 case "$__stype" in 253 *"shell script"*) 254 __names=$( exec 9<&1 1>&- 2>&- 255 last_name= 256 print_name() { 257 local name="$1" 258 case "$name" in 259 ""|.|..|*/*|"$last_name") return ;; 260 esac 261 echo "$name" >&9 262 last_name="$name" 263 } 264 eval "$( awk '{ 265 gsub(/load_rc_config /, "print_name ") 266 gsub(/run_rc_command /, ": ") 267 print 268 }' "$__spath" )" 269 ) ;; 270 *) 271 __names="$__sname" 272 esac 273 274 local __name __test_path __configs= 275 for __name in $__names; do 276 for __dir in /etc/rc.d $__local_startup; do 277 __test_path="${__dir%/rc.d}/rc.conf.d/$__name" 278 [ -d "$__test_path" ] || 279 __configs="$__configs $__test_path" continue 280 for __test_path in "$__test_path"/*; do 281 [ -f "$__test_path" ] || continue 282 __configs="$__configs $__test_path" 283 done 284 done 285 done 286 __configs="${__configs# }" 287 288 if [ "$__var_to_set" ]; then 289 local __cur= 290 [ "$__append" -o "$__prepend" ] && 291 f_getvar "$__var_to_set" __cur 292 [ "$__append" ] && __configs="$__cur{$__cur:+ }$__configs" 293 [ "$__prepend" ] && __configs="$__configs${__cur:+ }$__cur" 294 setvar "$__var_to_set" "$__configs" 295 else 296 echo "$__configs" 297 fi 298 299 return $SUCCESS 300} 301 302# f_sysrc_get_default $varname 303# 304# Get a system configuration default setting from the default rc.conf(5) file 305# (or whatever RC_DEFAULTS points at). 306# 307f_sysrc_get_default() 308{ 309 # Sanity check 310 [ -f "$RC_DEFAULTS" -a -r "$RC_DEFAULTS" ] || return $FAILURE 311 312 # Taint-check variable name 313 case "$1" in 314 [0-9]*) 315 # Don't expand possible positional parameters 316 return $FAILURE ;; 317 *) 318 [ "$1" ] || return $FAILURE 319 esac 320 321 ( # Execute within sub-shell to protect parent environment 322 323 # 324 # Clear the environment of all variables, preventing the 325 # expansion of normals such as `PS1', `TERM', etc. 326 # 327 f_clean_env --except RC_DEFAULTS 328 329 . "$RC_DEFAULTS" > /dev/null 2>&1 330 331 unset RC_DEFAULTS 332 # no longer needed 333 334 # 335 # This must be the last functional line for both the sub-shell 336 # and the function to preserve the return status from formats 337 # such as "${varname?}" and "${varname:?}" (see "Parameter 338 # Expansion" in sh(1) for more information). 339 # 340 eval printf "'%s\\n'" '"${'"$1"'}"' 2> /dev/null 341 ) 342} 343 344# f_sysrc_find $varname 345# 346# Find which file holds the effective last-assignment to a given variable 347# within the rc.conf(5) file(s). 348# 349# If the variable is found in any of the rc.conf(5) files, the function prints 350# the filename it was found in and then returns success. Otherwise output is 351# NULL and the function returns with error status. 352# 353f_sysrc_find() 354{ 355 local varname="${1%%[!$VALID_VARNAME_CHARS]*}" 356 local regex="^[[:space:]]*$varname=" 357 local rc_conf_files="$( f_sysrc_get rc_conf_files )" 358 local conf_files= 359 local file 360 361 # Check parameters 362 case "$varname" in 363 ""|[0-9]*) return $FAILURE 364 esac 365 366 # 367 # If RC_CONFS is defined, set $rc_conf_files to an explicit 368 # value, modifying the default behavior of source_rc_confs(). 369 # 370 [ "${RC_CONFS+set}" ] && rc_conf_files="$RC_CONFS" 371 372 # 373 # Reverse the order of files in rc_conf_files (the boot process sources 374 # these in order, so we will search them in reverse-order to find the 375 # last-assignment -- the one that ultimately effects the environment). 376 # 377 for file in $rc_conf_files; do 378 conf_files="$file${conf_files:+ }$conf_files" 379 done 380 381 # 382 # Append the defaults file (since directives in the defaults file 383 # indeed affect the boot process, we'll want to know when a directive 384 # is found there). 385 # 386 conf_files="$conf_files${conf_files:+ }$RC_DEFAULTS" 387 388 # 389 # Find which file matches assignment to the given variable name. 390 # 391 for file in $conf_files; do 392 [ -f "$file" -a -r "$file" ] || continue 393 if grep -Eq "$regex" $file; then 394 echo $file 395 return $SUCCESS 396 fi 397 done 398 399 return $FAILURE # Not found 400} 401 402# f_sysrc_desc $varname 403# 404# Attempts to return the comments associated with varname from the rc.conf(5) 405# defaults file `/etc/defaults/rc.conf' (or whatever RC_DEFAULTS points to). 406# 407# Multi-line comments are joined together. Results are NULL if no description 408# could be found. 409# 410# This function is a two-parter. Below is the awk(1) portion of the function, 411# afterward is the sh(1) function which utilizes the below awk script. 412# 413f_sysrc_desc_awk=' 414# Variables that should be defined on the invocation line: 415# -v varname="varname" 416# 417BEGIN { 418 regex = "^[[:space:]]*"varname"=" 419 found = 0 420 buffer = "" 421} 422{ 423 if ( ! found ) 424 { 425 if ( ! match($0, regex) ) next 426 427 found = 1 428 sub(/^[^#]*(#[[:space:]]*)?/, "") 429 buffer = $0 430 next 431 } 432 433 if ( !/^[[:space:]]*#/ || 434 /^[[:space:]]*[[:alpha:]_][[:alnum:]_]*=/ || 435 /^[[:space:]]*#[[:alpha:]_][[:alnum:]_]*=/ || 436 /^[[:space:]]*$/ ) exit 437 438 sub(/(.*#)*[[:space:]]*/, "") 439 buffer = buffer" "$0 440} 441END { 442 # Clean up the buffer 443 sub(/^[[:space:]]*/, "", buffer) 444 sub(/[[:space:]]*$/, "", buffer) 445 446 print buffer 447 exit ! found 448} 449' 450f_sysrc_desc() 451{ 452 awk -v varname="$1" "$f_sysrc_desc_awk" < "$RC_DEFAULTS" 453} 454 455# f_sysrc_set $varname $new_value 456# 457# Change a setting in the system configuration files (edits the files in-place 458# to change the value in the last assignment to the variable). If the variable 459# does not appear in the source file, it is appended to the end of the primary 460# system configuration file `/etc/rc.conf'. 461# 462# This function is a two-parter. Below is the awk(1) portion of the function, 463# afterward is the sh(1) function which utilizes the below awk script. 464# 465f_sysrc_set_awk=' 466# Variables that should be defined on the invocation line: 467# -v varname="varname" 468# -v new_value="new_value" 469# 470BEGIN { 471 regex = "^[[:space:]]*"varname"=" 472 found = retval = 0 473} 474{ 475 # If already found... just spew 476 if ( found ) { print; next } 477 478 # Does this line match an assignment to our variable? 479 if ( ! match($0, regex) ) { print; next } 480 481 # Save important match information 482 found = 1 483 matchlen = RSTART + RLENGTH - 1 484 485 # Store the value text for later munging 486 value = substr($0, matchlen + 1, length($0) - matchlen) 487 488 # Store the first character of the value 489 t1 = t2 = substr(value, 0, 1) 490 491 # Assignment w/ back-ticks, expression, or misc. 492 # We ignore these since we did not generate them 493 # 494 if ( t1 ~ /[`$\\]/ ) { retval = 1; print; next } 495 496 # Assignment w/ single-quoted value 497 else if ( t1 == "'\''" ) { 498 sub(/^'\''[^'\'']*/, "", value) 499 if ( length(value) == 0 ) t2 = "" 500 sub(/^'\''/, "", value) 501 } 502 503 # Assignment w/ double-quoted value 504 else if ( t1 == "\"" ) { 505 sub(/^"(.*\\\\+")*[^"]*/, "", value) 506 if ( length(value) == 0 ) t2 = "" 507 sub(/^"/, "", value) 508 } 509 510 # Assignment w/ non-quoted value 511 else if ( t1 ~ /[^[:space:];]/ ) { 512 t1 = t2 = "\"" 513 sub(/^[^[:space:]]*/, "", value) 514 } 515 516 # Null-assignment 517 else if ( t1 ~ /[[:space:];]/ ) { t1 = t2 = "\"" } 518 519 printf "%s%c%s%c%s\n", substr($0, 0, matchlen), \ 520 t1, new_value, t2, value 521} 522END { exit retval } 523' 524f_sysrc_set() 525{ 526 local funcname=f_sysrc_set 527 local varname="$1" new_value="$2" 528 529 # Check arguments 530 [ "$varname" ] || return $FAILURE 531 532 # 533 # Find which rc.conf(5) file contains the last-assignment 534 # 535 local not_found= 536 local file="$( f_sysrc_find "$varname" )" 537 if [ "$file" = "$RC_DEFAULTS" -o ! "$file" ]; then 538 # 539 # We either got a null response (not found) or the variable 540 # was only found in the rc.conf(5) defaults. In either case, 541 # let's instead modify the first file from $rc_conf_files. 542 # 543 544 not_found=1 545 546 # 547 # If RC_CONFS is defined, use $RC_CONFS 548 # rather than $rc_conf_files. 549 # 550 if [ "${RC_CONFS+set}" ]; then 551 file="${RC_CONFS%%[$IFS]*}" 552 else 553 file=$( f_sysrc_get 'rc_conf_files%%[$IFS]*' ) 554 fi 555 fi 556 557 # 558 # If not found, append new value to first file and return. 559 # 560 if [ "$not_found" ]; then 561 # Add a newline if missing before appending to the file 562 [ ! -e "$file" ] || awk 'BEGIN { wc = 0 } NR == 1 { 563 (cmd = "wc -l " FILENAME) | getline 564 close(cmd) 565 wc = $1 566 } END { exit wc != NR }' "$file" || 567 echo >> "$file" || return $? 568 echo "$varname=\"$new_value\"" >> "$file" 569 return $? 570 fi 571 572 # 573 # Perform sanity checks. 574 # 575 if [ ! -w "$file" ]; then 576 f_err "$msg_cannot_create_permission_denied\n" \ 577 "$pgm" "$file" 578 return $FAILURE 579 fi 580 581 # 582 # Create a new temporary file to write to. 583 # 584 local tmpfile 585 if ! f_eval_catch -dk tmpfile $funcname mktemp 'mktemp -t "%s"' "$pgm" 586 then 587 echo "$tmpfile" >&2 588 return $FAILURE 589 fi 590 591 # 592 # Fixup permissions (else we're in for a surprise, as mktemp(1) creates 593 # the temporary file with 0600 permissions, and if we simply mv(1) the 594 # temporary file over the destination, the destination will inherit the 595 # permissions from the temporary file). 596 # 597 local mode 598 f_eval_catch -dk mode $funcname stat 'stat -f "%%#Lp" "%s"' "$file" || 599 mode=0644 600 f_eval_catch -d $funcname chmod 'chmod "%s" "%s"' "$mode" "$tmpfile" 601 602 # 603 # Fixup ownership. The destination file _is_ writable (we tested 604 # earlier above). However, this will fail if we don't have sufficient 605 # permissions (so we throw stderr into the bit-bucket). 606 # 607 local owner 608 f_eval_catch -dk owner $funcname stat \ 609 'stat -f "%%u:%%g" "%s"' "$file" || owner="root:wheel" 610 f_eval_catch -d $funcname chown 'chown "%s" "%s"' "$owner" "$tmpfile" 611 612 # 613 # Operate on the matching file, replacing only the last occurrence. 614 # 615 # Use awk to ensure LF at end of each line, else files without ending 616 # LF will trigger a bug in `tail -r' where last two lines are joined. 617 # 618 local new_contents retval 619 new_contents=$( awk 1 "$file" 2> /dev/null | tail -r ) 620 new_contents=$( echo "$new_contents" | awk -v varname="$varname" \ 621 -v new_value="$new_value" "$f_sysrc_set_awk" ) 622 retval=$? 623 624 # 625 # Write the temporary file contents. 626 # 627 echo "$new_contents" | tail -r > "$tmpfile" || return $FAILURE 628 if [ $retval -ne $SUCCESS ]; then 629 echo "$varname=\"$new_value\"" >> "$tmpfile" 630 fi 631 632 # 633 # Taint-check our results. 634 # 635 if ! f_eval_catch -d $funcname sh '/bin/sh -n "%s"' "$tmpfile"; then 636 f_err "$msg_previous_syntax_errors\n" "$pgm" "$file" 637 rm -f "$tmpfile" 638 return $FAILURE 639 fi 640 641 # 642 # Finally, move the temporary file into place. 643 # 644 f_eval_catch -de $funcname mv 'mv "%s" "%s"' "$tmpfile" "$file" 645} 646 647# f_sysrc_delete $varname 648# 649# Remove a setting from the system configuration files (edits files in-place). 650# Deletes all assignments to the given variable in all config files. If the 651# `-f file' option is passed, the removal is restricted to only those files 652# specified, otherwise the system collection of rc_conf_files is used. 653# 654# This function is a two-parter. Below is the awk(1) portion of the function, 655# afterward is the sh(1) function which utilizes the below awk script. 656# 657f_sysrc_delete_awk=' 658# Variables that should be defined on the invocation line: 659# -v varname="varname" 660# 661BEGIN { 662 regex = "^[[:space:]]*"varname"=" 663 found = 0 664} 665{ 666 if ( $0 ~ regex ) 667 found = 1 668 else 669 print 670} 671END { exit ! found } 672' 673f_sysrc_delete() 674{ 675 local funcname=f_sysrc_delete 676 local varname="$1" 677 local file 678 679 # Check arguments 680 [ "$varname" ] || return $FAILURE 681 682 # 683 # Operate on each of the specified files 684 # 685 local tmpfile 686 for file in ${RC_CONFS-$( f_sysrc_get rc_conf_files )}; do 687 [ -e "$file" ] || continue 688 689 # 690 # Create a new temporary file to write to. 691 # 692 if ! f_eval_catch -dk tmpfile $funcname mktemp \ 693 'mktemp -t "%s"' "$pgm" 694 then 695 echo "$tmpfile" >&2 696 return $FAILURE 697 fi 698 699 # 700 # Fixup permissions and ownership (mktemp(1) defaults to 0600 701 # permissions) to instead match the destination file. 702 # 703 local mode owner 704 f_eval_catch -dk mode $funcname stat \ 705 'stat -f "%%#Lp" "%s"' "$file" || mode=0644 706 f_eval_catch -dk owner $funcname stat \ 707 'stat -f "%%u:%%g" "%s"' "$file" || owner="root:wheel" 708 f_eval_catch -d $funcname chmod \ 709 'chmod "%s" "%s"' "$mode" "$tmpfile" 710 f_eval_catch -d $funcname chown \ 711 'chown "%s" "%s"' "$owner" "$tmpfile" 712 713 # 714 # Operate on the file, removing all occurrences, saving the 715 # output in our temporary file. 716 # 717 awk -v varname="$varname" "$f_sysrc_delete_awk" "$file" \ 718 > "$tmpfile" 719 if [ $? -ne $SUCCESS ]; then 720 # The file didn't contain any assignments 721 rm -f "$tmpfile" 722 continue 723 fi 724 725 # 726 # Taint-check our results. 727 # 728 if ! f_eval_catch -d $funcname sh '/bin/sh -n "%s"' "$tmpfile" 729 then 730 f_err "$msg_previous_syntax_errors\n" \ 731 "$pgm" "$file" 732 rm -f "$tmpfile" 733 return $FAILURE 734 fi 735 736 # 737 # Perform sanity checks 738 # 739 if [ ! -w "$file" ]; then 740 f_err "$msg_permission_denied\n" "$pgm" "$file" 741 rm -f "$tmpfile" 742 return $FAILURE 743 fi 744 745 # 746 # Finally, move the temporary file into place. 747 # 748 f_eval_catch -de $funcname mv \ 749 'mv "%s" "%s"' "$tmpfile" "$file" || return $FAILURE 750 done 751} 752 753############################################################ MAIN 754 755f_dprintf "%s: Successfully loaded." sysrc.subr 756 757fi # ! $_SYSRC_SUBR 758