aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-18 13:15:37 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-18 13:15:37 +0200
commit8d015643ded1f5c982105ff6fed7dece632846e4 (patch)
tree25ed915927d2bdef773c0f81a240689e967b61d7
parent3ec5dbd52ed34e48fefee989b4ea9d095ab094a7 (diff)
downloadbokf-8d015643ded1f5c982105ff6fed7dece632846e4.tar.gz
bokf-8d015643ded1f5c982105ff6fed7dece632846e4.zip
bokftui: retry auto-login for 60s on reload, log and show the reasonv0.1.21
- 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
-rw-r--r--clients/bokftui.c172
1 files changed, 124 insertions, 48 deletions
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 <string.h>
#include <strings.h>
#include <sys/stat.h>
+#include <time.h>
#include <unistd.h>
#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;