Remove casts made unneeded by the previous changeset.
[umurmur.git] / src / channel.c
index 77ee4157dfe3fba941e29a76a6561c2d5b8e55b8..ec331bb1cca9b83b5daa3a04edaa6b36ca117825 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
-   Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
+/* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
+   Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
 
    All rights reserved.
 
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "log.h"
+#include "memory.h"
 #include "list.h"
 #include "client.h"
 #include "channel.h"
@@ -46,10 +47,7 @@ static channel_t *createChannel(int id, const char *name, const char *desc)
 {
        channel_t *ch;
 
-       ch = malloc(sizeof(channel_t));
-       if (ch == NULL)
-               Log_fatal("out of memory");
-       memset(ch, 0, sizeof(channel_t));
+       ch = Memory_safeCalloc(1, sizeof(channel_t));
        ch->id = id;
        ch->name = strdup(name);
        if (desc)
@@ -93,7 +91,7 @@ static channel_t *next_channel(channel_t *ch)
        if (list_get_next(&ch->node) == &list_get_entry(&ch->node, channel_t, node)->parent->subs)
                return NULL;
        else
-               return list_get_entry(list_get_next(&ch->node), channel_t, node);       
+               return list_get_entry(list_get_next(&ch->node), channel_t, node);
 }
 #endif
 
@@ -134,7 +132,7 @@ channel_t *Chan_iterate_siblings(channel_t *parent, channel_t **channelpptr)
        *channelpptr = ch;
        return ch;
 }
-                       
+
 void Chan_init()
 {
        int i;
@@ -143,7 +141,7 @@ void Chan_init()
        const char *defaultChannelName;
 
        defaultChannelName = getStrConf(DEFAULT_CHANNEL);
-       
+
        for (i = 0; ; i++) {
                if (Conf_getNextChannel(&chdesc, i) < 0) {
                        if (i == 0)
@@ -153,6 +151,7 @@ void Chan_init()
                if (i == 0) {
                        rootChan = createChannel(0, chdesc.name, chdesc.description);
                        rootChan->noenter = chdesc.noenter;
+                       rootChan->silent = chdesc.silent;
                        list_add_tail(&rootChan->flatlist_node, &channels);
                        if (strcmp(defaultChannelName, chdesc.name) == 0)
                                defaultChan = rootChan;
@@ -161,18 +160,23 @@ void Chan_init()
                        channel_t *ch, *ch_itr = NULL;
                        ch = Chan_createChannel(chdesc.name, chdesc.description);
                        ch->noenter = chdesc.noenter;
-                       
+                       ch->position = chdesc.position;
+                       ch->silent = chdesc.silent;
+                       if (chdesc.password) {
+                               Log_info("Setting password on channel '%s'", ch->name);
+                               ch->password = strdup(chdesc.password);
+                       }
                        if (strcmp(defaultChannelName, chdesc.name) == 0) {
-                               Log_info("Setting default channel %s", ch->name); 
+                               Log_info("Setting default channel '%s'", ch->name);
                                defaultChan = ch;
                        }
-                       
+
                        do {
                                Chan_iterate(&ch_itr);
                        } while (ch_itr != NULL && strcmp(ch_itr->name, chdesc.parent) != 0);
-                       
+
                        if (ch_itr == NULL)
-                               Log_fatal("Error in channel configuration: parent not found");
+                               Log_fatal("Error in channel configuration: parent '%s' not found", chdesc.parent);
                        else {
                                Chan_addChannel(ch_itr, ch);
                                Log_info("Adding channel '%s' parent '%s'", ch->name, chdesc.parent);
@@ -181,13 +185,16 @@ void Chan_init()
        }
        if (defaultChan == NULL)
                defaultChan = rootChan;
-       
+
        if (defaultChan->noenter)
                Log_fatal("Error in channel configuration: default channel is marked as noenter");
+       if (defaultChan->password)
+               Log_fatal("Error in channel configuration: default channel has a password");
 
        /* Channel links */
        for (i = 0; ; i++) {
                channel_t *ch_src, *ch_dst, *ch_itr = NULL;
+               channellist_t *chl;
                if (Conf_getNextChannelLink(&chlink, i) < 0) {
                        if (i == 0)
                                Log_info("No channel links found in configuration file.");
@@ -202,8 +209,8 @@ void Chan_init()
                                          chlink.source);
                else
                        ch_src = ch_itr;
-               
-               ch_itr = NULL;          
+
+               ch_itr = NULL;
                do {
                        Chan_iterate(&ch_itr);
                } while (ch_itr != NULL && strcmp(ch_itr->name, chlink.destination) != 0);
@@ -212,8 +219,11 @@ void Chan_init()
                                          chlink.destination);
                else
                        ch_dst = ch_itr;
