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 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 -s Silent. Quiet and exit 0 on modified file.
39 local s
diff name init file_dir exists verbose backup quiet silent
40 file_dir
="$(dirname "$file")"
48 -b) backup
=true
; shift ;;
49 -v) verbose
=true
; shift ;;
50 -q) quiet
=true
; shift ;;
51 -s) quiet
=true
; silent
=true
; shift ;;
52 -h|
--help) echo "$help"; return ;;
55 if (( $# == 2 )); then
61 local file_name
="${file##*/}"
66 # bind zone files use ; for comments yes, a little hacky detection.
67 if [[ $file_name == db.
* ]]; then
70 local begin
="$comment start delimiter of cedit section$name. do not modify. $comment"
71 local end
="$comment end delimiter of cedit section$name. do not modify. $comment"
73 if [[ ! -e $file_dir ]]; then
74 if ! mkdir
-p $file_dir; then
76 $s mkdir
-p $file_dir ||
return 2
79 if [[ ! -e $file ]]; then
81 if ! $s touch $file; then
83 $s touch $file ||
return 2
87 [[ -w $file ]] || s
=sudo
90 local in_section
=false
93 local temp
="$(mktemp -d)/$file_name"
96 while IFS
= read -r line
; do
97 tailn
=$
(( tailn
+ 1 ))
98 if [[ $line == "$begin" ]]; then
102 printf '%s\n' "$line" >> $file
106 IFS
= read -d '' -n 1 -r init
108 $s tee -a "$file" >/dev
/null
<<<"$begin"
109 printf '%s' "$init" |
$s tee -a "$file" >/dev
/null
110 $s tee -a "$file" >/dev
/null
111 $s tee -a "$file" >/dev
/null
<<<"$end"
114 if $exists && $in_section; then
115 while IFS
= read -r line
; do
116 if [[ $line == "$begin" ]]; then
119 if ! $in_section; then
120 printf '%s\n' "$line" >> $file
122 if [[ $line == $end ]]; then
125 done < <(tail -n +$tailn "$temp")
132 echo "New file $file:"
135 elif type -t diff &>/dev
/null
; then
136 diff=$
(diff -u "$temp" "$file")
138 if (( $ret )) && ! $quiet; then
139 echo "backup of original at $temp"
140 echo diff -u "$temp" "$file":
143 # echo "No changes made to $file"
146 # for systems like openwrt which don't have diff
147 diff=$
(cmp "$temp" "$file")
153 if ! $backup && $exists; then