#include "view.h"
/* Global data */
-log_t *chat_log;
-int chat_len;
+server_t *servers;
+channel_t *channels;
+message_t *messages;
+int history;
/* Local data */
-static buf_t log_buf;
+static buf_t srv_buf;
+static buf_t chan_buf;
+static buf_t msg_buf;
-/* Local functions */
+static const char *proto_map[] = {
+ [IRC] "irc",
+ [XMPP] "xmpp",
+};
/* View init */
void chat_init(void)
{
- chat_log = (log_t*)log_buf.data;
- chat_len = 0;
+ servers = (server_t*)srv_buf.data;
+ channels = (channel_t*)chan_buf.data;
+ messages = (message_t*)msg_buf.data;
+ history = 0;
irc_init();
xmpp_init();
void chat_config(const char *group, const char *name, const char *key, const char *value)
{
- irc_config(group, name, key, value);
- xmpp_config(group, name, key, value);
+ int protocol = -1;
+ server_t *server = NULL;
+ channel_t *channel = NULL;
+
+ if (match(group, "server")) {
+ server = find_server(name);
+ if (match(key, "")) {
+ get_name(name);
+ }
+ else if (match(key, "protocol")) {
+ protocol = get_enum(value, proto_map, N_ELEMENTS(proto_map));
+ server = add_server(name, protocol);
+ }
+ else if (server) {
+ protocol = server->protocol;
+ }
+ else {
+ error("No server found for [%s]", name);
+ }
+ }
+
+ if (match(group, "channel")) {
+ channel = find_channel(name);
+ if (match(key, "")) {
+ get_name(name);
+ }
+ else if (match(key, "server")) {
+ server = find_server(get_string(value));
+ if (!server)
+ error("server '%s' does not exist", name);
+ channel = add_channel(name, server);
+ protocol = server->protocol;
+ server = NULL;
+ }
+ else if (channel) {
+ protocol = channel->server->protocol;
+ }
+ else {
+ error("No channel found for [%s]", name);
+ }
+ }
+
+ debug("chat_config: [%s-%s \"%s\"] %s = %s",
+ protocol>=0 ? proto_map[protocol] : "none",
+ group, name, key, value,
+ server, channel);
+
+ switch (protocol) {
+ case IRC:
+ irc_config(server, channel, group, name, key, value);
+ break;
+ case XMPP:
+ xmpp_config(server, channel, group, name, key, value);
+ break;
+ }
}
void chat_notice(const char *channel, const char *from, const char *fmt, ...)
chat_recv(channel, from, buf);
}
-void chat_recv(const char *channel, const char *from, const char *msg)
+void chat_recv(const char *channel, const char *from, const char *text)
{
- append(&log_buf, NULL, sizeof(log_t));
- chat_log = (log_t*)log_buf.data;
+ append(&msg_buf, NULL, sizeof(message_t));
+ messages = (message_t*)msg_buf.data;
- log_t *log = &chat_log[chat_len];
- log->when = time(NULL);
- log->from = strcopy(from);
- log->channel = strcopy(channel);
- log->msg = strcopy(msg);
+ message_t *msg = &messages[history];
+ msg->channel = find_channel(channel);
+ msg->when = time(NULL);
+ msg->from = strcopy(from);
+ msg->text = strcopy(text);
- chat_len++;
+ history++;
view_draw();
}
-void chat_send(const char *channel, const char *msg)
+void chat_send(const char *channel_name, const char *text)
{
- append(&log_buf, NULL, sizeof(log_t));
- chat_log = (log_t*)log_buf.data;
-
- log_t *log = &chat_log[chat_len];
- log->when = time(NULL);
- log->from = "andy";
- log->channel = strcopy(channel);
- log->msg = strcopy(msg);
-
- chat_len++;
- irc_send(channel, msg);
- xmpp_send(channel, msg);
+ channel_t *channel = find_channel(channel_name);
+
+ append(&msg_buf, NULL, sizeof(message_t));
+ messages = (message_t*)msg_buf.data;
+
+ message_t *msg = &messages[history];
+ msg->channel = channel;
+ msg->when = time(NULL);
+ msg->from = strcopy("andy");
+ msg->text = strcopy(text);
+ history++;
+
+ irc_send(msg);
+ xmpp_send(msg);
+
view_draw();
}
irc_exit();
xmpp_exit();
- for (int i = 0; i < chat_len; i++)
- free((void*)chat_log[i].msg);
- release(&log_buf);
+ for (int i = 0; i < history; i++)
+ free((void*)messages[i].text);
+ release(&msg_buf);
}
+
+/* Server and channel function */
+server_t *add_server(const char *name, protocol_t protocol)
+{
+ server_t *server = NULL;
+ debug("adding %s server \"%s\"", proto_map[protocol], name);
+ switch (protocol) {
+ case IRC:
+ server = irc_server();
+ break;
+ case XMPP:
+ server = xmpp_server();
+ break;
+ }
+ server->next = servers;
+ server->name = strcopy(name);
+ server->protocol = protocol;
+ return (servers = server);
+}
+
+channel_t *add_channel(const char *name, server_t *server)
+{
+ channel_t *channel = NULL;
+ debug("adding %s channel \"%s\"", server->name, name);
+ switch (server->protocol) {
+ case IRC:
+ channel = irc_channel();
+ break;
+ case XMPP:
+ channel = xmpp_channel();
+ break;
+ }
+ channel->next = channels;
+ channel->name = strcopy(name);
+ channel->server = server;
+ return (channels = channel);
+}
+
+server_t *find_server(const char *name)
+{
+ for (server_t *cur = servers; cur; cur = cur->next)
+ if (match(cur->name, name))
+ return cur;
+ return NULL;
+}
+
+channel_t *find_channel(const char *name)
+{
+ for (channel_t *cur = channels; cur; cur = cur->next) {
+ if (match(cur->name, name))
+ return cur;
+ }
+ return NULL;
+}
+