#!/bin/sh -e # # 2018 Steven Armstrong (steven-cdist at armstrong.cc) # 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # # cdist is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # cdist is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # if [ -f "$__object/parameter/before" ] && [ -f "$__object/parameter/after" ]; then echo "Use either --before OR --after but not both." >&2 exit 1 fi if [ -f "$__object/parameter/file" ]; then file="$(cat "$__object/parameter/file")" else file="/$__object_id" fi state_should="$(cat "$__object/parameter/state")" state_is="$(cat "$__object/explorer/state")" if [ -z "$state_is" ]; then printf 'The file "%s" is missing. Please create it before using %s on it.\n' "$file" "${__type##*/}" >&2 exit 1 fi if [ "$state_should" = "$state_is" ] || \ { [ "$state_should" = "present" ] && [ "$state_is" = "matching" ] ;} || \ { [ "$state_should" = "replace" ] && [ "$state_is" = "present" ] ;} ; then # If state matches already, or 'present' is used and regex matches # or 'replace' is used and the exact line is present, then there is # nothing to do exit 0 fi if [ -f "$__object/parameter/before" ]; then position="before" elif [ -f "$__object/parameter/after" ]; then position="after" else # By default we append to the end of the file. position="end" fi if [ -f "$__object/parameter/regex" ]; then needle="regex" else needle="line" fi add=0 remove=0 case "$state_should" in present|replace) if [ "$state_is" = "wrongposition" ] || [ "$state_is" = "matching" ]; then echo updated >> "$__messages_out" remove=1 else echo added >> "$__messages_out" fi add=1 ;; absent) echo removed >> "$__messages_out" remove=1 ;; esac cat << DONE tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX) # preserve ownership and permissions of existing file if [ -f "$file" ]; then cp -p "$file" "\$tmpfile" fi awk -v position="$position" -v needle="$needle" -v remove=$remove -v add=$add ' function _find(_text, _pattern) { if (needle == "regex") { return match(_text, _pattern) } else { return index(_text, _pattern) } } BEGIN { line_file = ENVIRON["__object"] "/parameter/line" getline line < line_file # Need to close line file as it may be re-read as pattern below. close(line_file) getline pattern < (ENVIRON["__object"] "/parameter/" needle) getline anchor < (ENVIRON["__object"] "/parameter/" position) } { if (remove) { if (_find(\$0, pattern)) { # skip over this line -> remove it next } } if (add) { if (anchor && match(\$0, anchor)) { if (position == "before") { print line add = 0 print } else if (position == "after") { print print line add = 0 } next } } print } END { if (add) { print line } } ' "$file" > "\$tmpfile" mv -f "\$tmpfile" "$file" DONE if [ -f "$__object/parameter/onchange" ]; then cat "$__object/parameter/onchange" fi