2021-01-02 13:10:00 -05:00
|
|
|
#include "ssb.h"
|
2021-08-22 15:34:28 -04:00
|
|
|
#include "ssb.import.h"
|
|
|
|
#include "ssb.export.h"
|
2021-01-02 13:10:00 -05:00
|
|
|
#include "task.h"
|
|
|
|
#include "taskstub.h"
|
2021-08-19 15:29:37 -04:00
|
|
|
#include "tests.h"
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
#include <quickjs-libc.h>
|
|
|
|
#include <quickjs.h>
|
|
|
|
#include <sqlite3.h>
|
|
|
|
#include <xopt.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#if !defined (_WIN32) && !defined (__MACH__)
|
|
|
|
#include <signal.h>
|
|
|
|
#include <sys/prctl.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !defined(_countof)
|
|
|
|
#define _countof(a) ((int)(sizeof((a)) / sizeof(*(a))))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define XOPT_PARSE(name, flags, options, config_ptr, argc, argv, extrac_ptr, extrav_ptr, err_ptr, autohelp_file, autohelp_usage, autohelp_prefix, autohelp_suffix, autohelp_spacer) do { \
|
|
|
|
xoptContext *_xopt_ctx; \
|
|
|
|
*(err_ptr) = NULL; \
|
|
|
|
_xopt_ctx = xopt_context((name), (options), ((flags) ^ XOPT_CTX_POSIXMEHARDER), (err_ptr)); \
|
|
|
|
if (*(err_ptr)) break; \
|
|
|
|
*extrac_ptr = xopt_parse(_xopt_ctx, (argc), (argv), (config_ptr), (extrav_ptr), (err_ptr)); \
|
2021-10-10 17:51:38 -04:00
|
|
|
if ((config_ptr)->help) \
|
|
|
|
{ \
|
2021-01-02 13:10:00 -05:00
|
|
|
xoptAutohelpOptions __xopt_autohelp_opts; \
|
|
|
|
__xopt_autohelp_opts.usage = (autohelp_usage); \
|
|
|
|
__xopt_autohelp_opts.prefix = (autohelp_prefix); \
|
|
|
|
__xopt_autohelp_opts.suffix = (autohelp_suffix); \
|
|
|
|
__xopt_autohelp_opts.spacer = (autohelp_spacer); \
|
|
|
|
xopt_autohelp(_xopt_ctx, (autohelp_file), &__xopt_autohelp_opts, (err_ptr)); \
|
|
|
|
if (*(err_ptr)) goto __xopt_end_free_extrav; \
|
|
|
|
free(_xopt_ctx); \
|
|
|
|
goto xopt_help; \
|
|
|
|
} \
|
|
|
|
if (*(err_ptr)) goto __xopt_end_free_ctx; \
|
|
|
|
__xopt_end_free_ctx: \
|
|
|
|
free(_xopt_ctx); \
|
|
|
|
break; \
|
|
|
|
__xopt_end_free_extrav: \
|
|
|
|
free(*(extrav_ptr)); \
|
|
|
|
free(_xopt_ctx); \
|
|
|
|
break; \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
static int _tf_command_test(const char* file, int argc, char* argv[]);
|
|
|
|
static int _tf_command_import(const char* file, int argc, char* argv[]);
|
|
|
|
static int _tf_command_export(const char* file, int argc, char* argv[]);
|
|
|
|
static int _tf_command_run(const char* file, int argc, char* argv[]);
|
|
|
|
static int _tf_command_sandbox(const char* file, int argc, char* argv[]);
|
|
|
|
static int _tf_command_post(const char* file, int argc, char* argv[]);
|
|
|
|
static int _tf_command_usage(const char* file, int argc, char* argv[]);
|
|
|
|
|
|
|
|
typedef struct _command_t {
|
|
|
|
const char* name;
|
|
|
|
int (*callback)(const char* file, int argc, char* argv[]);
|
|
|
|
const char* description;
|
|
|
|
} command_t;
|
|
|
|
|
|
|
|
const command_t k_commands[] = {
|
|
|
|
{ "run", _tf_command_run, "Run tildefriends (default)." },
|
|
|
|
{ "sandbox", _tf_command_sandbox, "Run a sandboxed tildefriends sandbox process (used internally)." },
|
|
|
|
{ "post", _tf_command_post, "Create an SSB post." },
|
|
|
|
{ "import", _tf_command_import, "Import apps to SSB." },
|
|
|
|
{ "export", _tf_command_export, "Export apps from SSB." },
|
|
|
|
{ "test", _tf_command_test, "Test SSB." },
|
|
|
|
};
|
|
|
|
|
|
|
|
void shedPrivileges()
|
|
|
|
{
|
|
|
|
#if !defined (_WIN32)
|
|
|
|
struct rlimit zeroLimit;
|
|
|
|
zeroLimit.rlim_cur = 0;
|
|
|
|
zeroLimit.rlim_max = 0;
|
|
|
|
|
|
|
|
// RLIMIT_AS
|
|
|
|
// RLIMIT_CORE
|
|
|
|
// RLIMIT_CPU
|
|
|
|
// RLIMIT_DATA
|
|
|
|
// RLIMIT_FSIZE
|
|
|
|
// RLIMIT_RSS
|
|
|
|
// RLIMIT_RTPRIO
|
|
|
|
// RLIMIT_RTTIME
|
|
|
|
// RLIMIT_SIGPENDING
|
|
|
|
// RLIMIT_STACK
|
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (setrlimit(RLIMIT_FSIZE, &zeroLimit) != 0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
perror("setrlimit(RLIMIT_FSIZE, {0, 0})");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
perror("setrlimit(RLIMIT_NOFILE, {0, 0})");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
perror("setrlimit(RLIMIT_NPROC, {0, 0})");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
#if !defined (__MACH__)
|
2021-10-10 17:51:38 -04:00
|
|
|
if (setrlimit(RLIMIT_LOCKS, &zeroLimit) != 0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
perror("setrlimit(RLIMIT_LOCKS, {0, 0})");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
perror("setrlimit(RLIMIT_MSGQUEUE, {0, 0})");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_test(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
typedef struct args_t {
|
2021-09-06 14:23:22 -04:00
|
|
|
const char* tests;
|
2021-01-02 13:10:00 -05:00
|
|
|
bool help;
|
|
|
|
} args_t;
|
|
|
|
|
|
|
|
xoptOption options[] = {
|
2021-09-06 14:23:22 -04:00
|
|
|
{ "tests", 't', offsetof(args_t, tests), NULL, XOPT_TYPE_STRING, NULL, "Comma-separated list of test names to run." },
|
2021-01-02 13:10:00 -05:00
|
|
|
{ "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
|
|
|
XOPT_NULLOPTION,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_t args = { 0 };
|
|
|
|
const char** extras = NULL;
|
|
|
|
int extra_count = 0;
|
|
|
|
const char *err = NULL;
|
2021-10-15 15:44:10 -04:00
|
|
|
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "test [options]", "options:", NULL, 15);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (err)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
fprintf(stderr, "Error: %s\n", err);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2021-09-06 14:23:22 -04:00
|
|
|
tf_test_options_t test_options =
|
|
|
|
{
|
|
|
|
.exe_path = file,
|
|
|
|
.tests = args.tests,
|
|
|
|
};
|
|
|
|
tf_tests(&test_options);
|
2021-01-02 13:10:00 -05:00
|
|
|
return 0;
|
|
|
|
xopt_help:
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_import(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
typedef struct args_t {
|
|
|
|
const char* user;
|
|
|
|
const char* db_path;
|
|
|
|
bool help;
|
|
|
|
} args_t;
|
|
|
|
|
|
|
|
xoptOption options[] = {
|
|
|
|
{ "user", 'u', offsetof(args_t, user), NULL, XOPT_TYPE_STRING, NULL, "User into whose account apps will be imported (default: \"import\")." },
|
|
|
|
{ "db-path", 'd', offsetof(args_t, db_path), NULL, XOPT_TYPE_STRING, NULL, "Sqlite database path (default: db.sqlite)." },
|
|
|
|
{ "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
|
|
|
XOPT_NULLOPTION,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_t args = { .user = "import" };
|
|
|
|
const char** extras = NULL;
|
|
|
|
int extra_count = 0;
|
|
|
|
const char *err = NULL;
|
2021-10-15 15:44:10 -04:00
|
|
|
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "import [options] [paths] ...", "options:", NULL, 15);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (err)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
fprintf(stderr, "Error: %s\n", err);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlite3* db = NULL;
|
2021-10-10 17:51:38 -04:00
|
|
|
if (args.db_path)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
sqlite3_open(args.db_path, &db);
|
|
|
|
}
|
|
|
|
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, db, NULL);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extra_count)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < extra_count; i++)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("Importing %s...\n", extras[i]);
|
|
|
|
tf_ssb_import(ssb, args.user, extras[i]);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("Importing %s...\n", "apps");
|
|
|
|
tf_ssb_import(ssb, args.user, "apps");
|
|
|
|
}
|
|
|
|
tf_ssb_destroy(ssb);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (db)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
sqlite3_close(db);
|
|
|
|
}
|
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
xopt_help:
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_export(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
typedef struct args_t {
|
|
|
|
bool help;
|
|
|
|
} args_t;
|
|
|
|
|
|
|
|
xoptOption options[] = {
|
|
|
|
{ "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
|
|
|
XOPT_NULLOPTION,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_t args = { 0 };
|
|
|
|
const char** extras = NULL;
|
|
|
|
int extra_count = 0;
|
|
|
|
const char *err = NULL;
|
2021-10-15 15:44:10 -04:00
|
|
|
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "export [options] [paths] ...", "options:", NULL, 15);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (err)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
fprintf(stderr, "Error: %s\n", err);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, NULL, NULL);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extra_count)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < extra_count; i++)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("Exporting %s...\n", extras[i]);
|
|
|
|
tf_ssb_export(ssb, extras[i]);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
const char* k_export[] = {
|
|
|
|
"/~cory/index",
|
|
|
|
"/~cory/docs",
|
|
|
|
};
|
2021-10-10 17:51:38 -04:00
|
|
|
for (int i = 0; i < _countof(k_export); i++)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf("Exporting %s...\n", k_export[i]);
|
|
|
|
tf_ssb_export(ssb, k_export[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tf_ssb_destroy(ssb);
|
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
xopt_help:
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_run(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
typedef struct args_t {
|
|
|
|
const char* script;
|
|
|
|
int ssb_port;
|
|
|
|
int http_port;
|
|
|
|
int https_port;
|
|
|
|
const char* db_path;
|
|
|
|
const char* secrets_path;
|
|
|
|
bool help;
|
|
|
|
} args_t;
|
|
|
|
|
|
|
|
xoptOption options[] = {
|
|
|
|
{ "script", 's', offsetof(args_t, script), NULL, XOPT_TYPE_STRING, NULL, "Script to run (default: core/core.js)." },
|
|
|
|
{ "ssb-port", 'b', offsetof(args_t, ssb_port), NULL, XOPT_TYPE_INT, NULL, "Port on which to run SSB (default: 8009)." },
|
|
|
|
{ "http-port", 'p', offsetof(args_t, http_port), NULL, XOPT_TYPE_INT, NULL, "Port on which to run Tilde Friends web server (default: 12345)." },
|
|
|
|
{ "https-port", 'q', offsetof(args_t, https_port), NULL, XOPT_TYPE_INT, NULL, "Port on which to run secure Tilde Friends web server (default: 12346)." },
|
|
|
|
{ "db-path", 'd', offsetof(args_t, db_path), NULL, XOPT_TYPE_STRING, NULL, "Sqlite database path (default: db.sqlite)." },
|
|
|
|
{ "secrets-path", 'i', offsetof(args_t, secrets_path), NULL, XOPT_TYPE_STRING, NULL, "Secrets/identity path." },
|
|
|
|
{ "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
|
|
|
XOPT_NULLOPTION,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_t args = {
|
|
|
|
.script = "core/core.js",
|
|
|
|
.http_port = 12345,
|
|
|
|
.ssb_port = 8009,
|
|
|
|
.db_path = "db.sqlite",
|
|
|
|
};
|
|
|
|
const char** extras = NULL;
|
|
|
|
int extra_count = 0;
|
|
|
|
const char *err = NULL;
|
2021-10-15 15:44:10 -04:00
|
|
|
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "run [options] [paths] ...", "options:", NULL, 15);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (err)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
fprintf(stderr, "Error: %s\n", err);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
|
|
|
|
int result = 0;
|
|
|
|
#if !defined (_WIN32) && !defined (__MACH__)
|
|
|
|
setpgid(0, 0);
|
|
|
|
#endif
|
|
|
|
tf_task_t* task = tf_task_create();
|
|
|
|
tf_task_set_trusted(task, true);
|
|
|
|
tf_task_set_ssb_port(task, args.ssb_port);
|
|
|
|
tf_task_set_http_port(task, args.http_port);
|
|
|
|
tf_task_set_https_port(task, args.https_port);
|
|
|
|
tf_task_set_db_path(task, args.db_path);
|
|
|
|
tf_task_set_secrets_path(task, args.secrets_path);
|
|
|
|
tf_task_activate(task);
|
|
|
|
if (!tf_task_execute(task, args.script))
|
|
|
|
{
|
|
|
|
result = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result == 0)
|
|
|
|
{
|
|
|
|
tf_task_run(task);
|
|
|
|
}
|
|
|
|
tf_task_destroy(task);
|
|
|
|
return result;
|
|
|
|
|
|
|
|
xopt_help:
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_sandbox(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
typedef struct args_t {
|
|
|
|
const char* script;
|
|
|
|
bool help;
|
|
|
|
} args_t;
|
|
|
|
|
|
|
|
xoptOption options[] = {
|
|
|
|
{ "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
|
|
|
XOPT_NULLOPTION,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_t args = { 0 };
|
|
|
|
const char** extras = NULL;
|
|
|
|
int extra_count = 0;
|
|
|
|
const char *err = NULL;
|
2021-10-15 15:44:10 -04:00
|
|
|
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_POSIXMEHARDER | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "sandbox [options]", "options:", NULL, 15);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (err)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
fprintf(stderr, "Error: %s\n", err);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(_WIN32) && !defined(__MACH__)
|
|
|
|
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
|
|
|
#endif
|
|
|
|
tf_task_t* task = tf_task_create();
|
|
|
|
tf_task_configure_from_stdin(task);
|
|
|
|
shedPrivileges();
|
|
|
|
tf_task_activate(task);
|
|
|
|
tf_task_run(task);
|
|
|
|
tf_task_destroy(task);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
xopt_help:
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_post(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
typedef struct args_t {
|
|
|
|
char* message;
|
|
|
|
bool help;
|
|
|
|
} args_t;
|
|
|
|
|
|
|
|
xoptOption options[] = {
|
|
|
|
{ "message", 'm', offsetof(args_t, message), NULL, XOPT_REQUIRED | XOPT_TYPE_STRING, "TEXT", "Text to post." },
|
|
|
|
{ "help", 'h', offsetof(args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
|
|
|
XOPT_NULLOPTION,
|
|
|
|
};
|
|
|
|
|
|
|
|
args_t args = { 0 };
|
|
|
|
const char** extras = NULL;
|
|
|
|
int extra_count = 0;
|
|
|
|
const char *err = NULL;
|
2021-10-15 15:44:10 -04:00
|
|
|
XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "post [options]", "options:", NULL, 15);
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
2021-10-10 17:51:38 -04:00
|
|
|
if (err)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
fprintf(stderr, "Error: %s\n", err);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
tf_ssb_t* ssb = tf_ssb_create(NULL, NULL, NULL, NULL);
|
|
|
|
tf_ssb_broadcast_listener_start(ssb, false);
|
|
|
|
tf_ssb_append_post(ssb, args.message);
|
|
|
|
tf_ssb_destroy(ssb);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
xopt_help:
|
2021-10-10 17:51:38 -04:00
|
|
|
if (extras)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
free((void*)extras);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _tf_command_usage(const char* file, int argc, char* argv[])
|
|
|
|
{
|
|
|
|
printf("Usage: %s command [command-options]\n", file);
|
|
|
|
printf("commands:\n");
|
2021-10-10 17:51:38 -04:00
|
|
|
for (int i = 0; i < _countof(k_commands); i++)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
printf(" %s - %s\n", k_commands[i].name, k_commands[i].description);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2021-08-19 15:29:37 -04:00
|
|
|
prctl(PR_SET_PDEATHSIG, SIGKILL);
|
2021-01-02 13:10:00 -05:00
|
|
|
uv_setup_args(argc, argv);
|
|
|
|
tf_taskstub_startup();
|
|
|
|
|
|
|
|
#if !defined (_WIN32)
|
2021-10-10 17:51:38 -04:00
|
|
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
perror("signal");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-10-10 17:51:38 -04:00
|
|
|
if (argc >= 2)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < _countof(k_commands); i++)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
const command_t* command = &k_commands[i];
|
2021-10-10 17:51:38 -04:00
|
|
|
if (strcmp(argv[1], command->name) == 0)
|
|
|
|
{
|
2021-01-02 13:10:00 -05:00
|
|
|
return command->callback(argv[0], argc - 2, argv + 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return _tf_command_usage(argv[0], argc, argv);
|
|
|
|
}
|
|
|
|
|
|
|
|
return _tf_command_run(argv[0], argc - 1, argv + 1);
|
|
|
|
}
|