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