108 lines
2.6 KiB
C
108 lines
2.6 KiB
C
/**
|
|
* @file main.c
|
|
* @brief Trainlog TUI process entry point.
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "trainlog/database.h"
|
|
#include "trainlog/tui.h"
|
|
|
|
static int ensure_directory(const char *path)
|
|
{
|
|
if (mkdir(path, 0700) == 0 || errno == EEXIST) {
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int build_database_path(char *output, size_t output_size)
|
|
{
|
|
const char *xdg = getenv("XDG_DATA_HOME");
|
|
const char *home = getenv("HOME");
|
|
char base[PATH_MAX];
|
|
char trainlog_dir[PATH_MAX];
|
|
int written;
|
|
|
|
if (xdg != NULL && xdg[0] != '\0') {
|
|
written = snprintf(base, sizeof(base), "%s", xdg);
|
|
} else if (home != NULL && home[0] != '\0') {
|
|
written = snprintf(base, sizeof(base), "%s/.local/share", home);
|
|
} else {
|
|
return -1;
|
|
}
|
|
|
|
if (written < 0 || (size_t)written >= sizeof(base)) {
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Creating ~/.local and ~/.local/share recursively would normally require
|
|
* a generic mkdir -p helper. On Arch these parents already exist for a
|
|
* desktop user; XDG_DATA_HOME custom paths are likewise expected to have
|
|
* their parent created by the user.
|
|
*/
|
|
if (ensure_directory(base) != 0 && errno != EEXIST) {
|
|
/* Continue only when the base already exists. */
|
|
struct stat info;
|
|
if (stat(base, &info) != 0 || !S_ISDIR(info.st_mode)) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
written = snprintf(
|
|
trainlog_dir,
|
|
sizeof(trainlog_dir),
|
|
"%s/trainlog",
|
|
base
|
|
);
|
|
if (written < 0 || (size_t)written >= sizeof(trainlog_dir)) {
|
|
return -1;
|
|
}
|
|
|
|
if (ensure_directory(trainlog_dir) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
written = snprintf(
|
|
output,
|
|
output_size,
|
|
"%s/trainlog.db",
|
|
trainlog_dir
|
|
);
|
|
|
|
return written >= 0 && (size_t)written < output_size ? 0 : -1;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
char database_path[PATH_MAX];
|
|
TrainlogDatabase *database = NULL;
|
|
TrainlogStatus status;
|
|
int result;
|
|
|
|
if (build_database_path(database_path, sizeof(database_path)) != 0) {
|
|
(void)fprintf(stderr, "trainlog: unable to create data directory\n");
|
|
return 1;
|
|
}
|
|
|
|
status = trainlog_database_open(database_path, &database);
|
|
if (status != TRAINLOG_STATUS_OK) {
|
|
(void)fprintf(
|
|
stderr,
|
|
"trainlog: unable to open database (%d)\n",
|
|
(int)status
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
result = trainlog_tui_run(database);
|
|
trainlog_database_close(database);
|
|
return result;
|
|
}
|