From 8d015643ded1f5c982105ff6fed7dece632846e4 Mon Sep 17 00:00:00 2001 From: Anders Betts Date: Fri, 18 Sep 2026 13:15:37 +0200 Subject: bokftui: retry auto-login for 60s on reload, log and show the reason - whole chain (session, token, password) is retried while the server is unreachable, with an on-screen counter - the adopted connection is taken over instead of reconnecting - failures show the server error in a box and append to ~/.cache/bokf/tui.log for later diagnosis --- clients/bokftui.c | 172 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 124 insertions(+), 48 deletions(-) (limited to 'clients/bokftui.c') diff --git a/clients/bokftui.c b/clients/bokftui.c index 4895704..f111570 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "client.h" @@ -138,6 +139,8 @@ static char g_status[512]; static char g_server_version[32]; static int disp_width(const char *s); +static void tui_log(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); static void show_error(const char *title, const char *resp); static int64_t vouchers_new(struct app *a); @@ -3996,6 +3999,8 @@ static void do_reload(struct app *a, const char *self) setenv("BOKFD_SESSION", a->session, 1); if (a->password[0]) setenv("BOKFD_PASSWORD", a->password, 1); + tui_log("reload: screen=%s org=%lld fy=%lld", g_reload_scene, (long long)a->org, + (long long)a->fy); endwin(); execvp(argv[0], argv); fprintf(stderr, "bokftui: kunde inte ladda om: %s\n", strerror(errno)); @@ -4078,7 +4083,7 @@ static void config_path(char *buf, size_t n) static void config_mkdirs(const char *path) { - char tmp[512]; + char tmp[640]; snprintf(tmp, sizeof tmp, "%s", path); if (strlen(tmp) >= sizeof tmp) return; @@ -4129,13 +4134,38 @@ static void config_save(const struct app *a) chmod(path, 0600); } -static int server_reachable(const char *socket) +/* Small append-only log for connection/reload problems. */ +static void tui_log(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); + +static void tui_log(const char *fmt, ...) { - struct client_conn c; - if (client_connect(socket, &c) != 0) - return 0; - client_close(&c); - return 1; + char path[600], dir[512]; + const char *cache = getenv("XDG_CACHE_HOME"); + if (cache && *cache) + snprintf(dir, sizeof dir, "%s/bokf", cache); + else { + const char *home = getenv("HOME"); + snprintf(dir, sizeof dir, "%s/.cache/bokf", home && *home ? home : "."); + } + if (snprintf(path, sizeof path, "%s/tui.log", dir) >= (int)sizeof path) + return; + config_mkdirs(path); + FILE *f = fopen(path, "a"); + if (!f) + return; + time_t now = time(NULL); + struct tm tm; + gmtime_r(&now, &tm); + fprintf(f, "%04d-%02d-%02dT%02d:%02d:%02dZ ", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, + tm.tm_min, tm.tm_sec); + va_list ap; + va_start(ap, fmt); + vfprintf(f, fmt, ap); + va_end(ap); + fputc('\n', f); + fclose(f); } /* Connects and opens a session. Returns 0 on success, -2 when the @@ -4422,52 +4452,98 @@ int main(int argc, char **argv) const char *env_pass = getenv("BOKFD_PASSWORD"); int have_auto = (session_arg && *session_arg) || (token && *token) || (app.username[0] && env_pass && *env_pass); - if (have_auto) { - for (int i = 0; i < 30; i++) { - if (server_reachable(app.socket)) - break; - mvprintw(LINES / 2, 2, "Ansluter till servern... (%ds)", i + 1); - refresh(); - sleep(1); - } - } int stale_session = 0; - if (session_arg && *session_arg && - client_connect(app.socket, &app.conn) == 0) { - char *resp = - client_rpc(&app.conn, "session.whoami", session_arg, 0, NULL); - if (resp && client_ok(resp)) - snprintf(app.session, sizeof app.session, "%s", session_arg); - else { - stale_session = 1; - client_close(&app.conn); - } - free(resp); - } - - if (!app.session[0] && token && *token) { - char *err = NULL; - if (try_login(&app, NULL, NULL, token, &err) == 0) - config_save(&app); - else { - message("Token", "Token-inloggning misslyckades: %s", - err ? err : "okänt fel"); - free(err); + char *auto_err = NULL; + if (have_auto) { + tui_log("auto-login start (session=%d token=%d password=%d)", + session_arg && *session_arg ? 1 : 0, token && *token ? 1 : 0, + app.username[0] && env_pass && *env_pass ? 1 : 0); + for (int i = 0; i < 60 && !app.session[0]; i++) { + if (i > 0) { + mvprintw(LINES / 2, 2, "Återansluter till servern... (%ds)", + i); + refresh(); + sleep(1); + } + if (session_arg && *session_arg) { + struct client_conn c; + if (client_connect(app.socket, &c) != 0) + continue; + char *resp = client_rpc(&c, "session.whoami", session_arg, 0, + NULL); + if (resp && client_ok(resp)) { + app.conn = c; + snprintf(app.session, sizeof app.session, "%s", + session_arg); + free(resp); + tui_log("auto-login: reused session"); + break; + } + if (!resp) { + free(resp); + client_close(&c); + continue; + } + free(resp); + client_close(&c); + stale_session = 1; + session_arg = NULL; + tui_log("auto-login: session expired"); + } + if (token && *token) { + char *err = NULL; + int rc = try_login(&app, NULL, NULL, token, &err); + if (rc == 0) { + config_save(&app); + tui_log("auto-login: token ok"); + break; + } + token = NULL; + if (rc == -2) { + free(err); + continue; + } + tui_log("auto-login: token failed: %s", err ? err : "?"); + free(auto_err); + auto_err = err; + } + if (app.username[0] && env_pass && *env_pass) { + char *err = NULL; + int rc = try_login(&app, app.username, env_pass, NULL, &err); + if (rc == 0) { + snprintf(app.password, sizeof app.password, "%s", + env_pass); + config_save(&app); + tui_log("auto-login: password ok"); + break; + } + env_pass = NULL; + if (rc == -2) { + free(err); + continue; + } + tui_log("auto-login: password failed: %s", err ? err : "?"); + free(auto_err); + auto_err = err; + } + break; } + if (!app.session[0]) + tui_log("auto-login: giving up, login screen"); } - if (!app.session[0] && app.username[0] && env_pass && *env_pass) { - char *err = NULL; - if (try_login(&app, app.username, env_pass, NULL, &err) == 0) { - snprintf(app.password, sizeof app.password, "%s", env_pass); - config_save(&app); - } else { - message("Inloggning", "Automatisk inloggning misslyckades: %s", - err ? err : "okänt fel"); - free(err); + if (!app.session[0]) { + if (auto_err) { + char *code = jstr_dup(auto_err, "error.code"); + char *msg = jstr_dup(auto_err, "error.message"); + message("Återanslutning misslyckades", "%s: %s", + code ? code : "fel", msg ? msg : "okänt fel"); + free(code); + free(msg); + } else if (stale_session) { + message("Session", "Sessionen har gått ut, logga in igen."); } } - if (!app.session[0] && stale_session) - message("Session", "Sessionen har gått ut, logga in igen."); + free(auto_err); if (!app.session[0] && login_screen(&app) != 0) { endwin(); return 0; -- cgit v1.3