degesch: create servers from configuration
This means that as of now, the only way of creating a server is to edit the configuration file by hand and add (at least) an empty object under the server's name.
This commit is contained in:
parent
0ecd297c6f
commit
9b41256ebf
2
common.c
2
common.c
|
@ -1131,7 +1131,6 @@ config_schema_accepts_type
|
||||||
&& config_item_type_is_string (type))
|
&& config_item_type_is_string (type))
|
||||||
return true;
|
return true;
|
||||||
return !self->default_ && type == CONFIG_ITEM_NULL;
|
return !self->default_ && type == CONFIG_ITEM_NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -2008,6 +2007,7 @@ config_load (struct config *self, struct config_item_ *root)
|
||||||
subtree = config_item_object ();
|
subtree = config_item_object ();
|
||||||
str_map_set (&root->value.object, module->name, subtree);
|
str_map_set (&root->value.object, module->name, subtree);
|
||||||
}
|
}
|
||||||
|
if (module->loader)
|
||||||
module->loader (subtree, module->user_data);
|
module->loader (subtree, module->user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
132
degesch.c
132
degesch.c
|
@ -1573,18 +1573,11 @@ static struct config_schema g_config_attributes[] =
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
static void
|
|
||||||
load_config_server (struct config_item_ *subtree, void *user_data)
|
|
||||||
{
|
|
||||||
(void) user_data;
|
|
||||||
// This will eventually iterate over the object and create servers
|
|
||||||
config_schema_apply_to_object (g_config_server, subtree);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_config_behaviour (struct config_item_ *subtree, void *user_data)
|
load_config_behaviour (struct config_item_ *subtree, void *user_data)
|
||||||
{
|
{
|
||||||
(void) user_data;
|
(void) user_data;
|
||||||
|
// TODO: assign user_data to all the subitems
|
||||||
config_schema_apply_to_object (g_config_behaviour, subtree);
|
config_schema_apply_to_object (g_config_behaviour, subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1592,6 +1585,7 @@ static void
|
||||||
load_config_attributes (struct config_item_ *subtree, void *user_data)
|
load_config_attributes (struct config_item_ *subtree, void *user_data)
|
||||||
{
|
{
|
||||||
(void) user_data;
|
(void) user_data;
|
||||||
|
// TODO: assign user_data to all the subitems
|
||||||
config_schema_apply_to_object (g_config_attributes, subtree);
|
config_schema_apply_to_object (g_config_attributes, subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1599,12 +1593,10 @@ static void
|
||||||
register_config_modules (struct app_context *ctx)
|
register_config_modules (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
struct config *config = &ctx->config;
|
struct config *config = &ctx->config;
|
||||||
config_register_module (config,
|
// The servers are loaded later when we can create buffers for them
|
||||||
"server", load_config_server, ctx);
|
config_register_module (config, "servers", NULL, NULL);
|
||||||
config_register_module (config,
|
config_register_module (config, "behaviour", load_config_behaviour, ctx);
|
||||||
"behaviour", load_config_behaviour, ctx);
|
config_register_module (config, "attributes", load_config_attributes, ctx);
|
||||||
config_register_module (config,
|
|
||||||
"attributes", load_config_attributes, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -2930,13 +2922,14 @@ buffer_get_index (struct app_context *ctx, struct buffer *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_buffers (struct app_context *ctx)
|
init_global_buffer (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
struct buffer *global = ctx->global_buffer = buffer_new ();
|
struct buffer *global = ctx->global_buffer = buffer_new ();
|
||||||
global->type = BUFFER_GLOBAL;
|
global->type = BUFFER_GLOBAL;
|
||||||
global->name = xstrdup (PROGRAM_NAME);
|
global->name = xstrdup (PROGRAM_NAME);
|
||||||
|
|
||||||
buffer_add (ctx, global);
|
buffer_add (ctx, global);
|
||||||
|
buffer_activate (ctx, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Users, channels ---------------------------------------------------------
|
// --- Users, channels ---------------------------------------------------------
|
||||||
|
@ -8388,6 +8381,75 @@ load_configuration (struct app_context *ctx)
|
||||||
get_config_boolean (ctx->config.root, "behaviour.isolate_buffers");
|
get_config_boolean (ctx->config.root, "behaviour.isolate_buffers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_server_from_config (struct app_context *ctx,
|
||||||
|
const char *name, struct config_item_ *subtree)
|
||||||
|
{
|
||||||
|
// They're case-insensitive in the application but not so in the config
|
||||||
|
if (str_map_find (&ctx->servers, name))
|
||||||
|
{
|
||||||
|
log_global_error (ctx, "Error in configuration: "
|
||||||
|
"ignoring server `#s' as it collides with another one", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct server *s = xmalloc (sizeof *s);
|
||||||
|
server_init (s, &ctx->poller);
|
||||||
|
|
||||||
|
// TODO: assign user_data (s) to all the subitems
|
||||||
|
config_schema_apply_to_object (g_config_server, subtree);
|
||||||
|
|
||||||
|
s->ctx = ctx;
|
||||||
|
s->name = xstrdup (name);
|
||||||
|
str_map_set (&ctx->servers, s->name, s);
|
||||||
|
s->config = subtree;
|
||||||
|
|
||||||
|
// Add a buffer and activate it
|
||||||
|
struct buffer *buffer = s->buffer = buffer_new ();
|
||||||
|
buffer->type = BUFFER_SERVER;
|
||||||
|
buffer->name = xstrdup (s->name);
|
||||||
|
buffer->server = s;
|
||||||
|
|
||||||
|
buffer_add (ctx, buffer);
|
||||||
|
buffer_activate (ctx, buffer);
|
||||||
|
|
||||||
|
// XXX: is this desirable in here? I think we should do it only when
|
||||||
|
// actually creating a new server instead of every time we load them.
|
||||||
|
struct error *e = NULL;
|
||||||
|
if (!irc_autofill_user_info (s, &e))
|
||||||
|
{
|
||||||
|
log_server_error (s, s->buffer,
|
||||||
|
"#s: #s", "Failed to fill in user details", e->message);
|
||||||
|
error_free (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to the server ASAP
|
||||||
|
// TODO: make this configurable ("autoconnect")
|
||||||
|
poller_timer_set (&s->reconnect_tmr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_servers (struct app_context *ctx)
|
||||||
|
{
|
||||||
|
struct config_item_ *servers =
|
||||||
|
config_item_get (ctx->config.root, "servers", NULL);
|
||||||
|
|
||||||
|
struct str_map_iter iter;
|
||||||
|
str_map_iter_init (&iter, &servers->value.object);
|
||||||
|
|
||||||
|
struct config_item_ *s;
|
||||||
|
while ((s = str_map_iter_next (&iter)))
|
||||||
|
{
|
||||||
|
if (s->type != CONFIG_ITEM_OBJECT)
|
||||||
|
log_global_error (ctx, "Error in configuration: "
|
||||||
|
"ignoring server `#s' as it's not an object", iter.link->key);
|
||||||
|
else
|
||||||
|
load_server_from_config (ctx, iter.link->key, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Signals -----------------------------------------------------------------
|
// --- Signals -----------------------------------------------------------------
|
||||||
|
|
||||||
static int g_signal_pipe[2]; ///< A pipe used to signal... signals
|
static int g_signal_pipe[2]; ///< A pipe used to signal... signals
|
||||||
|
@ -8603,40 +8665,6 @@ display_logo (void)
|
||||||
str_vector_free (&v);
|
str_vector_free (&v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
create_server (struct app_context *ctx)
|
|
||||||
{
|
|
||||||
struct server *s = xmalloc (sizeof *s);
|
|
||||||
server_init (s, &ctx->poller);
|
|
||||||
|
|
||||||
s->ctx = ctx;
|
|
||||||
s->name = xstrdup ("server");
|
|
||||||
str_map_set (&ctx->servers, s->name, s);
|
|
||||||
|
|
||||||
// Load configuration
|
|
||||||
s->config = config_item_get (ctx->config.root, "server", NULL);
|
|
||||||
hard_assert (s->config != NULL);
|
|
||||||
|
|
||||||
struct error *e = NULL;
|
|
||||||
if (!irc_autofill_user_info (s, &e))
|
|
||||||
{
|
|
||||||
print_error ("%s: %s", "failed to fill in user details", e->message);
|
|
||||||
error_free (e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a buffer and activate it
|
|
||||||
struct buffer *buffer = s->buffer = buffer_new ();
|
|
||||||
buffer->type = BUFFER_SERVER;
|
|
||||||
buffer->name = xstrdup (s->name);
|
|
||||||
buffer->server = s;
|
|
||||||
|
|
||||||
buffer_add (ctx, buffer);
|
|
||||||
buffer_activate (ctx, buffer);
|
|
||||||
|
|
||||||
// Connect to the server ASAP
|
|
||||||
poller_timer_set (&s->reconnect_tmr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -8695,14 +8723,12 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
init_colors (&ctx);
|
init_colors (&ctx);
|
||||||
init_poller_events (&ctx);
|
init_poller_events (&ctx);
|
||||||
init_buffers (&ctx);
|
init_global_buffer (&ctx);
|
||||||
|
init_servers (&ctx);
|
||||||
|
|
||||||
refresh_prompt (&ctx);
|
refresh_prompt (&ctx);
|
||||||
input_start (&ctx.input, argv[0]);
|
input_start (&ctx.input, argv[0]);
|
||||||
|
|
||||||
// TODO: finish multi-server
|
|
||||||
create_server (&ctx);
|
|
||||||
|
|
||||||
ctx.polling = true;
|
ctx.polling = true;
|
||||||
while (ctx.polling)
|
while (ctx.polling)
|
||||||
poller_run (&ctx.poller);
|
poller_run (&ctx.poller);
|
||||||
|
|
Loading…
Reference in New Issue