Bump liberty, use newer configuration format
So that we don't need to maintain our own string parser for attribute strings. More or less just plugging in what the old code has evolved into in degesch.
This commit is contained in:
parent
50c8ef12ac
commit
3e2728443b
439
json-rpc-shell.c
439
json-rpc-shell.c
@ -21,18 +21,27 @@
|
|||||||
/// Some arbitrary limit for the history file
|
/// Some arbitrary limit for the history file
|
||||||
#define HISTORY_LIMIT 10000
|
#define HISTORY_LIMIT 10000
|
||||||
|
|
||||||
// String constants for all attributes we use for output
|
// A table of all attributes we use for output
|
||||||
#define ATTR_PROMPT "attr_prompt"
|
#define ATTR_TABLE(XX) \
|
||||||
#define ATTR_RESET "attr_reset"
|
XX( PROMPT, "prompt", "Terminal attrs for the prompt" ) \
|
||||||
#define ATTR_WARNING "attr_warning"
|
XX( RESET, "reset", "String to reset terminal attributes" ) \
|
||||||
#define ATTR_ERROR "attr_error"
|
XX( WARNING, "warning", "Terminal attrs for warnings" ) \
|
||||||
#define ATTR_INCOMING "attr_incoming"
|
XX( ERROR, "error", "Terminal attrs for errors" ) \
|
||||||
#define ATTR_OUTGOING "attr_outgoing"
|
XX( INCOMING, "incoming", "Terminal attrs for incoming traffic" ) \
|
||||||
|
XX( OUTGOING, "outgoing", "Terminal attrs for outgoing traffic" )
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
#define XX(x, y, z) ATTR_ ## x,
|
||||||
|
ATTR_TABLE (XX)
|
||||||
|
#undef XX
|
||||||
|
ATTR_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
// User data for logger functions to enable formatted logging
|
// User data for logger functions to enable formatted logging
|
||||||
#define print_fatal_data ATTR_ERROR
|
#define print_fatal_data ((void *) ATTR_ERROR)
|
||||||
#define print_error_data ATTR_ERROR
|
#define print_error_data ((void *) ATTR_ERROR)
|
||||||
#define print_warning_data ATTR_WARNING
|
#define print_warning_data ((void *) ATTR_WARNING)
|
||||||
|
|
||||||
#define LIBERTY_WANT_SSL
|
#define LIBERTY_WANT_SSL
|
||||||
#define LIBERTY_WANT_PROTO_HTTP
|
#define LIBERTY_WANT_PROTO_HTTP
|
||||||
@ -63,23 +72,6 @@
|
|||||||
return false; \
|
return false; \
|
||||||
BLOCK_END
|
BLOCK_END
|
||||||
|
|
||||||
// --- Configuration (application-specific) ------------------------------------
|
|
||||||
|
|
||||||
static struct simple_config_item g_config_table[] =
|
|
||||||
{
|
|
||||||
{ ATTR_PROMPT, NULL, "Terminal attributes for the prompt" },
|
|
||||||
{ ATTR_RESET, NULL, "String to reset terminal attributes" },
|
|
||||||
{ ATTR_WARNING, NULL, "Terminal attributes for warnings" },
|
|
||||||
{ ATTR_ERROR, NULL, "Terminal attributes for errors" },
|
|
||||||
{ ATTR_INCOMING, NULL, "Terminal attributes for incoming traffic" },
|
|
||||||
{ ATTR_OUTGOING, NULL, "Terminal attributes for outgoing traffic" },
|
|
||||||
|
|
||||||
{ "ca_file", NULL, "OpenSSL trusted CA certificates file" },
|
|
||||||
{ "ca_path", NULL, "OpenSSL trusted CA certificates path" },
|
|
||||||
|
|
||||||
{ NULL, NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Terminal ----------------------------------------------------------------
|
// --- Terminal ----------------------------------------------------------------
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
@ -233,6 +225,8 @@ ws_context_init (struct ws_context *self)
|
|||||||
str_vector_init (&self->extra_headers);
|
str_vector_init (&self->extra_headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
struct curl_context
|
struct curl_context
|
||||||
{
|
{
|
||||||
CURL *curl; ///< cURL handle
|
CURL *curl; ///< cURL handle
|
||||||
@ -262,7 +256,10 @@ static struct app_context
|
|||||||
struct ws_context ws; ///< WebSockets backend data
|
struct ws_context ws; ///< WebSockets backend data
|
||||||
struct curl_context curl; ///< cURL backend data
|
struct curl_context curl; ///< cURL backend data
|
||||||
|
|
||||||
struct str_map config; ///< Program configuration
|
char *attrs_defaults[ATTR_COUNT]; ///< Default terminal attributes
|
||||||
|
char *attrs[ATTR_COUNT]; ///< Terminal attributes
|
||||||
|
|
||||||
|
struct config config; ///< Program configuration
|
||||||
enum color_mode color_mode; ///< Colour output mode
|
enum color_mode color_mode; ///< Colour output mode
|
||||||
bool pretty_print; ///< Whether to pretty print
|
bool pretty_print; ///< Whether to pretty print
|
||||||
bool verbose; ///< Print requests
|
bool verbose; ///< Print requests
|
||||||
@ -279,6 +276,146 @@ static struct app_context
|
|||||||
}
|
}
|
||||||
g_ctx;
|
g_ctx;
|
||||||
|
|
||||||
|
// --- Configuration -----------------------------------------------------------
|
||||||
|
|
||||||
|
static void on_config_attribute_change (struct config_item *item);
|
||||||
|
|
||||||
|
static struct config_schema g_config_connection[] =
|
||||||
|
{
|
||||||
|
{ .name = "tls_ca_file",
|
||||||
|
.comment = "OpenSSL CA bundle file",
|
||||||
|
.type = CONFIG_ITEM_STRING },
|
||||||
|
{ .name = "tls_ca_path",
|
||||||
|
.comment = "OpenSSL CA bundle path",
|
||||||
|
.type = CONFIG_ITEM_STRING },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct config_schema g_config_attributes[] =
|
||||||
|
{
|
||||||
|
#define XX(x, y, z) { .name = y, .comment = z, .type = CONFIG_ITEM_STRING, \
|
||||||
|
.on_change = on_config_attribute_change },
|
||||||
|
ATTR_TABLE (XX)
|
||||||
|
#undef XX
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_config_connection (struct config_item *subtree, void *user_data)
|
||||||
|
{
|
||||||
|
config_schema_apply_to_object (g_config_connection, subtree, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_config_attributes (struct config_item *subtree, void *user_data)
|
||||||
|
{
|
||||||
|
config_schema_apply_to_object (g_config_attributes, subtree, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
register_config_modules (struct app_context *ctx)
|
||||||
|
{
|
||||||
|
struct config *config = &ctx->config;
|
||||||
|
config_register_module (config, "connection", load_config_connection, ctx);
|
||||||
|
config_register_module (config, "attributes", load_config_attributes, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_config_string (struct config_item *root, const char *key)
|
||||||
|
{
|
||||||
|
struct config_item *item = config_item_get (root, key, NULL);
|
||||||
|
hard_assert (item);
|
||||||
|
if (item->type == CONFIG_ITEM_NULL)
|
||||||
|
return NULL;
|
||||||
|
hard_assert (config_item_type_is_string (item->type));
|
||||||
|
return item->value.string.str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_configuration (struct config_item *root, const char *path_hint)
|
||||||
|
{
|
||||||
|
struct str data;
|
||||||
|
str_init (&data);
|
||||||
|
|
||||||
|
str_append (&data,
|
||||||
|
"# " PROGRAM_NAME " " PROGRAM_VERSION " configuration file\n"
|
||||||
|
"#\n"
|
||||||
|
"# Relative paths are searched for in ${XDG_CONFIG_HOME:-~/.config}\n"
|
||||||
|
"# /" PROGRAM_NAME " as well as in $XDG_CONFIG_DIRS/" PROGRAM_NAME "\n"
|
||||||
|
"#\n"
|
||||||
|
"# All text must be in UTF-8.\n"
|
||||||
|
"\n");
|
||||||
|
config_item_write (root, true, &data);
|
||||||
|
|
||||||
|
struct error *e = NULL;
|
||||||
|
char *filename = write_configuration_file (path_hint, &data, &e);
|
||||||
|
str_free (&data);
|
||||||
|
|
||||||
|
if (!filename)
|
||||||
|
{
|
||||||
|
print_error ("%s: %s", "saving configuration failed", e->message);
|
||||||
|
error_free (e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print_status ("configuration written to `%s'", filename);
|
||||||
|
free (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
// TODO: consider moving to liberty, degesch has exactly the same function
|
||||||
|
static struct config_item *
|
||||||
|
load_configuration_file (const char *filename, struct error **e)
|
||||||
|
{
|
||||||
|
struct config_item *root = NULL;
|
||||||
|
|
||||||
|
struct str data;
|
||||||
|
str_init (&data);
|
||||||
|
if (!read_file (filename, &data, e))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
struct error *error = NULL;
|
||||||
|
if (!(root = config_item_parse (data.str, data.len, false, &error)))
|
||||||
|
{
|
||||||
|
error_set (e, "parse error: %s", error->message);
|
||||||
|
error_free (error);
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
str_free (&data);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_configuration (struct app_context *ctx)
|
||||||
|
{
|
||||||
|
char *filename = resolve_filename
|
||||||
|
(PROGRAM_NAME ".conf", resolve_relative_config_filename);
|
||||||
|
if (!filename)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct error *e = NULL;
|
||||||
|
struct config_item *root = load_configuration_file (filename, &e);
|
||||||
|
free (filename);
|
||||||
|
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
print_error ("error loading configuration: %s", e->message);
|
||||||
|
error_free (e);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
config_load (&ctx->config, root);
|
||||||
|
config_schema_call_changed (ctx->config.root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Attributed output -------------------------------------------------------
|
// --- Attributed output -------------------------------------------------------
|
||||||
|
|
||||||
typedef int (*terminal_printer_fn) (int);
|
typedef int (*terminal_printer_fn) (int);
|
||||||
@ -301,30 +438,24 @@ get_attribute_printer (FILE *stream)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
vprint_attributed (struct app_context *ctx,
|
vprint_attributed (struct app_context *ctx,
|
||||||
FILE *stream, const char *attribute, const char *fmt, va_list ap)
|
FILE *stream, intptr_t attribute, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
terminal_printer_fn printer = get_attribute_printer (stream);
|
terminal_printer_fn printer = get_attribute_printer (stream);
|
||||||
if (!attribute)
|
if (!attribute)
|
||||||
printer = NULL;
|
printer = NULL;
|
||||||
|
|
||||||
if (printer)
|
if (printer)
|
||||||
{
|
tputs (ctx->attrs[attribute], 1, printer);
|
||||||
const char *value = str_map_find (&ctx->config, attribute);
|
|
||||||
tputs (value, 1, printer);
|
|
||||||
}
|
|
||||||
|
|
||||||
vfprintf (stream, fmt, ap);
|
vfprintf (stream, fmt, ap);
|
||||||
|
|
||||||
if (printer)
|
if (printer)
|
||||||
{
|
tputs (ctx->attrs[ATTR_RESET], 1, printer);
|
||||||
const char *value = str_map_find (&ctx->config, ATTR_RESET);
|
|
||||||
tputs (value, 1, printer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_attributed (struct app_context *ctx,
|
print_attributed (struct app_context *ctx,
|
||||||
FILE *stream, const char *attribute, const char *fmt, ...)
|
FILE *stream, intptr_t attribute, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, fmt);
|
va_start (ap, fmt);
|
||||||
@ -353,8 +484,8 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt,
|
|||||||
rl_redisplay ();
|
rl_redisplay ();
|
||||||
}
|
}
|
||||||
|
|
||||||
print_attributed (&g_ctx, stream, user_data, "%s", quote);
|
print_attributed (&g_ctx, stream, (intptr_t) user_data, "%s", quote);
|
||||||
vprint_attributed (&g_ctx, stream, user_data, fmt, ap);
|
vprint_attributed (&g_ctx, stream, (intptr_t) user_data, fmt, ap);
|
||||||
fputs ("\n", stream);
|
fputs ("\n", stream);
|
||||||
|
|
||||||
if (g_ctx.readline_prompt_shown)
|
if (g_ctx.readline_prompt_shown)
|
||||||
@ -370,36 +501,31 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt,
|
|||||||
static void
|
static void
|
||||||
init_colors (struct app_context *ctx)
|
init_colors (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
|
char **defaults = ctx->attrs_defaults;
|
||||||
|
#define INIT_ATTR(id, ti) defaults[ATTR_ ## id] = xstrdup ((ti))
|
||||||
|
|
||||||
// Use escape sequences from terminfo if possible, and SGR as a fallback
|
// Use escape sequences from terminfo if possible, and SGR as a fallback
|
||||||
if (init_terminal ())
|
if (init_terminal ())
|
||||||
{
|
{
|
||||||
const char *attrs[][2] =
|
INIT_ATTR (PROMPT, enter_bold_mode);
|
||||||
{
|
INIT_ATTR (RESET, exit_attribute_mode);
|
||||||
{ ATTR_PROMPT, enter_bold_mode },
|
INIT_ATTR (WARNING, g_terminal.color_set[COLOR_YELLOW]);
|
||||||
{ ATTR_RESET, exit_attribute_mode },
|
INIT_ATTR (ERROR, g_terminal.color_set[COLOR_RED]);
|
||||||
{ ATTR_WARNING, g_terminal.color_set[3] },
|
INIT_ATTR (INCOMING, "");
|
||||||
{ ATTR_ERROR, g_terminal.color_set[1] },
|
INIT_ATTR (OUTGOING, "");
|
||||||
{ ATTR_INCOMING, "" },
|
|
||||||
{ ATTR_OUTGOING, "" },
|
|
||||||
};
|
|
||||||
for (size_t i = 0; i < N_ELEMENTS (attrs); i++)
|
|
||||||
str_map_set (&ctx->config, attrs[i][0], xstrdup (attrs[i][1]));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *attrs[][2] =
|
INIT_ATTR (PROMPT, "\x1b[1m");
|
||||||
{
|
INIT_ATTR (RESET, "\x1b[0m");
|
||||||
{ ATTR_PROMPT, "\x1b[1m" },
|
INIT_ATTR (WARNING, "\x1b[33m");
|
||||||
{ ATTR_RESET, "\x1b[0m" },
|
INIT_ATTR (ERROR, "\x1b[31m");
|
||||||
{ ATTR_WARNING, "\x1b[33m" },
|
INIT_ATTR (INCOMING, "");
|
||||||
{ ATTR_ERROR, "\x1b[31m" },
|
INIT_ATTR (OUTGOING, "");
|
||||||
{ ATTR_INCOMING, "" },
|
|
||||||
{ ATTR_OUTGOING, "" },
|
|
||||||
};
|
|
||||||
for (size_t i = 0; i < N_ELEMENTS (attrs); i++)
|
|
||||||
str_map_set (&ctx->config, attrs[i][0], xstrdup (attrs[i][1]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef INIT_ATTR
|
||||||
|
|
||||||
switch (ctx->color_mode)
|
switch (ctx->color_mode)
|
||||||
{
|
{
|
||||||
case COLOR_ALWAYS:
|
case COLOR_ALWAYS:
|
||||||
@ -416,150 +542,42 @@ init_colors (struct app_context *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_log_message_real = log_message_attributed;
|
g_log_message_real = log_message_attributed;
|
||||||
|
|
||||||
|
// Apply the default values so that we start with any formatting at all
|
||||||
|
config_schema_call_changed
|
||||||
|
(config_item_get (ctx->config.root, "attributes", NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Configuration loading ---------------------------------------------------
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
static bool
|
static ssize_t
|
||||||
read_hexa_escape (const char **cursor, struct str *output)
|
attr_by_name (const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
static const char *table[ATTR_COUNT] =
|
||||||
char c, code = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
{
|
{
|
||||||
c = tolower (*(*cursor));
|
#define XX(x, y, z) [ATTR_ ## x] = y,
|
||||||
if (c >= '0' && c <= '9')
|
ATTR_TABLE (XX)
|
||||||
code = (code << 4) | (c - '0');
|
#undef XX
|
||||||
else if (c >= 'a' && c <= 'f')
|
};
|
||||||
code = (code << 4) | (c - 'a' + 10);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
(*cursor)++;
|
for (size_t i = 0; i < N_ELEMENTS (table); i++)
|
||||||
}
|
if (!strcmp (name, table[i]))
|
||||||
|
return i;
|
||||||
if (!i)
|
return -1;
|
||||||
return false;
|
|
||||||
|
|
||||||
str_append_c (output, code);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
read_octal_escape (const char **cursor, struct str *output)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char c, code = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
c = *(*cursor);
|
|
||||||
if (c < '0' || c > '7')
|
|
||||||
break;
|
|
||||||
|
|
||||||
code = (code << 3) | (c - '0');
|
|
||||||
(*cursor)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!i)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
str_append_c (output, code);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
read_string_escape_sequence (const char **cursor,
|
|
||||||
struct str *output, struct error **e)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
switch ((c = *(*cursor)++))
|
|
||||||
{
|
|
||||||
case '?': str_append_c (output, '?'); break;
|
|
||||||
case '"': str_append_c (output, '"'); break;
|
|
||||||
case '\\': str_append_c (output, '\\'); break;
|
|
||||||
case 'a': str_append_c (output, '\a'); break;
|
|
||||||
case 'b': str_append_c (output, '\b'); break;
|
|
||||||
case 'f': str_append_c (output, '\f'); break;
|
|
||||||
case 'n': str_append_c (output, '\n'); break;
|
|
||||||
case 'r': str_append_c (output, '\r'); break;
|
|
||||||
case 't': str_append_c (output, '\t'); break;
|
|
||||||
case 'v': str_append_c (output, '\v'); break;
|
|
||||||
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
str_append_c (output, '\x1b');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
if (!read_hexa_escape (cursor, output))
|
|
||||||
FAIL ("invalid hexadecimal escape");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\0':
|
|
||||||
FAIL ("premature end of escape sequence");
|
|
||||||
|
|
||||||
default:
|
|
||||||
(*cursor)--;
|
|
||||||
if (!read_octal_escape (cursor, output))
|
|
||||||
FAIL ("unknown escape sequence");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
unescape_string (const char *s, struct str *output, struct error **e)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
while ((c = *s++))
|
|
||||||
{
|
|
||||||
if (c != '\\')
|
|
||||||
str_append_c (output, c);
|
|
||||||
else if (!read_string_escape_sequence (&s, output, e))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_config (struct app_context *ctx)
|
on_config_attribute_change (struct config_item *item)
|
||||||
{
|
{
|
||||||
// TODO: employ a better configuration file format, so that we don't have
|
struct app_context *ctx = item->user_data;
|
||||||
// to do this convoluted post-processing anymore.
|
ssize_t id = attr_by_name (item->schema->name);
|
||||||
|
if (id != -1)
|
||||||
struct str_map map;
|
|
||||||
str_map_init (&map);
|
|
||||||
map.free = free;
|
|
||||||
|
|
||||||
struct error *e = NULL;
|
|
||||||
if (!simple_config_update_from_file (&map, &e))
|
|
||||||
{
|
{
|
||||||
print_error ("error loading configuration: %s", e->message);
|
free (ctx->attrs[id]);
|
||||||
error_free (e);
|
ctx->attrs[id] = xstrdup (item->type == CONFIG_ITEM_NULL
|
||||||
exit (EXIT_FAILURE);
|
? ctx->attrs_defaults[id]
|
||||||
|
: item->value.string.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct str_map_iter iter;
|
|
||||||
str_map_iter_init (&iter, &map);
|
|
||||||
while (str_map_iter_next (&iter))
|
|
||||||
{
|
|
||||||
struct error *e = NULL;
|
|
||||||
struct str value;
|
|
||||||
str_init (&value);
|
|
||||||
if (!unescape_string (iter.link->data, &value, &e))
|
|
||||||
{
|
|
||||||
print_error ("error reading configuration: %s: %s",
|
|
||||||
iter.link->key, e->message);
|
|
||||||
error_free (e);
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
str_map_set (&ctx->config, iter.link->key, str_steal (&value));
|
|
||||||
}
|
|
||||||
|
|
||||||
str_map_free (&map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- WebSockets backend ------------------------------------------------------
|
// --- WebSockets backend ------------------------------------------------------
|
||||||
@ -995,8 +1013,11 @@ backend_ws_set_up_ssl_ctx (struct app_context *ctx)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ca_file = str_map_find (&ctx->config, "ca_file");
|
// TODO: try to resolve filenames relative to configuration directories
|
||||||
const char *ca_path = str_map_find (&ctx->config, "ca_path");
|
const char *ca_file = get_config_string
|
||||||
|
(ctx->config.root, "connection.tls_ca_file");
|
||||||
|
const char *ca_path = get_config_string
|
||||||
|
(ctx->config.root, "connection.tls_ca_path");
|
||||||
if (ca_file || ca_path)
|
if (ca_file || ca_path)
|
||||||
{
|
{
|
||||||
if (SSL_CTX_load_verify_locations (self->ssl_ctx, ca_file, ca_path))
|
if (SSL_CTX_load_verify_locations (self->ssl_ctx, ca_file, ca_path))
|
||||||
@ -1567,8 +1588,11 @@ backend_curl_init (struct app_context *ctx,
|
|||||||
|
|
||||||
if (!ctx->trust_all)
|
if (!ctx->trust_all)
|
||||||
{
|
{
|
||||||
const char *ca_file = str_map_find (&ctx->config, "ca_file");
|
// TODO: try to resolve filenames relative to configuration directories
|
||||||
const char *ca_path = str_map_find (&ctx->config, "ca_path");
|
const char *ca_file = get_config_string
|
||||||
|
(ctx->config.root, "connection.tls_ca_file");
|
||||||
|
const char *ca_path = get_config_string
|
||||||
|
(ctx->config.root, "connection.tls_ca_path");
|
||||||
if ((ca_file && curl_easy_setopt (curl, CURLOPT_CAINFO, ca_file))
|
if ((ca_file && curl_easy_setopt (curl, CURLOPT_CAINFO, ca_file))
|
||||||
|| (ca_path && curl_easy_setopt (curl, CURLOPT_CAPATH, ca_path)))
|
|| (ca_path && curl_easy_setopt (curl, CURLOPT_CAPATH, ca_path)))
|
||||||
exit_fatal ("cURL setup failed");
|
exit_fatal ("cURL setup failed");
|
||||||
@ -2040,7 +2064,7 @@ parse_program_arguments (struct app_context *ctx, int argc, char **argv,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
call_simple_config_write_default (optarg, g_config_table);
|
save_configuration (ctx->config.root, optarg);
|
||||||
exit (EXIT_SUCCESS);
|
exit (EXIT_SUCCESS);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2065,15 +2089,16 @@ parse_program_arguments (struct app_context *ctx, int argc, char **argv,
|
|||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
str_map_init (&g_ctx.config);
|
config_init (&g_ctx.config);
|
||||||
g_ctx.config.free = free;
|
register_config_modules (&g_ctx);
|
||||||
|
config_load (&g_ctx.config, config_item_object ());
|
||||||
|
|
||||||
char *origin = NULL;
|
char *origin = NULL;
|
||||||
char *endpoint = NULL;
|
char *endpoint = NULL;
|
||||||
parse_program_arguments (&g_ctx, argc, argv, &origin, &endpoint);
|
parse_program_arguments (&g_ctx, argc, argv, &origin, &endpoint);
|
||||||
|
|
||||||
init_colors (&g_ctx);
|
init_colors (&g_ctx);
|
||||||
load_config (&g_ctx);
|
load_configuration (&g_ctx);
|
||||||
|
|
||||||
struct http_parser_url url;
|
struct http_parser_url url;
|
||||||
if (http_parser_parse_url (endpoint, strlen (endpoint), false, &url))
|
if (http_parser_parse_url (endpoint, strlen (endpoint), false, &url))
|
||||||
@ -2145,11 +2170,11 @@ main (int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// XXX: to be completely correct, we should use tputs, but we cannot
|
// XXX: to be completely correct, we should use tputs, but we cannot
|
||||||
const char *prompt_attrs = str_map_find (&g_ctx.config, ATTR_PROMPT);
|
|
||||||
const char *reset_attrs = str_map_find (&g_ctx.config, ATTR_RESET);
|
|
||||||
g_ctx.readline_prompt = xstrdup_printf ("%c%s%cjson-rpc> %c%s%c",
|
g_ctx.readline_prompt = xstrdup_printf ("%c%s%cjson-rpc> %c%s%c",
|
||||||
RL_PROMPT_START_IGNORE, prompt_attrs, RL_PROMPT_END_IGNORE,
|
RL_PROMPT_START_IGNORE, g_ctx.attrs[ATTR_PROMPT],
|
||||||
RL_PROMPT_START_IGNORE, reset_attrs, RL_PROMPT_END_IGNORE);
|
RL_PROMPT_END_IGNORE,
|
||||||
|
RL_PROMPT_START_IGNORE, g_ctx.attrs[ATTR_RESET],
|
||||||
|
RL_PROMPT_END_IGNORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// So that if the remote end closes the connection, attempts to write to
|
// So that if the remote end closes the connection, attempts to write to
|
||||||
@ -2204,7 +2229,7 @@ main (int argc, char *argv[])
|
|||||||
g_ctx.backend->destroy (&g_ctx);
|
g_ctx.backend->destroy (&g_ctx);
|
||||||
free (origin);
|
free (origin);
|
||||||
free (g_ctx.readline_prompt);
|
free (g_ctx.readline_prompt);
|
||||||
str_map_free (&g_ctx.config);
|
config_free (&g_ctx.config);
|
||||||
free_terminal ();
|
free_terminal ();
|
||||||
ev_loop_destroy (loop);
|
ev_loop_destroy (loop);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
2
liberty
2
liberty
@ -1 +1 @@
|
|||||||
Subproject commit 91fca5cb054fc95fe2e7ac090cac2c3a302565ca
|
Subproject commit 8b2e41ed8ffac0494763495896c6a80a9e9db543
|
Loading…
Reference in New Issue
Block a user