@@ -28,28 +28,74 @@ log() {
2828 fi
2929}
3030
31- # Generic curl handler function
32- curl_handler () {
33- local command=" $1 "
34- local hostname=" $2 "
35-
36- response=$( $command -w " %{http_code}" -o /dev/null)
37- curl_exit_code=$?
38-
39- if [ " $response " -ge 200 ] && [ " $response " -lt 300 ]; then
40- return 0
41- elif [ $curl_exit_code -ne 0 ]; then
42- log " ERROR" " $RED " " Connection error during request to $hostname (curl exit code: $curl_exit_code )."
43- return 1
44- elif [ " $response " -ge 400 ]; then
45- log " ERROR" " $RED " " Server error during request to $hostname (HTTP status code: $response )."
46- return 2
31+ # Fetch a URL to a destination file, validating status codes.
32+ # Usage: fetch "<url>" "<dest or empty>" "200 404"
33+ fetch () {
34+ local url=" $1 "
35+ local dest=" $2 "
36+ local accepted=" ${3:- 200} "
37+
38+ # If no dest given, just discard body
39+ local out
40+ if [ -n " $dest " ]; then
41+ # Write to ".tmp" files first, then move when success, to ensure we don't write partial files
42+ out=" ${dest} .tmp"
4743 else
48- log " ERROR" " $RED " " Unexpected response from $hostname (HTTP status code: $response )."
49- return 3
44+ out=" /dev/null"
5045 fi
46+
47+ response=$( curl --connect-timeout 5 --max-time 30 -s -w " %{http_code}" -o " $out " " $url " )
48+ local curl_exit_code=$?
49+
50+ if [ $curl_exit_code -ne 0 ]; then
51+ [ -n " $dest " ] && rm -f " $out "
52+ log " ERROR" " $RED " " Connection error during request to $url (curl exit code: $curl_exit_code )."
53+ return 1
54+ fi
55+
56+ for code in $accepted ; do
57+ if [ " $response " -eq " $code " ]; then
58+ # success → move tmp into place
59+ if [ -n " $dest " ]; then
60+ mv " $out " " $dest "
61+ fi
62+ return 0
63+ fi
64+ done
65+
66+ # not accepted
67+ [ -n " $dest " ] && rm -f " $out "
68+ log " ERROR" " $RED " " Unexpected response from $url (HTTP $response )."
69+ return 2
5170}
5271
72+
73+ # POST a file to a URL, validating status codes.
74+ # Usage: post_file "<url>" "<file>" "200"
75+ post_file () {
76+ local url=" $1 "
77+ local file=" $2 "
78+ local accepted=" ${3:- 200} "
79+
80+ response=$( curl --connect-timeout 5 --max-time 300 -s -w " %{http_code}" -o /dev/null -X POST -F " file=@$file " " $url " )
81+ local curl_exit_code=$?
82+
83+ if [ $curl_exit_code -ne 0 ]; then
84+ log " ERROR" " $RED " " Connection error during POST to $url (curl exit code: $curl_exit_code )."
85+ return 1
86+ fi
87+
88+ for code in $accepted ; do
89+ if [ " $response " -eq " $code " ]; then
90+ return 0
91+ fi
92+ done
93+
94+ log " ERROR" " $RED " " Unexpected response from $url (HTTP $response )."
95+ return 2
96+ }
97+
98+
5399# Print help message
54100show_help () {
55101 cat << EOF
@@ -109,44 +155,27 @@ backup_one() {
109155 local address=" $2 "
110156 local port=" $3 "
111157
112- log " INFO" " $YELLOW " " Backing up device config/presets: $hostname ($address :$port )"
158+ log " INFO" " $YELLOW " " Backing up device config/presets/ir : $hostname ($address :$port )"
113159
114160 mkdir -p " $backup_dir "
115161
116- local cfg_url=" http://$address :$port /cfg.json"
117- local presets_url=" http://$address :$port /presets.json"
118- local ir_url=" http://$address :$port /ir.json"
119- local cfg_dest=" ${backup_dir} /${hostname} .cfg.json"
120- local presets_dest=" ${backup_dir} /${hostname} .presets.json"
121- local ir_dest=" ${backup_dir} /${hostname} .ir.json"
122-
123- # Write to ".tmp" files first, then move when success, to ensure we don't write partial files
124- local curl_command_cfg=" curl -s " $cfg_url " -o " $cfg_dest .tmp" "
125- local curl_command_presets=" curl -s " $presets_url " -o " $presets_dest .tmp" "
126- local curl_command_ir=" curl -s " $ir_url " -o " $ir_dest .tmp" "
162+ local file_prefix=" ${backup_dir} /${hostname} "
127163
128- if ! curl_handler " $curl_command_cfg " " $hostname " ; then
164+ if ! fetch " http:// $address : $port /cfg.json " " ${file_prefix} .cfg.json " ; then
129165 log " ERROR" " $RED " " Failed to backup configuration for $hostname "
130- rm -f " $cfg_dest .tmp"
131166 return 1
132167 fi
133168
134- if ! curl_handler " $curl_command_presets " " $hostname " ; then
169+ if ! fetch " http:// $address : $port /presets.json " " ${file_prefix} .presets.json " ; then
135170 log " ERROR" " $RED " " Failed to backup presets for $hostname "
136- rm -f " $presets_dest .tmp"
137171 return 1
138172 fi
139173
140- mv " $cfg_dest .tmp" " $cfg_dest "
141- mv " $presets_dest .tmp" " $presets_dest "
142-
143- if curl_handler " $curl_command_ir " " $hostname " ; then
144- mv " $ir_dest .tmp" " $ir_dest "
145- else
146- rm -f " $ir_dest .tmp"
147- log " WARN" " $YELLOW " " No ir.json found for $hostname (skipping)"
174+ # ir.json is optional
175+ if ! fetch " http://$address :$port /ir.json" " ${file_prefix} .ir.json" " 200 404" ; then
176+ log " ERROR" " $RED " " Failed to backup ir configs for $hostname "
148177 fi
149-
178+
150179 log " INFO" " $GREEN " " Successfully backed up config and presets for $hostname "
151180 return 0
152181}
@@ -161,9 +190,8 @@ update_one() {
161190 log " INFO" " $YELLOW " " Starting firmware update for device: $hostname ($address :$port )"
162191
163192 local url=" http://$address :$port /update"
164- local curl_command=" curl -s -X POST -F " file=@$firmware " " $url " "
165193
166- if ! curl_handler " $curl_command " " $hostname " ; then
194+ if ! post_file " $url " " $firmware " " 200 " ; then
167195 log " ERROR" " $RED " " Failed to update firmware for $hostname "
168196 return 1
169197 fi
0 commit comments