-               
-               list_add_tail(&ch_dst->link_node, &ch_src->channel_links);
+
+               chl = Memory_safeMalloc(1, sizeof(channellist_t));
+               chl->chan = ch_dst;
+               init_list_entry(&chl->node);
+               list_add_tail(&chl->node, &ch_src->channel_links);
                ch_src->linkcount++;
                Log_info("Adding channel link '%s' -> '%s'", ch_src->name, ch_dst->name);
        }
@@ -222,14 +232,22 @@ void Chan_init()
 void Chan_free()
 {
        struct dlist *itr, *save;
+       struct dlist *linkitr, *linksave;
        channel_t *ch;
-       
+
        list_iterate_safe(itr, save, &channels) {
                ch = list_get_entry(itr, channel_t, flatlist_node);
                Log_debug("Free channel '%s'", ch->name);
                free(ch->name);
                if (ch->desc)
                        free(ch->desc);
+               if (ch->password)
+                       free(ch->password);
+               list_iterate_safe(linkitr, linksave, &ch->channel_links) {
+                       channellist_t *chl;
+                       chl = list_get_entry(linkitr, channellist_t, node);
+                       free(chl);
+               }
                free(ch);
        }
 }
@@ -261,10 +279,10 @@ int Chan_userLeave(client_t *client)
 {
        channel_t *leaving = NULL;
        int leaving_id = -1;
-       
+
        if (client->channel) {
                list_del(&client->chan_node);
-               leaving = (channel_t *)client->channel;
+               leaving = client->channel;
                if (leaving->temporary && list_empty(&leaving->clients)) {
                        leaving_id = leaving->id;
                        Chan_freeChannel(leaving);
@@ -278,14 +296,14 @@ int Chan_userJoin(channel_t *ch, client_t *client)
        int leaving_id;
 
        /* Do nothing if user already is in this channel */
-       if ((channel_t *)client->channel == ch)
+       if (client->channel == ch)
                return 0;
-       
-       Log_debug("Add user %s to channel %s", client->username, ch->name); 
+
+       Log_debug("Add user %s to channel %s", client->username, ch->name);
        /* Only allowed in one channel at a time */
        leaving_id = Chan_userLeave(client);
        list_add_tail(&client->chan_node, &ch->clients);
-       client->channel = (void *)ch;
+       client->channel = ch;
        return leaving_id;
 }
 
@@ -300,23 +318,28 @@ int Chan_userJoin_id(int channelid, client_t *client)
                return -1;
        }
        else
-               return Chan_userJoin(ch_itr, client);   
+               return Chan_userJoin(ch_itr, client);
 }
 
-bool_t Chan_userJoin_id_test(int channelid)
+channelJoinResult_t Chan_userJoin_id_test(int channelid, client_t *client)
 {
+       channelJoinResult_t result;
        channel_t *ch_itr = NULL;
        do {
                Chan_iterate(&ch_itr);
        } while (ch_itr != NULL && ch_itr->id != channelid);
        if (ch_itr == NULL) {
                Log_warn("Channel id %d not found - ignoring.", channelid);
-               return false;
+               result.CHJOIN_NOTFOUND = true;
        }
-       if (ch_itr->noenter)
-               return false;
        else
-               return true;
+               result.CHJOIN_NOTFOUND = false;
+
+       result.CHJOIN_NOENTER = ch_itr->noenter;
+       result.CHJOIN_WRONGPW = ch_itr->password && !Client_token_match(client, ch_itr->password) && !client->isAdmin;
+       result.CHJOIN_SILENT = ch_itr->silent;
+
+       return result;
 }
 
 #if 0
@@ -354,8 +377,8 @@ void Chan_buildTreeList(channel_t *ch, struct dlist *head)
        channellist_t *chl;
        struct dlist *itr;
        channel_t *sub;
-       
-       chl = malloc(sizeof(channellist_t));
+
+       chl = Memory_safeMalloc(1, sizeof(channellist_t));
        chl->chan = ch;
        init_list_entry(&chl->node);
        list_add_tail(&chl->node, head);