chore(bkgpslog):bump to version 0.2.1 from 0.2.0
[EVA-2020-02.git] / exec / bkgpslog
CommitLineData
032f4b05
SBS
1#!/bin/bash
2
8fbca23d
SBS
3# Desc: Records gps data until midnight
4# Author: Steven Baltakatei Sandoval; License: GPLv3+
aa2a49f1 5# Usage: bkgpslog -o [output dir]
032f4b05 6
8fbca23d 7#==BEGIN Define script parameters==
6c30388f
SBS
8## Logging Behavior parameters
9BUFFER_TTL="60"; # time between file writes
10SCRIPT_TTL="day"; # (day|hour)
aa2a49f1
SBS
11#### TZ="UTC"; export TZ; # Default time zone; overridden by '--time-zone=[str]' option
12DIR_TMP_DEFAULT="/dev/shm"; # Default parent of working directory
6c30388f 13
aa2a49f1
SBS
14SCRIPT_TIME_START=$(date +%Y%m%dT%H%M%S.%N);
15PATH="$HOME/.local/bin:$PATH"; # Add "$(systemd-path user-binaries)" path in case apps saved there
16SCRIPT_HOSTNAME=$(hostname); # Save hostname of system running this script.
f5def0c4 17SCRIPT_VERSION="bkgpslog 0.2.1"; # Define version of script.
4c0c5850 18SCRIPT_NAME="$(basename "$0")"; # Define basename of script file.
8fbca23d
SBS
19
20declare -Ag appRollCall # Associative array for storing app status
21declare -Ag fileRollCall # Associative array for storing file status
22declare -Ag dirRollCall # Associative array for storing dir status
17d49005 23declare -a recPubKeys # for processArguments function
77361307 24declare recipients # for main function
8fbca23d 25
cfc25c90
SBS
26## Initialize variables
27OPTION_VERBOSE=""; OPTION_ENCRYPT=""; OPTION_COMPRESS=""; OPTION_TMPDIR="";
28
8fbca23d
SBS
29#===BEGIN Declare local script functions===
30checkapp() {
31 # Desc: If arg is a command, save result in assoc array 'appRollCall'
32 # Usage: checkapp arg1 arg2 arg3 ...
33 # Input: global assoc. array 'appRollCall'
34 # Output: adds/updates key(value) to global assoc array 'appRollCall'
35 local returnState
36 #echo "DEBUG:$(date +%S.%N)..Starting checkapp function."
37 #echo "DEBUG:args: $@"
38 #echo "DEBUG:returnState:$returnState"
39
40 #===Process Args===
41 for arg in "$@"; do
42 #echo "DEBUG:processing arg:$arg"
0b3dde05 43 if command -v "$arg" 1>/dev/null 2>&1; then # Check if arg is a valid command
8fbca23d
SBS
44 appRollCall[$arg]="true";
45 #echo "DEBUG:appRollCall[$arg]:"${appRollCall[$arg]}
46 if ! [ "$returnState" = "false" ]; then returnState="true"; fi
47 else
48 appRollCall[$arg]="false"; returnState="false";
49 fi
50 done
51
52 #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done
53 #echo "DEBUG:evaluating returnstate. returnState:"$returnState
54
55 #===Determine function return code===
56 if [ "$returnState" = "true" ]; then
57 #echo "DEBUG:checkapp returns true for $arg";
58 return 0;
59 else
60 #echo "DEBUG:checkapp returns false for $arg";
61 return 1;
62 fi
63} # Check that app exists
64checkfile() {
65 # Desc: If arg is a file path, save result in assoc array 'fileRollCall'
66 # Usage: checkfile arg1 arg2 arg3 ...
67 # Input: global assoc. array 'fileRollCall'
68 # Output: adds/updates key(value) to global assoc array 'fileRollCall';
69 # Output: returns 0 if app found, 1 otherwise
70 local returnState
71
72 #===Process Args===
73 for arg in "$@"; do
74 #echo "DEBUG:processing arg:$arg"
75 if [ -f "$arg" ]; then
76 fileRollCall["$arg"]="true";
77 #echo "DEBUG:fileRollCall[\"$arg\"]:"${fileRollCall["$arg"]}
78 if ! [ "$returnState" = "false" ]; then returnState="true"; fi
79 else
80 fileRollCall["$arg"]="false"; returnState="false";
81 fi
82 done
83
84 #for key in "${!fileRollCall[@]}"; do echo "DEBUG:fileRollCall key [$key] is:${fileRollCall[$key]}"; done
85 #echo "DEBUG:evaluating returnstate. returnState:"$returnState
86
87 #===Determine function return code===
88 if [ "$returnState" = "true" ]; then
89 #echo "DEBUG:checkapp returns true for $arg";
90 return 0;
91 else
92 #echo "DEBUG:checkapp returns false for $arg";
93 return 1;
94 fi
95} # Check that file exists
96checkdir() {
97 # Desc: If arg is a dir path, save result in assoc array 'dirRollCall'
98 # Usage: checkdir arg1 arg2 arg3 ...
99 # Input: global assoc. array 'dirRollCall'
100 # Output: adds/updates key(value) to global assoc array 'dirRollCall';
101 # Output: returns 0 if app found, 1 otherwise
102 local returnState
103
104 #===Process Args===
105 for arg in "$@"; do
106 #echo "DEBUG:processing arg:$arg"
107 if [ -d "$arg" ]; then
108 dirRollCall["$arg"]="true";
109 #echo "DEBUG:dirRollCall[\"$arg\"]:"${dirRollCall["$arg"]}
110 if ! [ "$returnState" = "false" ]; then returnState="true"; fi
bcf09dcc 111 elif [ "$arg" = "" ]; then
8fbca23d 112 dirRollCall["$arg"]="false"; returnState="false";
bcf09dcc
SBS
113 else
114 returnState="false";
8fbca23d
SBS
115 fi
116 done
117
118 #for key in "${!dirRollCall[@]}"; do echo "DEBUG:dirRollCall key [$key] is:${dirRollCall[$key]}"; done
119 #echo "DEBUG:evaluating returnstate. returnState:"$returnState
120
121 #===Determine function return code===
122 if [ "$returnState" = "true" ]; then
123 #echo "DEBUG:checkapp returns true for $arg";
124 return 0;
125 else
126 #echo "DEBUG:checkapp returns false for $arg";
127 return 1;
128 fi
129} # Check that dir exists
032f4b05 130
c609b9c8
SBS
131# Yell, Die, Try Three-Fingered Claw technique
132# Ref/Attrib: https://stackoverflow.com/a/25515370
133yell() { echo "$0: $*" >&2; }
134die() { yell "$*"; exit 111; }
135try() { "$@" || die "cannot $*"; }
136
032f4b05
SBS
137echoerr() {
138 echo "$@" 1>&2; # Define stderr echo function.
139} # Define stderr message function.
140showUsage() {
141 echoerr "USAGE:"
94e094d1 142 echoerr " bkgpslog [ options ]"
032f4b05
SBS
143 echoerr
144 echoerr "OPTIONS:"
145 echoerr " -h, --help"
146 echoerr " Display help information."
147 echoerr
148 echoerr " --version"
149 echoerr " Display script version."
150 echoerr
151 echoerr " -v, --verbose"
152 echoerr " Display debugging info."
153 echoerr
17d49005
SBS
154 echoerr " -e, --encrypt"
155 echoerr " Encrypt output."
156 echoerr
157 echoerr " -r, --recipient [ pubkey string ]"
f7f33d33
SBS
158 echoerr " Specify recipient. May be age or ssh pubkey."
159 echoerr " See https://github.com/FiloSottile/age"
17d49005 160 echoerr
032f4b05
SBS
161 echoerr " -o, --output [ directory ]"
162 echoerr " Specify output directory to save logs."
17d49005 163 echoerr
408a342b
SBS
164 echoerr " -c, --compress"
165 echoerr " Compress output with gzip (before encryption if enabled)."
166 echoerr
f7f33d33
SBS
167 echoerr " -z, --time-zone"
168 echoerr " Specify time zone. (ex: \"America/New_York\")"
169 echoerr
170 echoerr " -t, --temp-dir"
171 echoerr " Specify parent directory for temporary working directory."
172 echoerr " Default: \"/dev/shm\""
173 echoerr
17d49005 174 echoerr "EXAMPLE: (bash script lines)"
408a342b 175 echoerr "/bin/bash bkgpslog -e -c \\"
17d49005
SBS
176 echoerr "-r age1mrmfnwhtlprn4jquex0ukmwcm7y2nxlphuzgsgv8ew2k9mewy3rs8u7su5 \\"
177 echoerr "-r age1ala848kqrvxc88rzaauc6vc5v0fqrvef9dxyk79m0vjea3hagclswu0lgq \\"
178 echoerr "-o ~/Sync/Location"
032f4b05
SBS
179} # Display information on how to use this script.
180showVersion() {
181 echoerr "$SCRIPT_VERSION"
182} # Display script version.
183vbm() {
0b3dde05
SBS
184 # Usage: vbm "DEBUG:verbose message here"
185 # Description: Prints verbose message ("vbm") to stderr if OPTION_VERBOSE is set to "true".
186 # Input:
187 # - OPTION_VERBOSE variable set by processArguments function. (ex: "true", "false")
188 # - "$@" positional arguments fed to this function.
189 # Output: stderr
190 # Script function dependencies: echoerr
191 # External function dependencies: echo
192 # Last modified: 2020-04-11T23:57Z
193 # Last modified by: Steven Baltakatei Sandoval
194 # License: GPLv3+
195 # Ref./Attrib:
196
197 if [ "$OPTION_VERBOSE" = "true" ]; then
198 FUNCTION_TIME=$(date --iso-8601=ns); # Save current time in nano seconds.
199 echoerr "[$FUNCTION_TIME] ""$*"; # Display argument text.
032f4b05 200 fi
0b3dde05
SBS
201
202 # End function
203 return 0; # Function finished.
032f4b05
SBS
204} # Verbose message display function.
205processArguments() {
206 while [ ! $# -eq 0 ]; do # While number of arguments ($#) is not (!) equal to (-eq) zero (0).
d6896d3b
SBS
207 #echoerr "DEBUG:Starting processArguments while loop."
208 #echoerr "DEBUG:Provided arguments are:""$*"
032f4b05 209 case "$1" in
c1bbf9f7 210 -h | --help) showUsage; exit 1;; # Display usage.
032f4b05 211 --version) showVersion; exit 1;; # Show version
c1bbf9f7 212 -v | --verbose) OPTION_VERBOSE="true"; vbm "DEBUG:Verbose mode enabled.";; # Enable verbose mode.
6c30388f 213 -o | --output) if [ -d "$2" ]; then DIR_OUT="$2"; vbm "DEBUG:DIR_OUT:$DIR_OUT"; shift; fi ;; # Define output directory.
17d49005
SBS
214 -e | --encrypt) OPTION_ENCRYPT="true"; vbm "DEBUG:Encrypted output mode enabled.";;
215 -r | --recipient) # Add 'age' recipient via public key string
405ce7df 216 recPubKeys+=("$2"); vbm "STATUS:pubkey added:""$2"; shift;;
408a342b 217 -c | --compress) OPTION_COMPRESS="true"; vbm "DEBUG:Compressed output mode enabled.";;
6a17e8e7
SBS
218 -z | --time-zone) try setTimeZoneEV "$2"; shift;;
219 -t | --temp-dir) OPTION_TMPDIR="true" && TMP_DIR_PRIORITY="$2"; shift;;
b0da06ca 220 *) echoerr "ERROR: Unrecognized argument: $1"; echoerr "STATUS:All arguments:$*"; exit 1;; # Handle unrecognized options.
032f4b05
SBS
221 esac
222 shift
223 done
224} # Argument Processing
6c30388f
SBS
225setTimeZoneEV(){
226 # Desc: Set time zone environment variable TZ
227 # Usage: setTimeZoneEV arg1
228 # Input: arg1: 'date'-compatible timezone string (ex: "America/New_York")
229 # TZDIR env var (optional; default: "/usr/share/zoneinfo")
230 # Output: exports TZ
231 # exit code 0 on success
232 # exit code 1 on incorrect number of arguments
233 # exit code 2 if unable to validate arg1
234 # Depends: yell, printenv, bash 5
235 # Tested on: Debian 10
236 ARG1="$1"
237 local tzDir returnState
238 if ! [[ $# -eq 1 ]]; then
239 yell "ERROR:Invalid argument count.";
240 return 1;
241 fi
242
243 # Read TZDIR env var if available
244 if printenv TZDIR 1>/dev/null 2>&1; then
245 tzDir="$(printenv TZDIR)";
246 else
247 tzDir="/usr/share/zoneinfo";
248 fi
249
250 # Validate TZ string
251 if ! [[ -f "$tzDir"/"$ARG1" ]]; then
252 yell "ERROR:Invalid time zone argument.";
253 return 2;
254 else
255 # Export ARG1 as TZ environment variable
256 TZ="$ARG1" && export TZ && returnState="true";
257 fi
258
259 # Determine function return code
260 if [ "$returnState" = "true" ]; then
261 return 0;
262 fi
263} # Exports TZ environment variable
c2aaff78
SBS
264timeUntilNextDay(){
265 # Desc: Report seconds until next day.
3395ae22 266 # Version: 1.0.0
c2aaff78 267 # Output: stdout: integer seconds until next day
8fbca23d 268 # Output: exit code 0 if stdout > 0; 1 if stdout = 0; 2 if stdout < 0
c2aaff78
SBS
269 # Usage: timeUntilNextDay
270 # Usage: if ! myTTL="$(timeUntilNextDay)"; then yell "ERROR in if statement"; exit 1; fi
3395ae22
SBS
271 # Depends: date 8, echo 8, yell, try
272
c2aaff78 273 local returnState TIME_CURRENT TIME_NEXT_DAY SECONDS_UNTIL_NEXT_DAY
3395ae22 274
8fbca23d 275 TIME_CURRENT="$(date --iso-8601=seconds)" ; # Produce `date`-parsable current timestamp with resolution of 1 second.
c2aaff78
SBS
276 TIME_NEXT_DAY="$(date -d "$TIME_CURRENT next day" --iso-8601=date)"; # Produce timestamp of beginning of tomorrow with resolution of 1 second.
277 SECONDS_UNTIL_NEXT_DAY="$(( $(date +%s -d "$TIME_NEXT_DAY") - $(date +%s -d "$TIME_CURRENT") ))" ; # Calculate seconds until closest future midnight (res. 1 second).
278 if [[ "$SECONDS_UNTIL_NEXT_DAY" -gt 0 ]]; then
279 returnState="true";
280 elif [[ "$SECONDS_UNTIL_NEXT_DAY" -eq 0 ]]; then
3395ae22 281 returnState="warning_zero";
c2aaff78
SBS
282 yell "WARNING:Reported time until next day exactly zero.";
283 elif [[ "$SECONDS_UNTIL_NEXT_DAY" -lt 0 ]]; then
3395ae22 284 returnState="warning_negative";
c2aaff78
SBS
285 yell "WARNING:Reported time until next day is negative.";
286 fi
287
288 try echo "$SECONDS_UNTIL_NEXT_DAY"; # Report
289
3395ae22 290 # Determine function return code
c2aaff78
SBS
291 if [[ "$returnState" = "true" ]]; then
292 return 0;
3395ae22 293 elif [[ "$returnState" = "warning_zero" ]]; then
c2aaff78 294 return 1;
3395ae22 295 elif [[ "$returnState" = "warning_negative" ]]; then
c2aaff78
SBS
296 return 2;
297 fi
298} # Report seconds until next day
299timeUntilNextHour(){
300 # Desc: Report seconds until next hour
3395ae22 301 # Version 1.0.0
c2aaff78
SBS
302 # Output: stdout: integer seconds until next hour
303 # Output: exit code 0 if stdout > 0; 1 if stdout = 0; 2 if stdout < 0
304 # Usage: timeUntilNextHour
305 # Usage: if ! myTTL="$(timeUntilNextHour)"; then yell "ERROR in if statement"; exit 1; fi
3395ae22 306
c2aaff78
SBS
307 local returnState TIME_CURRENT TIME_NEXT_HOUR SECONDS_UNTIL_NEXT_HOUR
308 TIME_CURRENT="$(date --iso-8601=seconds)"; # Produce `date`-parsable current timestamp with resolution of 1 second.
309 TIME_NEXT_HOUR="$(date -d "$TIME_CURRENT next hour" --iso-8601=hours)"; # Produce `date`-parsable current time stamp with resolution of 1 second.
310 SECONDS_UNTIL_NEXT_HOUR="$(( $(date +%s -d "$TIME_NEXT_HOUR") - $(date +%s -d "$TIME_CURRENT") ))"; # Calculate seconds until next hour (res. 1 second).
311 if [[ "$SECONDS_UNTIL_NEXT_HOUR" -gt 0 ]]; then
8fbca23d 312 returnState="true";
c2aaff78 313 elif [[ "$SECONDS_UNTIL_NEXT_HOUR" -eq 0 ]]; then
3395ae22 314 returnState="warning_zero";
c2aaff78
SBS
315 yell "WARNING:Reported time until next hour exactly zero.";
316 elif [[ "$SECONDS_UNTIL_NEXT_HOUR" -lt 0 ]]; then
3395ae22 317 returnState="warning_negative";
c2aaff78 318 yell "WARNING:Reported time until next hour is negative.";
8fbca23d 319 fi
032f4b05 320
c2aaff78 321 try echo "$SECONDS_UNTIL_NEXT_HOUR"; # Report
8fbca23d 322
3395ae22 323 # Determine function return code
8fbca23d
SBS
324 if [[ "$returnState" = "true" ]]; then
325 return 0;
3395ae22 326 elif [[ "$returnState" = "warning_zero" ]]; then
8fbca23d 327 return 1;
3395ae22 328 elif [[ "$returnState" = "warning_negative" ]]; then
8fbca23d
SBS
329 return 2;
330 fi
c2aaff78 331} # Report seconds until next hour
8fbca23d
SBS
332dateTimeShort(){
333 # Desc: Timestamp without separators (YYYYmmddTHHMMSS+zzzz)
334 # Usage: dateTimeShort
335 # Output: stdout: timestamp (ISO-8601, no separators)
c2aaff78 336 local TIME_CURRENT TIME_CURRENT_SHORT
8fbca23d
SBS
337 TIME_CURRENT="$(date --iso-8601=seconds)" ; # Produce `date`-parsable current timestamp with resolution of 1 second.
338 TIME_CURRENT_SHORT="$(date -d "$TIME_CURRENT" +%Y%m%dT%H%M%S%z)"; # Produce separator-less current timestamp with resolution 1 second.
339 echo "$TIME_CURRENT_SHORT";
6c30388f
SBS
340} # Get YYYYmmddTHHMMSS±zzzz
341dateShort(){
342 # Desc: Date without separators (YYYYmmdd)
343 # Usage: dateShort
344 # Output: stdout: date (ISO-8601, no separators)
345 local TIME_CURRENT DATE_CURRENT_SHORT
346 TIME_CURRENT="$(date --iso-8601=seconds)" ; # Produce `date`-parsable current timestamp with resolution of 1 second.
347 DATE_CURRENT_SHORT="$(date -d "$TIME_CURRENT" +%Y%m%d)"; # Produce separator-less current date with resolution 1 day.
348 echo "$DATE_CURRENT_SHORT";
349} # Get YYYYmmdd
350timeDuration(){
351 # Desc: Output approximate time duration string before given time (default:current date)
352 # Ref/Attrib: ISO-8601:2004(E), §4.4.4.2 Representations of time intervals by duration and context information
353 # Note: "1 month" ("P1M") is assumed to be "30 days" (see ISO-8601:2004(E), §2.2.1.2)
354 # Usage: timeDuration [arg1] ([arg2])
3395ae22 355 # Version: 1.0.1
6c30388f
SBS
356 # Input: arg1: seconds as base 10 integer >= 0 (ex: 3601)
357 # arg2: precision level (optional; default=2)
358 # Output: stdout: ISO-8601 duration string (ex: "P1H1S", "P2Y10M15DT10H30M20S")
359 # Example: 'timeDuration 111111 3' yields 'P1DT6H51M'
3395ae22
SBS
360 # Depends: date 8 (gnucoreutils), yell,
361 local returnState ARG1 ARG2 remainder precision witherPrecision
362 local fullYears fullMonths fullDays fullHours fullMinutes fullSeconds
363 local displayYears displayMonths displayDays displayHours displayMinutes displaySeconds
364 local hasYears hasMonths hasDays hasHours hasMinutes hasSeconds
365
6c30388f
SBS
366 ARG1="$1";
367 ARG2="$2";
368 precision=2; # set default precision
369 returnState="true"; # set default return state
370
371 # Check that between one and two arguments is supplied
372 if ! { [[ $# -ge 1 ]] && [[ $# -le 2 ]]; }; then
373 yell "ERROR:Invalid number of arguments:$# . Exiting.";
374 returnState="ERROR_INPUT"; fi
375
376 # Check that arg1 provided
377 if [[ $# -ge 1 ]]; then
3395ae22 378 ## Check that arg1 is a positive integer
6c30388f 379 if [[ "$ARG1" =~ ^[[:digit:]]+$ ]]; then
3395ae22 380 :
6c30388f
SBS
381 else
382 yell "ERROR:ARG1 not a digit.";
383 returnState="ERROR_INPUT";
6c30388f
SBS
384 fi
385 else
386 yell "ERROR:No argument provided. Exiting.";
387 exit 1;
388 fi
389
390 # Consider whether arg2 was provided
391 if [[ $# -eq 2 ]]; then
392 # Check that the second arg is a positive integer
3395ae22 393 if [[ "$ARG2" =~ ^[[:digit:]]+$ ]] && [[ "$ARG2" -gt 0 ]]; then
6c30388f
SBS
394 precision="$ARG2";
395 else
396 yell "ERROR:ARG2 not a positive integer. (is $ARG2 ). Leaving early.";
397 returnState="ERROR_INPUT";
6c30388f
SBS
398 fi;
399 else
3395ae22 400 :
6c30388f
SBS
401 fi;
402
403 remainder="$ARG1" ; # seconds
404 ## Calculate full years Y, update remainder
405 fullYears=$(( remainder / (365*24*60*60) ));
406 remainder=$(( remainder - (fullYears*365*24*60*60) ));
407 ## Calculate full months M, update remainder
408 fullMonths=$(( remainder / (30*24*60*60) ));
409 remainder=$(( remainder - (fullMonths*30*24*60*60) ));
410 ## Calculate full days D, update remainder
411 fullDays=$(( remainder / (24*60*60) ));
412 remainder=$(( remainder - (fullDays*24*60*60) ));
413 ## Calculate full hours H, update remainder
414 fullHours=$(( remainder / (60*60) ));
415 remainder=$(( remainder - (fullHours*60*60) ));
416 ## Calculate full minutes M, update remainder
417 fullMinutes=$(( remainder / (60) ));
418 remainder=$(( remainder - (fullMinutes*60) ));
419 ## Calculate full seconds S, update remainder
420 fullSeconds=$(( remainder / (1) ));
421 remainder=$(( remainder - (remainder*1) ));
422 ## Check which fields filled
423 if [[ $fullYears -gt 0 ]]; then hasYears="true"; else hasYears="false"; fi
424 if [[ $fullMonths -gt 0 ]]; then hasMonths="true"; else hasMonths="false"; fi
425 if [[ $fullDays -gt 0 ]]; then hasDays="true"; else hasDays="false"; fi
426 if [[ $fullHours -gt 0 ]]; then hasHours="true"; else hasHours="false"; fi
427 if [[ $fullMinutes -gt 0 ]]; then hasMinutes="true"; else hasMinutes="false"; fi
428 if [[ $fullSeconds -gt 0 ]]; then hasSeconds="true"; else hasSeconds="false"; fi
429
430 ## Determine which fields to display (see ISO-8601:2004 §4.4.3.2)
431 witherPrecision="false"
432
433 ### Years
434 if $hasYears && [[ $precision -gt 0 ]]; then
435 displayYears="true";
436 witherPrecision="true";
437 else
438 displayYears="false";
439 fi;
440 if $witherPrecision; then ((precision--)); fi;
441
442 ### Months
443 if $hasMonths && [[ $precision -gt 0 ]]; then
444 displayMonths="true";
445 witherPrecision="true";
446 else
447 displayMonths="false";
448 fi;
449 if $witherPrecision && [[ $precision -gt 0 ]]; then
450 displayMonths="true";
451 fi;
452 if $witherPrecision; then ((precision--)); fi;
453
454 ### Days
455 if $hasDays && [[ $precision -gt 0 ]]; then
456 displayDays="true";
457 witherPrecision="true";
458 else
459 displayDays="false";
460 fi;
461 if $witherPrecision && [[ $precision -gt 0 ]]; then
462 displayDays="true";
463 fi;
464 if $witherPrecision; then ((precision--)); fi;
465
466 ### Hours
467 if $hasHours && [[ $precision -gt 0 ]]; then
468 displayHours="true";
469 witherPrecision="true";
470 else
471 displayHours="false";
472 fi;
473 if $witherPrecision && [[ $precision -gt 0 ]]; then
474 displayHours="true";
475 fi;
476 if $witherPrecision; then ((precision--)); fi;
477
478 ### Minutes
479 if $hasMinutes && [[ $precision -gt 0 ]]; then
480 displayMinutes="true";
481 witherPrecision="true";
482 else
483 displayMinutes="false";
484 fi;
485 if $witherPrecision && [[ $precision -gt 0 ]]; then
486 displayMinutes="true";
487 fi;
488 if $witherPrecision; then ((precision--)); fi;
489
490 ### Seconds
491
492 if $hasSeconds && [[ $precision -gt 0 ]]; then
493 displaySeconds="true";
494 witherPrecision="true";
495 else
496 displaySeconds="false";
497 fi;
498 if $witherPrecision && [[ $precision -gt 0 ]]; then
499 displaySeconds="true";
500 fi;
501 if $witherPrecision; then ((precision--)); fi;
502
503
504
505 ## Determine whether or not the "T" separator is needed to separate date and time elements
506 if ( $displayHours || $displayMinutes || $displaySeconds); then
507 displayDateTime="true"; else displayDateTime="false"; fi
508
509 ## Construct duration output string
510 OUTPUT="P"
511 if $displayYears; then
512 OUTPUT=$OUTPUT$fullYears"Y"; fi
513 if $displayMonths; then
514 OUTPUT=$OUTPUT$fullMonths"M"; fi
515 if $displayDays; then
516 OUTPUT=$OUTPUT$fullDays"D"; fi
517 if $displayDateTime; then
518 OUTPUT=$OUTPUT"T"; fi
519 if $displayHours; then
520 OUTPUT=$OUTPUT$fullHours"H"; fi
521 if $displayMinutes; then
522 OUTPUT=$OUTPUT$fullMinutes"M"; fi
523 if $displaySeconds; then
524 OUTPUT=$OUTPUT$fullSeconds"S"; fi
525
526 ## Output duration string to stdout
527 if [[ "$returnState" = "true" ]]; then echo "$OUTPUT"; fi
528
529 #===Determine function return code===
530 if [ "$returnState" = "true" ]; then
531 return 0;
532 else
533 echo "$returnState" 1>&2;
534 return 1;
535 fi
536
537} # Get duration (ex: PT10M4S )
538displayMissing() {
539 # Desc: Displays missing apps, files, and dirs
540 # Usage: displayMissing
541 # Input: associative arrays: appRollCall, fileRollCall, dirRollCall
542 # Output: stderr messages
543 #==BEGIN Display errors==
544 #===BEGIN Display Missing Apps===
545 missingApps="Missing apps :"
546 #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done
547 for key in "${!appRollCall[@]}"; do
548 value="${appRollCall[$key]}"
549 if [ "$value" = "false" ]; then
550 #echo "DEBUG:Missing apps: $key => $value";
551 missingApps="$missingApps""$key "
552 appMissing="true"
553 fi
554 done
555 if [ "$appMissing" = "true" ]; then # Only indicate if an app is missing.
556 echo "$missingApps" 1>&2;
557 fi
558 #===END Display Missing Apps===
559
560 #===BEGIN Display Missing Files===
561 missingFiles="Missing files:"
562 #for key in "${!fileRollCall[@]}"; do echo "DEBUG:$key => ${fileRollCall[$key]}"; done
563 for key in "${!fileRollCall[@]}"; do
564 value="${fileRollCall[$key]}"
565 if [ "$value" = "false" ]; then
566 #echo "DEBUG:Missing files: $key => $value";
567 missingFiles="$missingFiles""$key "
568 fileMissing="true"
569 fi
570 done
571 if [ "$fileMissing" = "true" ]; then # Only indicate if an app is missing.
572 echo "$missingFiles" 1>&2;
573 fi
574 #===END Display Missing Files===
575
576 #===BEGIN Display Missing Directories===
577 missingDirs="Missing dirs:"
578 #for key in "${!dirRollCall[@]}"; do echo "DEBUG:$key => ${dirRollCall[$key]}"; done
579 for key in "${!dirRollCall[@]}"; do
580 value="${dirRollCall[$key]}"
581 if [ "$value" = "false" ]; then
582 #echo "DEBUG:Missing dirs: $key => $value";
583 missingDirs="$missingDirs""$key "
584 dirMissing="true"
585 fi
586 done
587 if [ "$dirMissing" = "true" ]; then # Only indicate if an dir is missing.
588 echo "$missingDirs" 1>&2;
589 fi
590 #===END Display Missing Directories===
591
592 #==END Display errors==
593} # Display missing apps, files, dirs
594setScriptTTL() {
595 #Desc: Sets script TTL
596 #Usage: setScriptTTL arg1
597 #Input: arg1: "day" or "hour"
598 #Output: scriptTTL
599 #Depends: timeUntilNextHour or timeUntilNextDay
600 local ARG1
601 ARG1="$1"
602 if [[ "$ARG1" = "day" ]]; then
603 # Set script lifespan to end at start of next day
604 if ! scriptTTL="$(timeUntilNextDay)"; then
605 if [[ "$scriptTTL" -eq 0 ]]; then
606 ((scriptTTL++)); # Add 1 because 0 would cause 'timeout' to never timeout.
607 else
608 yell "ERROR: timeUntilNextDay exit code $?"; exit 1;
609 fi;
610 fi;
611 elif [[ "$ARG1" = "hour" ]]; then
612 # Set script lifespan to end at start of next hour
613 if ! scriptTTL="$(timeUntilNextHour)"; then
614 if [[ "$scriptTTL" -eq 0 ]]; then
615 ((scriptTTL++)); # Add 1 because 0 would cause 'timeout' to never timeout.
616 else
617 yell "ERROR: timeUntilNextHour exit code $?"; exit 1;
618 fi;
619 fi;
620 else
621 yell "ERROR:Invalid argument for setScriptTTL function."; exit 1;
622 fi
623} # Seconds until next (day|hour).
f6fb18bd
SBS
624checkMakeTar() {
625 # Desc: Checks that a valid tar archive exists, creates one otherwise
626 # Usage: checkMakeTar [ path ]
2fc10824 627 # Version: 1.0.1
f6fb18bd 628 # Input: arg1: path of tar archive
2fc10824
SBS
629 # Output: exit code 0 : tar readable
630 # exit code 1 : tar missing; created
631 # exit code 2 : tar not readable; moved; replaced
f6fb18bd 632 # Depends: try, tar, date
2fc10824
SBS
633 local PATH_TAR returnFlag0 returnFlag1 returnFlag2
634 PATH_TAR="$1"
f6fb18bd
SBS
635
636 # Check if file is a valid tar archive
637 if tar --list --file="$PATH_TAR" 1>/dev/null 2>&1; then
638 ## T1: return success
2fc10824 639 returnFlag0="tar valid";
f6fb18bd
SBS
640 else
641 ## F1: Check if file exists
642 if [[ -f "$PATH_TAR" ]]; then
643 ### T: Rename file
2fc10824
SBS
644 try mv "$PATH_TAR" "$PATH_TAR""--broken--""$(date +%Y%m%dT%H%M%S)" && \
645 returnFlag1="tar moved";
f6fb18bd
SBS
646 else
647 ### F: -
648 :
649 fi
650 ## F2: Create tar archive, return 0
2fc10824
SBS
651 try tar --create --file="$PATH_TAR" --files-from=/dev/null && \
652 returnFlag2="tar created";
653 fi
654
655 # Determine function return code
656 if [[ "$returnFlag0" = "tar valid" ]]; then
f6fb18bd 657 return 0;
2fc10824
SBS
658 elif [[ "$returnFlag2" = "tar created" ]] && ! [[ "$returnFlag1" = "tar moved" ]]; then
659 return 1; # tar missing so created
660 elif [[ "$returnFlag2" = "tar created" ]] && [[ "$returnFlag1" = "tar moved" ]]; then
661 return 2; # tar not readable so moved; replaced
f6fb18bd
SBS
662 fi
663} # checks if arg1 is tar; creates one otherwise
66af6225
SBS
664appendArgTar(){
665 # Desc: Writes first argument to temporary file with arguments as options, then appends file to tar
666 # Usage: writeArg "$(echo "Data to be written.")" [name of file to be inserted] [tar path] [temp dir] ([cmd1] [cmd2] [cmd3] [cmd4]...)
667 # Input: arg1: data to be written
668 # arg2: file name of file to be inserted into tar
669 # arg3: tar archive path (must exist first)
670 # arg4: temporary working dir
671 # arg5+: command strings (ex: "gpsbabel -i nmea -f - -o kml -F - ")
672 # Output: file written to disk
673 # Example: decrypt multiple large files in parallel
674 # appendArgTar "$(cat /tmp/largefile1.gpg)" "largefile1" $HOME/archive.tar /tmp "gpg --decrypt" &
675 # appendArgTar "$(cat /tmp/largefile2.gpg)" "largefile2" $HOME/archive.tar /tmp "gpg --decrypt" &
676 # appendArgTar "$(cat /tmp/largefile3.gpg)" "largefile3" $HOME/archive.tar /tmp "gpg --decrypt" &
66af6225
SBS
677 # Depends: bash 5
678
d9fe1eba
SBS
679 # Save function name
680 local FN="${FUNCNAME[0]}"
681 yell "DEBUG:STATUS:$FN:Finished appendArgTar()."
682
66af6225 683 # Set file name
d9fe1eba 684 if ! [ -z "$2" ]; then FILENAME="$2"; else yell "ERROR:$FN:Not enough arguments."; exit 1; fi
66af6225
SBS
685
686 # Check tar path is a file
d9fe1eba 687 if [ -f "$3" ]; then TAR_PATH="$3"; else yell "ERROR:$FN:Tar archive arg not a file."; exit 1; fi
66af6225
SBS
688
689 # Check temp dir arg
d9fe1eba 690 if ! [ -z "$4" ]; then TMP_DIR="$4"; else yell "ERROR:$FN:No temporary working dir set."; exit 1; fi
66af6225
SBS
691
692 # Set command strings
693 if ! [ -z "$5" ]; then CMD1="$5"; else CMD1="tee /dev/null "; fi # command string 1
694 if ! [ -z "$6" ]; then CMD2="$6"; else CMD2="tee /dev/null "; fi # command string 2
695 if ! [ -z "$7" ]; then CMD3="$7"; else CMD3="tee /dev/null "; fi # command string 3
696 if ! [ -z "$8" ]; then CMD4="$8"; else CMD4="tee /dev/null "; fi # command string 4
697
698 # Debug
d9fe1eba
SBS
699 yell "STATUS:$FN:CMD1:$CMD1"
700 yell "STATUS:$FN:CMD2:$CMD2"
701 yell "STATUS:$FN:CMD3:$CMD3"
702 yell "STATUS:$FN:CMD4:$CMD4"
703 yell "STATUS:$FN:FILENAME:$FILENAME"
704 yell "STATUS:$FN:TAR_PATH:$TAR_PATH"
705 yell "STATUS:$FN:TMP_DIR:$TMP_DIR"
66af6225
SBS
706 # Write to temporary working dir
707 echo "$1" | $CMD1 | $CMD2 | $CMD3 | $CMD4 > "$TMP_DIR"/"$FILENAME";
708
709 # Append to tar
710 try tar --append --directory="$TMP_DIR" --file="$TAR_PATH" "$FILENAME";
d9fe1eba 711 yell "DEBUG:STATUS:$FN:Finished appendArgTar()."
66af6225 712} # Append Bash var to file appended to Tar archive
3395ae22
SBS
713magicWriteVersion() {
714 # Desc: Appends time-stamped VERSION to PATHOUT_TAR
715 # Usage: magicWriteVersion
716 # Input: CONTENT_VERSION, FILEOUT_VERSION, PATHOUT_TAR, DIR_TMP
717 # Depends: dateTimeShort, appendArgTar
4c0c5850 718 local CONTENT_VERSION
3395ae22
SBS
719
720 # Generate VERSION file in BashVar
721 FILEOUT_VERSION="$(dateTimeShort)..VERSION";
4c0c5850
SBS
722 CONTENT_VERSION="VERSION=$SCRIPT_VERSION";
723 CONTENT_VERSION="$CONTENT_VERSION""\n""SCRIPT_NAME=SCRIPT_NAME";
724 CONTENT_VERSION="$CONTENT_VERSION""\n""DATE=$(date --iso-8601=seconds)";
725 CONTENT_VERSION="$CONTENT_VERSION""\n""HOSTNAME=$SCRIPT_HOSTNAME";
726 CONTENT_VERSION="$(echo -e "$CONTENT_VERSION")"
727
3395ae22
SBS
728 # Create BashVar as file FILEOUT_VERSION and write-append to PATHOUT_TAR
729 appendArgTar "$CONTENT_VERSION" "$FILEOUT_VERSION" "$PATHOUT_TAR" "$DIR_TMP";
730} # bkgpslog: write version data to PATHOUT_TAR via appendArgTar()
66af6225
SBS
731magicWriteBuffer() {
732 # Desc: bkgpslog-specific meta function for writing data to DIR_TMP then appending each file to PATHOUT_TAR
f6fb18bd
SBS
733 # Inputs: PATHOUT_TAR FILEOUT_{NMEA,GPX,KML} CMD_CONV_{NMEA,GPX,KML} CMD_{COMPRESS,ENCRYPT} DIR_TMP
734 # Depends: yell, try, vbm, appendArgTar, tar
1b0e6227 735 local FN="${FUNCNAME[0]}";
872c737e 736 wait; # Wait to avoid collision with older magicWriteBuffer() instances (see https://www.tldp.org/LDP/abs/html/x9644.html )
f6fb18bd
SBS
737 vbm "DEBUG:STATUS:$FN:Started magicWriteBuffer().";
738
3395ae22
SBS
739 # Validate PATHOUT_TAR as tar.
740 checkMakeTar "$PATHOUT_TAR";
741 ## Add VERSION file if checkMakeTar had to create a tar (exited 1) or replace one (exited 2)
742 if [[ $? -eq 1 ]] || [[ $? -eq 2 ]]; then magicWriteVersion; fi
f6fb18bd
SBS
743
744 # Write bufferBash to PATHOUT_TAR
66af6225 745 appendArgTar "$bufferBash" "$FILEOUT_NMEA" "$PATHOUT_TAR" "$DIR_TMP" "$CMD_CONV_NMEA" "$CMD_COMPRESS" "$CMD_ENCRYPT"; # Write NMEA data
8e83fee8
SBS
746 appendArgTar "$bufferBash" "$FILEOUT_GPX" "$PATHOUT_TAR" "$DIR_TMP" "$CMD_CONV_GPX" "$CMD_COMPRESS" "$CMD_ENCRYPT"; # Write GPX file
747 appendArgTar "$bufferBash" "$FILEOUT_KML" "$PATHOUT_TAR" "$DIR_TMP" "$CMD_CONV_KML" "$CMD_COMPRESS" "$CMD_ENCRYPT"; # Write KML file
e0452100
SBS
748 # Remove secured chunks from DIR_TMP
749 try rm "$PATHOUT_NMEA" "$PATHOUT_GPX" "$PATHOUT_KML";
1b0e6227 750 yell "DEBUG:STATUS:$FN:Finished magicWriteBuffer().";
66af6225
SBS
751} # bkgpslog write function
752
032f4b05 753main() {
0b3dde05 754 processArguments "$@" # Process arguments.
cfc25c90 755
aa2a49f1 756 # Determine working directory
cfc25c90
SBS
757 ## Set DIR_TMP_PARENT to user-specified value if specified
758 if [[ "$OPTION_TMPDIR" = "true" ]]; then
759 if [[ -d "$TMP_DIR_PRIORITY" ]]; then
760 DIR_TMP_PARENT="$OPTION_TMPDIR";
761 else
66af6225 762 yell "WARNING:Specified temporary working directory not valid:$OPTION_TMPDIR";
cfc25c90
SBS
763 exit 1;
764 fi
765 fi
766
767 ## Set DIR_TMP_PARENT to default or fallback otherwise
aa2a49f1 768 if [[ -d "$DIR_TMP_DEFAULT" ]]; then
cfc25c90
SBS
769 DIR_TMP_PARENT="$DIR_TMP_DEFAULT";
770 elif [[ -d /tmp ]]; then
771 yell "WARNING:/dev/shm not available. Falling back to /tmp .";
772 DIR_TMP_PARENT="/tmp";
aa2a49f1
SBS
773 else
774 yell "ERROR:No valid working directory available. Exiting.";
775 exit 1;
776 fi
cfc25c90
SBS
777
778 ## Set DIR_TMP using DIR_TMP_PARENT and nonce (SCRIPT_TIME_START)
0f4d2d90 779 DIR_TMP="$DIR_TMP_PARENT"/"$SCRIPT_TIME_START""..bkgpslog" && vbm "DEBUG:Set DIR_TMP to:$DIR_TMP"; # Note: removed at end of main().
aa2a49f1 780
6c30388f 781 # Set output encryption and compression option strings
17d49005
SBS
782 if [[ "$OPTION_ENCRYPT" = "true" ]]; then # Check if encryption option active.
783 if checkapp age; then # Check that age is available.
784 for pubkey in "${recPubKeys[@]}"; do # Validate recipient pubkey strings by forming test message
785 vbm "DEBUG:Testing pubkey string:$pubkey"
408a342b 786 if echo "butts" | age -a -r "$pubkey" 1>/dev/null; then
77361307
SBS
787 # Form age recipient string
788 recipients="$recipients""-r $pubkey ";
405ce7df 789 vbm "STATUS:Added pubkey for forming age recipient string:""$pubkey";
77361307 790 vbm "DEBUG:recipients:""$recipients";
408a342b
SBS
791 else
792 yell "ERROR:Exit code ""$?"". Invalid recipient pubkey string. Exiting."; exit 1;
77361307 793 fi
17d49005 794 done
77361307 795 vbm "DEBUG:Finished processing recPubKeys array";
408a342b 796 # Form age command string
c97313bf 797 CMD_ENCRYPT="age ""$recipients ";
408a342b 798 CMD_ENCRYPT_SUFFIX=".age";
17d49005
SBS
799 else
800 yell "ERROR:Encryption enabled but \"age\" not found. Exiting."; exit 1;
801 fi
408a342b 802 else
c97313bf 803 CMD_ENCRYPT="tee /dev/null ";
408a342b
SBS
804 CMD_ENCRYPT_SUFFIX="";
805 vbm "DEBUG:Encryption not enabled."
17d49005 806 fi
408a342b
SBS
807 if [[ "$OPTION_COMPRESS" = "true" ]]; then # Check if compression option active
808 if checkapp gzip; then # Check if gzip available
c97313bf 809 CMD_COMPRESS="gzip ";
408a342b
SBS
810 CMD_COMPRESS_SUFFIX=".gz";
811 else
812 yell "ERROR:Compression enabled but \"gzip\" not found. Exiting."; exit 1;
286d9825 813 fi
408a342b 814 else
c97313bf 815 CMD_COMPRESS="tee /dev/null ";
408a342b 816 CMD_COMPRESS_SUFFIX="";
1b0e6227 817 vbm "DEBUG:Compression not enabled.";
408a342b 818 fi
032f4b05 819
6c30388f
SBS
820 # Check that critical apps and dirs are available, displag missing ones.
821 if ! checkapp gpspipe tar && ! checkdir "$DIR_OUT" "/dev/shm"; then
822 yell "ERROR:Critical components missing.";
823 displayMissing; yell "Exiting."; exit 1; fi
824
825 # Set script lifespan
3395ae22 826 setScriptTTL "$SCRIPT_TTL"; # seconds until next new SCRIPT_TTL (ex: "day" or "hour")
6c30388f
SBS
827
828 # File name substring: encoded bufferTTL
829 bufferTTL_STR="$(timeDuration $BUFFER_TTL)";
830
831 # Init temp working dir
3a7b92f8 832 try mkdir "$DIR_TMP" && vbm "DEBUG:Working dir creatd at:$DIR_TMP";
6c30388f
SBS
833
834 # Initialize 'tar' archive
835 ## Define output tar path (note: each day gets *one* tar file (Ex: "20200731..hostname_location.[.gpx.gz].tar"))
9efeccb5
SBS
836 PATHOUT_TAR="$DIR_OUT"/"$(dateShort)".."$SCRIPT_HOSTNAME""_location""$CMD_COMPRESS_SUFFIX""$CMD_ENCRYPT_SUFFIX".tar && \
837 vbm "STATUS:Set PATHOUT_TAR to:$PATHOUT_TAR";
f6fb18bd
SBS
838 ## Check that PATHOUT_TAR is a tar. Rename old and create empty one otherwise.
839 checkMakeTar "$PATHOUT_TAR" && vbm "DEBUG:Confirmed or Created to be a tar:$PATHOUT_TAR";
6c30388f 840 ## Append VERSION file to PATHOUT_TAR
3395ae22 841 magicWriteVersion;
6c30388f
SBS
842
843 # Record gps data until script lifespan ends
844 declare debugCounter; debugCounter="0"; # set debug counter
6c30388f 845 while [[ "$SECONDS" -lt "$scriptTTL" ]]; do
29ef133a 846 timeBufferStart="$(dateTimeShort)"; # Note start time
6c30388f 847 # Determine file paths (time is start of buffer period)
29ef133a 848 FILEOUT_BASENAME="$timeBufferStart""--""$bufferTTL_STR""..""$SCRIPT_HOSTNAME""_location" && vbm "STATUS:Set FILEOUT_BASENAME to:$FILEOUT_BASENAME";
aa2a49f1 849 ## Files saved to DIR_TMP
1b0e6227
SBS
850 FILEOUT_NMEA="$FILEOUT_BASENAME".nmea"$CMD_COMPRESS_SUFFIX""$CMD_ENCRYPT_SUFFIX" && vbm "STATUS:Set FILEOUT_NMEA to:$FILEOUT_NMEA";
851 FILEOUT_GPX="$FILEOUT_BASENAME".gpx"$CMD_COMPRESS_SUFFIX""$CMD_ENCRYPT_SUFFIX" && vbm "STATUS:Set FILEOUT_GPX to:$FILEOUT_GPX";
852 FILEOUT_KML="$FILEOUT_BASENAME".kml"$CMD_COMPRESS_SUFFIX""$CMD_ENCRYPT_SUFFIX" && vbm "STATUS:Set FILEOUT_KML to:$FILEOUT_KML";
66af6225
SBS
853 PATHOUT_NMEA="$DIR_TMP"/"$FILEOUT_NMEA" && vbm "STATUS:Set PATHOUT_NMEA to:$PATHOUT_NMEA";
854 PATHOUT_GPX="$DIR_TMP"/"$FILEOUT_GPX" && vbm "STATUS:Set PATHOUT_GPX to:$PATHOUT_GPX";
855 PATHOUT_KML="$DIR_TMP"/"$FILEOUT_KML" && vbm "STATUS:Set PATHOUT_KML to:$PATHOUT_KML";
6c30388f
SBS
856 ## Files saved to disk (DIR_OUT)
857 ### one file per day (Ex: "20200731..hostname_location.[.gpx.gz].tar")
9e75f849 858 PATHOUT_TAR="$DIR_OUT"/"$(dateShort)".."$SCRIPT_HOSTNAME""_location""$CMD_COMPRESS_SUFFIX""$CMD_ENCRYPT_SUFFIX".tar && \
1b0e6227 859 vbm "STATUS:Set PATHOUT_TAR to:$PATHOUT_TAR";
6c30388f 860 # Define GPS conversion commands
405ce7df 861 CMD_CONV_NMEA="tee /dev/null " && vbm "STATUS:Set CMD_CONV_NMEA to:$CMD_CONV_NMEA"; # tee as passthrough
66af6225
SBS
862 CMD_CONV_GPX="gpsbabel -i nmea -f - -o gpx -F - " && vbm "STATUS:Set CMD_CONV_GPX to:$CMD_CONV_GPX"; # convert NMEA to GPX
863 CMD_CONV_KML="gpsbabel -i nmea -f - -o kml -F - " && vbm "STATUS:Set CMD_CONV_KML to:$CMD_CONV_KML"; # convert NMEA to KML
6c30388f 864 # Fill Bash variable buffer
18490e2b 865 bufferBash="$(timeout "$BUFFER_TTL""s" gpspipe -r)" && vbm "STATUS:Successfully filled bufferBash variable with gpspipe data."; # Record gpspipe nmea data to buffer for bufferTTL seconds
6c30388f 866 # Process bufferBash, save secured chunk set to DIR_TMP
18490e2b 867 vbm "STATUS:Beginning to save data to $DIR_TMP";
66af6225 868 magicWriteBuffer &
6c30388f 869 # Append each secured chunk in memory dir (DIR_TMP) to file on disk (PATHOUT_TAR in DIR_OUT)
405ce7df
SBS
870 vbm "STATUS:DIR_TMP :$DIR_TMP";
871 vbm "STATUS:PATHOUT_TAR :$PATHOUT_TAR";
872 vbm "STATUS:PATHOUT_NMEA:$PATHOUT_NMEA";
66af6225
SBS
873 vbm "STATUS:PATHOUT_GPX:$PATHOUT_GPX";
874 vbm "STATUS:PATHOUT_KML:$PATHOUT_KML";
e0452100 875
6c30388f 876 # Reset buffer and filenames
29ef133a 877 unset bufferBash FILEOUT_BASENAME PATHOUT_NMEA PATHOUT_GPX PATHOUT_KML PATHOUT_TAR timeBufferStart;
18490e2b 878 vbm "DEBUG:Completed buffer session $debugCounter ." 1>&2;
6c30388f
SBS
879 ((debugCounter++))
880 done
cfc25c90
SBS
881
882 # Remove DIR_TMP
883 try rm -r "$DIR_TMP";
0aabe6a3 884
1b0e6227 885 vbm "STATUS:Main function finished.";
8fbca23d
SBS
886} # Main function.
887#===END Declare local script functions===
888#==END Define script parameters==
032f4b05
SBS
889
890
8fbca23d
SBS
891#==BEGIN Perform work and exit==
892main "$@" # Run main function.
893exit 0;
894#==END Perform work and exit==