]> git.plutz.net Git - lobster/blob - therapies/update_therapy.sh
avoid race condition by using per-process temp files
[lobster] / therapies / update_therapy.sh
1 #!/bin/zsh
2
3 # Copyright 2016, 2020 Paul Hänsch
4 #
5 # This file is part of Confetti.
6
7 # Confetti is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # Confetti is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with Confetti.  If not, see <http://www.gnu.org/licenses/>. 
19
20 . "$_EXEC/pdiread.sh"
21 tpy="$(POST id)"
22
23 tpyfile="$_DATA/therapies/${tpy}.tpy"
24 tempfile="$_DATA/temp/${tpy}.$$.tpy"
25
26 if [ "$(POST tid)" != "$(transid "$tpyfile")" ]; then
27   if [ "$(POST autosubmit)" = "true" ]; then
28     printf 'Status: 409 Conflict\r\nContent-Length: 0\r\n\r\n'
29     exit 0
30   else
31     SET_COOKIE session message="TRANSACTION_CONFLICT"
32     REDIRECT "/therapies/${tpy%.*}/${tpy#*.}"
33   fi
34 fi
35
36 if [ "$(POST formend)" != "formend" ]; then
37   if [ "$(POST autosubmit)" = "true" ]; then
38     printf 'Status: 409 Conflict\r\nContent-Length: 0\r\n\r\n'
39     exit 0
40   else
41     SET_COOKIE session message="INCOMPLETE_SUBMIT"
42     REDIRECT "/therapies/${tpy%.*}/${tpy#*.}"
43   fi
44 fi
45
46 # serialize POST array into file
47 for key in $(POST_KEYS); do
48   case "$key" in
49     imagedata|tid|formend) : ;;
50     session*_date)
51       value="$(POST "$key")"
52       y=0 mon=0 dom=0
53       case $value in
54         *.*.*) IFS=. read dom mon y <<-END
55                 ${value}
56                 END
57           ;;
58         *.*.) IFS=. read dom mon <<-END
59                 ${value}
60                 END
61           ;;
62         */*/*) IFS=/ read mon dom y <<-END
63                 ${value}
64                 END
65           ;;
66         */*) IFS=/ read mon dom <<-END
67                 ${value}
68                 END
69           ;;
70         *-*-*) IFS=- read y mon dom <<-END
71                 ${value}
72                 END
73           ;;
74       esac
75       [ ! "$y" ] && y="$(date +%Y)"
76       [ "$y" -gt 0 -a "$y" -lt 100 ] && y="$((y + 2000))"
77       date -d "${y}-${mon}-${dom}" + && printf %s:%s\\n "$key" "$(date -d "${y}-${mon}-${dom}" +%F)" \
78                                      || printf %s:\\n "$key"
79       ;;
80     *) printf %s:%s\\n "$key" "$(pdi_escape "$(POST "$key")")" ;;
81   esac
82 done >"$tempfile" 2>&-
83
84 if [ "$(POST delete_session)" ]; then
85   n="$(POST delete_session)"
86   sed -Ei '/^session'$n'[_:]/d' "$tempfile"
87   rm "${tpyfile%.tpy}_session${n}.png"
88
89   while grep -Eq '^session'$(($n + 1))'_' "$tempfile"; do
90     sed -Ei 's;^session'$(($n + 1))'(_|:);session'$n'\1;' "$tempfile"
91     mv "${tpyfile%.tpy}_session$(($n+1)).png" "${tpyfile%.tpy}_session${n}.png"
92     n=$(($n+1))
93   done
94
95 elif [ "$(POST new_session)" ]; then
96   sid="$(POST new_session)"
97
98   read junkx junky dim junkz <<-E_READ
99         $(identify "$_EXEC/therapies/therapy_background.png")
100         E_READ
101
102   convert -size "$dim" xc:transparent "${tpyfile%.tpy}_${sid}.png"
103
104   printf '%s:exists\n' "$sid" >>"$tempfile"
105   printf '%s_open:checked\n' "$sid" >>"$tempfile"
106
107 elif [ "$(POST imagedata)" ]; then
108   sid="$(sed -En 's;^(session[0-9]+)_open:checked$;\1;p' "$tempfile" \
109          | sort -n \
110          | tail -n1
111        )"
112
113   convert "${tpyfile%.tpy}_${sid}.png" \
114           -draw "$(POST imagedata)" -transparent white \
115           "${tpyfile%.tpy}_${sid}.png"
116   sync
117 fi
118
119 if ! diff -q "$tempfile" "$tpyfile" >/dev/null; then
120   mv "$tempfile" "$tpyfile"
121   rm -f -- "${_DATA}/cache/${tpy%%.*}.vcf.cache"
122 fi
123
124 if [ "$(POST autosubmit)" = "true" ]; then
125   msg="$(transid "$tpyfile")"
126   printf 'HTTP/1.1 200 OK\r\nContent-Length: %i\r\n\r\n%s' \
127          "${#msg}" "${msg}"
128 else
129   REDIRECT "/therapies/${tpy%.*}/${tpy#*.}"
130 fi