From d2dff7f5219c07bc73b59bf992c05dd24f83f3e5 Mon Sep 17 00:00:00 2001 From: "Brandon McGinty (deepseek)" Date: Fri, 14 Aug 2026 12:29:42 -0400 Subject: [PATCH] Add barnard-ui session logging and wormhole log sharing --- barnard-ui | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 1 deletion(-) diff --git a/barnard-ui b/barnard-ui index 1ddf162..07e5d8d 100755 --- a/barnard-ui +++ b/barnard-ui @@ -38,6 +38,10 @@ configDir="$HOME/.config/barnard" serverFile="$configDir/servers.conf" certFile="$configDir/barnard.pem" logFile="$cacheDir/${0##*/}.log" +logDir="$HOME/barnard-logs" +logPrefsFile="$configDir/logging.conf" +sessionLogFile="" +saveSessionLogs=0 if ! mkdir -p "$cacheDir" "$configDir"; then printf 'Could not create Barnard configuration directories.\n' >&2 @@ -64,6 +68,9 @@ log() { local line while IFS= read -r line ; do printf '%s\n' "$line" >> "$logFile" + if [[ -n "$sessionLogFile" ]]; then + printf '%s\n' "$line" >> "$sessionLogFile" + fi done } @@ -141,6 +148,12 @@ trim() { printf '%s' "$value" } +sanitize_filename() { + local value="$1" + value="${value//[^[:alnum:]_.-]/_}" + printf '%s' "$value" +} + field_is_valid() { local value="$1" [[ "$value" != *$'\n'* && "$value" != *$'\r'* ]] @@ -376,6 +389,139 @@ config_has_nonempty_value() { return 1 } +load_logging_pref() { + local line + local key + local value + saveSessionLogs=0 + + [[ -r "$logPrefsFile" ]] || return 0 + while IFS= read -r line || [[ -n "$line" ]]; do + line="$(trim "$line")" + [[ -z "$line" || "$line" == \#* || "$line" != *=* ]] && continue + key="${line%%=*}" + key="$(trim "$key")" + key="${key,,}" + value="${line#*=}" + value="$(trim "$value")" + case "$key" in + savesessionlogs) + if [[ "$value" == "1" || "$value" == "true" || "$value" == "yes" ]]; then + saveSessionLogs=1 + fi + ;; + esac + done < "$logPrefsFile" +} + +save_logging_pref() { + local tmpFile="$logPrefsFile.tmp" + if ! printf 'saveSessionLogs=%s\n' "$saveSessionLogs" > "$tmpFile"; then + rm -f "$tmpFile" + msgbox "$(gettext "Could not save logging preference.")" + return 1 + fi + chmod 600 "$tmpFile" 2> /dev/null || true + if ! mv "$tmpFile" "$logPrefsFile"; then + rm -f "$tmpFile" + msgbox "$(gettext "Could not save logging preference.")" + return 1 + fi +} + +toggle-session-logging() { + local question + if (( saveSessionLogs )); then + question="$(gettext "Session logging is currently enabled. Disable it?")" + else + question="$(gettext "Session logging is currently disabled. Enable saving logs to the logs directory?")" + fi + if [[ "$(yesno "$question")" == "Yes" ]]; then + if (( saveSessionLogs )); then + saveSessionLogs=0 + else + saveSessionLogs=1 + fi + save_logging_pref + fi +} + +send-logs() { + local bundle + local outputFile + local code + local wormholePid + local status + local i + local detail + + if ! command -v wormhole > /dev/null 2>&1; then + msgbox "$(gettext "Required command not found:") wormhole" + return + fi + if ! command -v tar > /dev/null 2>&1; then + msgbox "$(gettext "Required command not found:") tar" + return + fi + if [[ ! -d "$logDir" ]] || ! compgen -G "$logDir"/*.log > /dev/null 2>&1; then + msgbox "$(gettext "No logs to send. Logs are saved to:") $logDir" + return + fi + + bundle="$cacheDir/barnard-logs-$(date +%Y%m%d-%H%M%S).tar.gz" + if ! tar -czf "$bundle" -C "$logDir" . 2> /dev/null; then + msgbox "$(gettext "Could not create log archive.")" + return + fi + + outputFile="$cacheDir/wormhole-$$.txt" + wormhole send "$bundle" > "$outputFile" 2>&1 & + wormholePid=$! + + code="" + for (( i = 0; i < 40; i++ )); do + sleep 0.25 + code="$(grep -Eo '[0-9]+-[a-z]+-[a-z]+' "$outputFile" 2> /dev/null | head -n1)" + [[ -n "$code" ]] && break + kill -0 "$wormholePid" 2> /dev/null || break + done + + if [[ -n "$code" ]]; then + msgbox "$(gettext "Wormhole code:") $code" + wait "$wormholePid" + status=$? + if (( status == 0 )); then + msgbox "$(gettext "Logs sent successfully.")" + else + msgbox "$(gettext "Log transfer did not complete successfully.")" + fi + else + kill "$wormholePid" 2> /dev/null || true + wait "$wormholePid" 2> /dev/null || true + detail="$(tail -n 3 "$outputFile" 2> /dev/null)" + if [[ -n "$detail" ]]; then + msgbox "$(gettext "Could not start wormhole transfer:") $detail" + else + msgbox "$(gettext "Could not start wormhole transfer.")" + fi + fi + + rm -f "$outputFile" "$bundle" +} + +manage-logs() { + local action + + while : ; do + action="$(menulist "$(gettext "Toggle session logging")" "$(gettext "Send logs with wormhole")" "$(gettext "Go Back")")" || return + case "$action" in + "$(gettext "Toggle session logging")") toggle-session-logging ;; + "$(gettext "Send logs with wormhole")") send-logs ;; + "$(gettext "Go Back")"|"") return ;; + esac + done +} + add-server() { local serverName local serverAddress @@ -424,6 +570,7 @@ add-server() { connect() { local serverName local barnardStatus + local safeServerName local -a names=() local -a barnardArgs=() @@ -440,6 +587,20 @@ connect() { require_command barnard barnard + sessionLogFile="" + if (( saveSessionLogs )); then + safeServerName="$(sanitize_filename "$serverName")" + if ! mkdir -p "$logDir"; then + msgbox "$(gettext "Could not create logs directory:") $logDir" + else + sessionLogFile="$logDir/${safeServerName}-$(date +%F).log" + if ! : >> "$sessionLogFile"; then + msgbox "$(gettext "Could not write log file:") $sessionLogFile" + sessionLogFile="" + fi + fi + fi + barnardArgs=(-server "${serverAddresses[$serverName]}:${serverPorts[$serverName]}") if [[ -n "${serverPasswords[$serverName]}" ]]; then barnardArgs+=(-password "${serverPasswords[$serverName]}") @@ -456,6 +617,7 @@ connect() { command barnard "${barnardArgs[@]}" --fifo "$configDir/cmd" --buffers 16 |& log barnardStatus=${PIPESTATUS[0]} + sessionLogFile="" if (( barnardStatus != 0 )); then msgbox "$(gettext "Barnard exited with status") $barnardStatus. $(gettext "See log:") $logFile" fi @@ -581,14 +743,16 @@ main() { require_command dialog dialog load_servers + load_logging_pref while : ; do - action="$(menulist "$(gettext "Connect")" "$(gettext "Add server")" "$(gettext "Remove server")" "$(gettext "Manage Certificate")" "$(gettext "Exit")")" || exit 0 + action="$(menulist "$(gettext "Connect")" "$(gettext "Add server")" "$(gettext "Remove server")" "$(gettext "Manage Certificate")" "$(gettext "Logs")" "$(gettext "Exit")")" || exit 0 case "$action" in "$(gettext "Connect")") connect ;; "$(gettext "Add server")") add-server ;; "$(gettext "Remove server")") remove-server ;; "$(gettext "Manage Certificate")") manage-certificate ;; + "$(gettext "Logs")") manage-logs ;; "$(gettext "Exit")"|"") exit 0 ;; esac done