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