]> woffs.de Git - fd/haskell-amqp-utils.git/blob - callback
update reuse compat
[fd/haskell-amqp-utils.git] / callback
1 #!/bin/bash
2 # SPDX-FileCopyrightText: 2022 Frank Doepper
3 #
4 # SPDX-License-Identifier: GPL-3.0-only
5
6 set -o pipefail
7 declare -A h # header array
8 # default (empty) action, to be overridden in config
9 action () {
10   :
11 }
12 wrap () {
13   local IFS=
14   "$@" | while read l
15   do
16     echo "$n $l"
17   done
18 }
19 setheader () {
20   local IFS==
21   set $1
22   h[$1]=$2
23 }
24 checktimeout () {
25   if [ $(date +%s) -gt $toolate ]
26   then
27     exit 1
28   fi
29 }
30 delay () {
31   sleep 2
32 }
33 checkshaandmoveorexit () {
34   sha=$1
35   src=$2
36   dst=$3
37   if [ "$sha" ] && sha1=$(sha1sum "$src" | awk '{print$1}')
38   then
39     if [ "$sha1" = "$sha" ]
40     then
41       echo "$n $src sha1 ok"
42       wrap mv -v "$src" "$dst"
43       wrap action "$dst"
44       exit
45     else
46       echo "$n $src sha1 FALSCH"
47       # keine action, aber ACK
48       exit 0
49     fi
50   else
51     # keine sha, auch gut
52     wrap mv -v "$src" "$dst"
53     wrap action "$dst"
54     exit
55   fi
56 }
57 while [ "x$1" != x ]
58 do
59   case $1 in
60     -f) f=$2;shift ;; # filename
61     -m) m=$2;shift ;; # mime type
62     -h) setheader "$2";shift ;; # headers
63     -n) n=$2;shift ;; # seq number
64     -r) r=$2;shift ;; # routing key
65     -d) dest=$2;shift ;; # file destination dir
66     -c) . $2 || exit;shift ;; # config snippet
67     -p) prio=$2;shift ;; # priority
68     -t) t=$2;shift ;; # timestamp
69     -R) redeliv=$2;shift ;; # redelivered message
70   esac
71   shift
72 done
73 trap "rm -f -- \"$f\"" 0 1 2 3 15
74 if [ "${h[chunkSize]}" -a "${h[fileSize]}" ]
75 then
76   : ${maxwait:=20}
77   : ${dest:=/tmp/files}
78   : ${temp:=$dest/.tmp}
79   mkdir -p $dest
80   mkdir -p $temp
81   begin=$(date +%s)
82   toolate=$((begin+maxwait))
83   if [ "${h[chunkSize]}" = "${h[fileSize]}" ]
84   then
85     # einteilig
86     wrap cp -v "$f" "$temp/${h[fileName]}"
87     checkshaandmoveorexit "${h[sha1]}" "$temp/${h[fileName]}" "$dest/${h[fileName]}"
88   elif [ "${h[chunkIndex]}" ]
89   then
90     # mehrteilig
91     wrap cp -v "$f" "$temp/${h[fileName]}.part${h[chunkIndex]}"
92     if [ "${h[chunkCount]}" = "${h[chunkIndex]}" ]
93     then
94       # letzter Teil
95       # 
96       until checktimeout; [ -f "$temp/${h[fileName]}.part" ]
97       do
98         for i in `seq 1 ${h[chunkCount]}`
99         do
100           if ! [ -f "$temp/${h[fileName]}.part$i" ]
101           then
102             # einer fehlt. versuch beenden. warten bis der da ist. nochmal probieren.
103             rm -f "$temp/${h[fileName]}.part"
104             delay
105             break
106           fi
107           # ls -l "$temp/${h[fileName]}.part$i"
108           cat "$temp/${h[fileName]}.part$i" >> "$temp/${h[fileName]}.part"
109         done
110       done
111       # warten, bis die Prozesse der anderen Teile sich beendet und ihre
112       # Datei entfernt haben und keine *.part* mehr da sind
113       wrap mv -v "$temp/${h[fileName]}.part" "$temp/${h[fileName]}"
114       rm -f -- "$temp/${h[fileName]}.part${h[chunkIndex]}"
115       until checktimeout; [ "$(echo "$temp/${h[fileName]}.part"*)" = "$temp/${h[fileName]}.part*" ]
116       do
117         delay
118       done
119       checkshaandmoveorexit "${h[sha1]}" "$temp/${h[fileName]}" "$dest/${h[fileName]}"
120     else
121       # nicht letzter Teil
122       # erst ACKen, wenn alle Teile da sind und zusammengesetzt sind.
123       until checktimeout; [ -f "$temp/${h[fileName]}" ]
124       do
125         delay
126       done
127       rm -f -- "$temp/${h[fileName]}.part${h[chunkIndex]}"
128     fi
129   fi
130 else
131   # keine headerdaten, normal!
132   wrap action "$f"
133   exit
134 fi
135
136 exit 0