1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#!/bin/sh
# Copyright (c) 2022 Thomas Voss <mail@thomasvoss.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# Copy an existing text file to a temporary location. Then edit the file.
# Attempt to then transfer the temporary file back to the original location if
# the temprary file has been altered. Conclude with a little clean-up. Try to
# avoid deleting any changes.
warn() { echo "$PROG: $1" >&2; }
die() { warn "$2"; exit $1; }
get_intr() {
stty -a | sed -En '
/^(.* )?intr = / {
s///
s/;.*$//
p
}'
}
PROG=${0##*/}
[ $# -ne 1 ] && {
echo "Usage: $PROG file"
exit 1
}
[ ! -f "$1" ] && die 2 "$1: File does not exist or is a special file/link."
[ -L "$1" ] && die 2 "$1: File is a symbolic link, refusing to edit."
[ ! -r "$1" ] && die 3 "$1: File cannot be read by the current user."
tmp=$(mktemp --tmpdir doasedit.XXXXXXXX --suffix="${1//\//-}") || \
die 4 "Could not create temporary file."
trap "rm -f $tmp" EXIT HUP INT TERM
cp "$1" "$tmp" || die 5 "$1: Unable to copy file."
"${VISUAL:-${EDITOR:-vi}}" "$tmp" || {
warn "Could not run visual editor '$VISUAL' or editor '$EDITOR'."
die 6 "Make sure the VISUAL and/or EDITOR variables are set."
}
cmp -s "$1" "$tmp" && \
die 0 "File unchanged. Not writing back to original location."
# At this point the file has been changed. Make sure it still exists.
[ -f "$tmp" ] && {
doas cp "$tmp" "$1"
until cmp -s "$tmp" "$1"; do
warn "$1: Copying failed. Press enter to try again,"
warn "or ($(get_intr)) to cancel."
read _
doas cp "$tmp" "$1"
done
}
|