aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.c4
-rw-r--r--degesch.c132
2 files changed, 81 insertions, 55 deletions
diff --git a/common.c b/common.c
index 951055c..102cbd6 100644
--- a/common.c
+++ b/common.c
@@ -1131,7 +1131,6 @@ config_schema_accepts_type
&& config_item_type_is_string (type))
return true;
return !self->default_ && type == CONFIG_ITEM_NULL;
-
}
static bool
@@ -2008,6 +2007,7 @@ config_load (struct config *self, struct config_item_ *root)
subtree = config_item_object ();
str_map_set (&root->value.object, module->name, subtree);
}
- module->loader (subtree, module->user_data);
+ if (module->loader)
+ module->loader (subtree, module->user_data);
}
}
diff --git a/degesch.c b/degesch.c
index 8cd192b..b56f36b 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1574,17 +1574,10 @@ 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
load_config_behaviour (struct config_item_ *subtree, void *user_data)
{
(void) user_data;
+ // TODO: assign user_data to all the subitems
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)
{
(void) user_data;
+ // TODO: assign user_data to all the subitems
config_schema_apply_to_object (g_config_attributes, subtree);
}
@@ -1599,12 +1593,10 @@ static void
register_config_modules (struct app_context *ctx)
{
struct config *config = &ctx->config;
- config_register_module (config,
- "server", load_config_server, ctx);
- config_register_module (config,
- "behaviour", load_config_behaviour, ctx);
- config_register_module (config,
- "attributes", load_config_attributes, ctx);
+ // The servers are loaded later when we can create buffers for them
+ config_register_module (config, "servers", NULL, NULL);
+ config_register_module (config, "behaviour", load_config_behaviour, 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
-init_buffers (struct app_context *ctx)
+init_global_buffer (struct app_context *ctx)
{
struct buffer *global = ctx->global_buffer = buffer_new ();
global->type = BUFFER_GLOBAL;
global->name = xstrdup (PROGRAM_NAME);
buffer_add (ctx, global);
+ buffer_activate (ctx, global);
}
// --- Users, channels ---------------------------------------------------------
@@ -8388,6 +8381,75 @@ load_configuration (struct app_context *ctx)
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 -----------------------------------------------------------------
static int g_signal_pipe[2]; ///< A pipe used to signal... signals
@@ -8603,40 +8665,6 @@ display_logo (void)
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
main (int argc, char *argv[])
{
@@ -8695,14 +8723,12 @@ main (int argc, char *argv[])
init_colors (&ctx);
init_poller_events (&ctx);
- init_buffers (&ctx);
+ init_global_buffer (&ctx);
+ init_servers (&ctx);
refresh_prompt (&ctx);
input_start (&ctx.input, argv[0]);
- // TODO: finish multi-server
- create_server (&ctx);
-
ctx.polling = true;
while (ctx.polling)
poller_run (&ctx.poller);