ssb: Put the database in (ie, ~/.local/share/tildefriends/db.sqlite) by default. Unless it already exists in the working directory, so that nobody worries they've lost it. #91
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 17m48s

This commit is contained in:
Cory McWilliams 2024-12-23 16:32:30 -05:00
parent dca56af5b9
commit 547d38d1ef

View File

@ -25,6 +25,7 @@
#if defined(__linux__)
#include <sys/prctl.h>
#include <sys/stat.h>
#endif
#if defined(__APPLE__)
@ -41,7 +42,102 @@
struct backtrace_state* g_backtrace_state;
const char* k_db_path_default = "db.sqlite";
#if !defined(TARGET_OS_IPHONE)
static const char* _get_db_path()
{
const char* k_db_path_default = "db.sqlite";
#if defined(__linux__)
if (stat(k_db_path_default, &(struct stat) { 0 }) == 0)
{
return tf_strdup(k_db_path_default);
}
else
{
char buffer[32];
char* data_home = NULL;
size_t size = sizeof(buffer);
int r = uv_os_getenv("XDG_DATA_HOME", buffer, &size);
if (r == 0 || r == UV_ENOBUFS)
{
size++;
data_home = alloca(size);
if (uv_os_getenv("XDG_DATA_HOME", data_home, &size) != 0)
{
data_home = NULL;
}
}
if (!data_home)
{
size = sizeof(buffer);
r = uv_os_getenv("HOME", buffer, &size);
if (r == 0 || r == UV_ENOBUFS)
{
size++;
char* home = alloca(size);
r = uv_os_getenv("HOME", home, &size);
if (r == 0)
{
size = snprintf(NULL, 0, "%s/.local/share", home) + 1;
data_home = alloca(size);
snprintf(data_home, size, "%s/.local/share", home);
}
}
}
if (data_home)
{
size = snprintf(NULL, 0, "%s/tildefriends/db.sqlite", data_home) + 1;
char* path = alloca(size);
snprintf(path, size, "%s/tildefriends/db.sqlite", data_home);
return tf_strdup(path);
}
}
#endif
return tf_strdup(k_db_path_default);
}
static void _create_directories_for_file(const char* path, int mode)
{
if (stat(path, &(struct stat) { 0 }) == 0)
{
/* It already exists. OK. */
return;
}
size_t length = strlen(path) + 1;
char* copy = alloca(length);
memcpy(copy, path, length);
#if defined(_WIN32)
for (char* c = copy; *c; c++)
{
if (*c == '\\')
{
*c = '/';
}
}
#endif
char* slash = copy;
while (slash)
{
slash = strchr(slash + 1, '/');
if (slash)
{
*slash = '\0';
#if defined(_WIN32)
if (mkdir(copy) == 0)
#else
if (mkdir(copy, mode) == 0)
#endif
{
tf_printf("Created directory %s.\n", copy);
}
*slash = '/';
}
}
}
#endif
#if !TARGET_OS_IPHONE && !defined(__ANDROID__)
static int _tf_command_export(const char* file, int argc, char* argv[]);
@ -131,7 +227,8 @@ static int _tf_command_test(const char* file, int argc, char* argv[])
static int _tf_command_import(const char* file, int argc, char* argv[])
{
const char* user = "import";
const char* db_path = k_db_path_default;
const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
bool show_usage = false;
while (!show_usage)
@ -169,11 +266,13 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
tf_printf("\n%s import [options] [paths...]\n\n", file);
tf_printf("options:\n");
tf_printf(" -u, --user user User into whose account apps will be imported (default: \"import\").\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
_create_directories_for_file(db_path, 0700);
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
if (optind < argc)
{
@ -189,13 +288,15 @@ static int _tf_command_import(const char* file, int argc, char* argv[])
tf_ssb_import(ssb, user, "apps");
}
tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return EXIT_SUCCESS;
}
static int _tf_command_export(const char* file, int argc, char* argv[])
{
const char* user = "core";
const char* db_path = k_db_path_default;
const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
bool show_usage = false;
while (!show_usage)
@ -233,10 +334,11 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
tf_printf("\n%s export [options] [paths...]\n\n", file);
tf_printf("options:\n");
tf_printf(" -u, --user user User from whose account apps will be exported (default: \"core\").\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -h, --help Show this usage information.\n");
tf_printf("\n");
tf_printf("paths Paths of apps to export (example: /~core/ssb /~user/app).\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
@ -271,6 +373,7 @@ static int _tf_command_export(const char* file, int argc, char* argv[])
}
}
tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return EXIT_SUCCESS;
}
@ -298,7 +401,8 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
{
const char* user = NULL;
const char* identity = NULL;
const char* db_path = k_db_path_default;
const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
const char* content = NULL;
bool show_usage = false;
@ -346,14 +450,16 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
tf_printf("options:\n");
tf_printf(" -u, --user user User owning identity with which to publish.\n");
tf_printf(" -i, --id identity Identity with which to publish message.\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -c, --content json JSON content of message to publish.\n");
tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
int result = EXIT_FAILURE;
tf_printf("Posting %s as account %s belonging to %s...\n", content, identity, user);
_create_directories_for_file(db_path, 0700);
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
uint8_t private_key[512] = { 0 };
if (tf_ssb_db_identity_get_private_key(ssb, user, identity, private_key, sizeof(private_key)))
@ -386,12 +492,14 @@ static int _tf_command_publish(const char* file, int argc, char* argv[])
tf_printf("Did not find private key for identity %s belonging to %s.\n", identity, user);
}
tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return result;
}
static int _tf_command_store_blob(const char* file, int argc, char* argv[])
{
const char* db_path = k_db_path_default;
const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
const char* file_path = NULL;
bool show_usage = false;
@ -429,9 +537,10 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
{
tf_printf("\n%s store_blob [options]\n\n", file);
tf_printf("options:\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -f, --file file_path Path to file to add to the blob store.\n");
tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
@ -441,6 +550,7 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
if (!blob_file)
{
tf_printf("Failed to open %s: %s.\n", file_path, strerror(errno));
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
@ -464,11 +574,13 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
tf_printf("Failed to read %s: %s.\n", file_path, strerror(errno));
fclose(blob_file);
tf_free(data);
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
fclose(blob_file);
char id[256];
_create_directories_for_file(db_path, 0700);
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
if (tf_ssb_db_blob_store(ssb, (const uint8_t*)data, size, id, sizeof(id), NULL))
{
@ -476,13 +588,15 @@ static int _tf_command_store_blob(const char* file, int argc, char* argv[])
}
tf_ssb_destroy(ssb);
tf_free(data);
tf_free((void*)default_db_path);
return EXIT_SUCCESS;
}
static int _tf_command_verify(const char* file, int argc, char* argv[])
{
const char* identity = NULL;
const char* db_path = k_db_path_default;
const char* default_db_path = _get_db_path();
const char* db_path = default_db_path;
bool show_usage = false;
while (!show_usage)
@ -520,8 +634,9 @@ static int _tf_command_verify(const char* file, int argc, char* argv[])
tf_printf("\n%s import [options] [paths...]\n\n", file);
tf_printf("options:\n");
tf_printf(" -i, --identity identity Identity to verify.\n");
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", k_db_path_default);
tf_printf(" -d, --db-path db_path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
@ -529,6 +644,7 @@ static int _tf_command_verify(const char* file, int argc, char* argv[])
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db_path, NULL);
bool verified = tf_ssb_db_verify(ssb, identity);
tf_ssb_destroy(ssb);
tf_free((void*)default_db_path);
return verified ? EXIT_SUCCESS : EXIT_FAILURE;
}
#endif
@ -673,13 +789,14 @@ static void _shed_privileges()
static int _tf_command_run(const char* file, int argc, char* argv[])
{
const char* default_db_path = _get_db_path();
tf_run_args_t args = {
.count = 1,
.script = "core/core.js",
.http_port = 12345,
.https_port = 12346,
.ssb_port = 8008,
.db_path = k_db_path_default,
.db_path = default_db_path,
};
bool show_usage = false;
@ -764,7 +881,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_printf(" -b, --ssb-port port Port on which to run SSB (default: 8008, 0 disables).\n");
tf_printf(" -p, --http-port port Port on which to run Tilde Friends web server (default: 12345).\n");
tf_printf(" -q, --https-port port Port on which to run secure Tilde Friends web server (default: 12346).\n");
tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", k_db_path_default);
tf_printf(" -d, --db-path path SQLite database path (default: %s).\n", default_db_path);
tf_printf(" -k, --ssb-network-key key SSB network key to use.\n");
tf_printf(" -n, --count count Number of instances to run.\n");
tf_printf(" -a, --args args Arguments of the format key=value,foo=bar,verbose=true.\n");
@ -772,6 +889,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_printf(" -z, --zip path Zip archive from which to load files.\n");
tf_printf(" -v, --verbose Log raw messages.\n");
tf_printf(" -h, --help Show this usage information.\n");
tf_free((void*)default_db_path);
return EXIT_FAILURE;
}
@ -780,6 +898,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
setpgid(0, 0);
#endif
_create_directories_for_file(args.db_path, 0700);
if (args.count == 1)
{
result = _tf_run_task(&args, 0);
@ -807,6 +926,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
tf_free(data);
tf_free(threads);
}
tf_free((void*)default_db_path);
return result;
}
@ -1088,7 +1208,7 @@ void tf_run_thread_start(const char* zip_path)
.http_port = 12345,
.https_port = 12346,
.ssb_port = 8008,
.db_path = k_db_path_default,
.db_path = "db.sqlite",
.one_proc = true,
.zip = zip_path,
};