+# Function to save which stage we are in, so we can restart an interrupted
+# dinstall. Or even run actions in parallel, if we dare to, by simply
+# backgrounding the call to this function. But that should only really be
+# done for things we don't care much about.
+#
+# This should be called with the first argument being an array, with the
+# members
+# - FUNC - the function name to call
+# - ARGS - Possible arguments to hand to the function. Can be the empty string
+# - TIME - The timestamp name. Can be the empty string
+# - ERR - if this is the string false, then the call will be surrounded by
+# set +e ... set -e calls, so errors in the function do not exit
+# dinstall. Can be the empty string, meaning true.
+#
+# MAKE SURE TO KEEP THIS THE LAST FUNCTION, AFTER ALL THE VARIOUS ONES
+# ADDED FOR DINSTALL FEATURES!
+function stage() {
+ ARGS='GO[@]'
+ local "${!ARGS}"
+
+ error=${ERR:-"true"}
+
+ STAGEFILE="${stagedir}/${FUNC}"
+ if [ -f "${STAGEFILE}" ]; then
+ stamptime=$(/usr/bin/stat -c %Z "${STAGEFILE}")
+ unixtime=$(date +%s)
+ difference=$(( $unixtime - $stamptime ))
+ if [ ${difference} -ge 14400 ]; then
+ log_error "Did already run ${FUNC}, stagefile exists, but that was ${difference} seconds ago. Please check."
+ else
+ log "Did already run ${FUNC}, not calling again..."
+ fi
+ return
+ fi
+
+ debug "Now calling function ${FUNC}. Arguments: ${ARGS}. Timestamp: ${TIME}"
+
+ # Make sure we are always at the same place. If a function wants to be elsewhere,
+ # it has to cd first!
+ cd ${configdir}
+
+ # Now redirect the output into $STAGEFILE.log. In case it errors out somewhere our
+ # errorhandler trap can then mail the contents of $STAGEFILE.log only, instead of a whole
+ # dinstall logfile. Short error mails ftw!
+ exec >> "${STAGEFILE}.log" 2>&1
+
+ if [ -f "${LOCK_STOP}" ]; then
+ log "${LOCK_STOP} exists, exiting immediately"
+ exit 42
+ fi
+
+ if [ "${error}" = "false" ]; then
+ set +e
+ fi
+ ${FUNC} ${ARGS}
+
+ # No matter what happened in the function, we make sure we have set -e default state back
+ set -e
+
+ # Make sure we are always at the same place.
+ cd ${configdir}
+
+ touch "${STAGEFILE}"
+
+ if [ -n "${TIME}" ]; then
+ ts "${TIME}"
+ fi
+
+ # And the output goes back to the normal logfile
+ exec >> "$LOGFILE" 2>&1
+
+ # Now we should make sure that we have a usable dinstall.log, so append the $STAGEFILE.log
+ # to it.
+ cat "${STAGEFILE}.log" >> "${LOGFILE}"
+ rm -f "${STAGEFILE}.log"
+
+ if [ -f "${LOCK_STOP}" ]; then
+ log "${LOCK_STOP} exists, exiting immediately"
+ exit 42
+ fi
+}