2 # I, Ian Kelling, follow the GNU license recommendations at
3 # https://www.gnu.org/licenses/license-recommendations.en.html. They
4 # recommend that small programs, < 300 lines, be licensed under the
5 # Apache License 2.0. This file contains or is part of one or more small
6 # programs. If a small program grows beyond 300 lines, I plan to switch
9 # Copyright 2024 Ian Kelling
11 # Licensed under the Apache License, Version 2.0 (the "License");
12 # you may not use this file except in compliance with the License.
13 # You may obtain a copy of the License at
15 # http://www.apache.org/licenses/LICENSE-2.0
17 # Unless required by applicable law or agreed to in writing, software
18 # distributed under the License is distributed on an "AS IS" BASIS,
19 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 # See the License for the specific language governing permissions and
21 # limitations under the License.
24 local help="Usage: [-h|--help ] [-v] [SECTION_NAME] FILE
25 Create/modify a comment-delimited section in a config file
27 Returns 1 if the file is modified by this command, 2 or higher
30 The section is #comment delimited. Reads STDIN for the contents of the
31 section. Without SECTION_NAME, it acts on a global unnamed
32 section. cedit is short for config edit.
35 -e Exit 0 on modified file.
36 -s Silent. Quiet and exit 0 on modified file.
40 local s
diff name init file_dir exists verbose backup quiet silent
41 file_dir
="$(dirname "$file")"
50 -b) backup
=true
; shift ;;
51 -e) exit_status
=false
; shift ;;
52 -s) quiet
=true
; silent
=true
; exit_status
=false
; shift ;;
53 -q) quiet
=true
; shift ;;
54 -v) verbose
=true
; shift ;;
55 -h|
--help) echo "$help"; return ;;
58 if (( $# == 2 )); then
64 local file_name
="${file##*/}"
69 # bind zone files use ; for comments yes, a little hacky detection.
70 if [[ $file_name == db.
* ]]; then
73 local begin
="$comment start delimiter of cedit section$name. do not modify. $comment"
74 local end
="$comment end delimiter of cedit section$name. do not modify. $comment"
76 if [[ ! -e $file_dir ]]; then
77 if ! mkdir
-p $file_dir; then
79 $s mkdir
-p $file_dir ||
return 2
82 if [[ ! -e $file ]]; then
84 if ! $s touch $file; then
86 $s touch $file ||
return 2
90 [[ -w $file ]] || s
=sudo
93 local in_section
=false
96 local temp
="$(mktemp -d)/$file_name"
99 while IFS
= read -r line
; do
100 tailn
=$
(( tailn
+ 1 ))
101 if [[ $line == "$begin" ]]; then
105 printf '%s\n' "$line" >> $file
109 IFS
= read -d '' -n 1 -r init
111 $s tee -a "$file" >/dev
/null
<<<"$begin"
112 printf '%s' "$init" |
$s tee -a "$file" >/dev
/null
113 $s tee -a "$file" >/dev
/null
114 $s tee -a "$file" >/dev
/null
<<<"$end"
117 if $exists && $in_section; then
118 while IFS
= read -r line
; do
119 if [[ $line == "$begin" ]]; then
122 if ! $in_section; then
123 printf '%s\n' "$line" >> $file
125 if [[ $line == $end ]]; then
128 done < <(tail -n +$tailn "$temp")
135 echo "New file $file:"
138 elif type -t diff &>/dev
/null
; then
139 diff=$
(diff -u "$temp" "$file")
141 if (( $ret )) && ! $quiet; then
142 echo "backup of original at $temp"
143 echo diff -u "$temp" "$file":
146 # echo "No changes made to $file"
149 # for systems like openwrt which don't have diff
150 diff=$
(cmp "$temp" "$file")
156 if ! $backup && $exists; then
159 if ! $exit_status; then