added OPER support (let the bots try to op themselves)
[NeonServV5.git] / src / IRCParser.c
index e92b3462279b6c18895ff66d4eb0b29c349104cc..2ff95c8ba066b3e2b440d1b6250e4242060e1042 100644 (file)
@@ -1,4 +1,4 @@
-/* IRCParser.c - NeonServ v5.3
+/* IRCParser.c - NeonServ v5.4
  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
  * 
  * This program is free software: you can redistribute it and/or modify
@@ -466,17 +466,28 @@ static IRC_CMD(raw_kick) {
 
 static IRC_CMD(raw_topic) {
     if(from == NULL || argc < 2) return 0;
+    SYNCHRONIZE(cache_sync);
     struct UserNode *user = getUserByMask(from);
     struct ChanNode *chan = getChanByName(argv[0]);
-    if(chan == NULL) return 0;
-    if(chan->chanbot != client->user) return 1; //just ignore it to prevent event duplicates
+    if(chan == NULL) {
+        DESYNCHRONIZE(cache_sync);
+        return 0;
+    }
+    if(chan->chanbot != client->user) {
+        DESYNCHRONIZE(cache_sync);
+        return 1; //just ignore it to prevent event duplicates
+    }
     if(user == NULL) {
         user = createTempUserMask(from);
-               if(!user) return 0;
+               if(!user) {
+            DESYNCHRONIZE(cache_sync);
+            return 0;
+        }
         user->flags |= USERFLAG_ISTMPUSER;
     }
     event_topic(user, chan, argv[1]);
     strcpy(chan->topic, argv[1]);
+    DESYNCHRONIZE(cache_sync);
     return 1;
 }
 
@@ -570,15 +581,26 @@ static void client_renamed(struct ClientSocket *client);
 
 static IRC_CMD(raw_nick) {
     if(from == NULL || argc == 0) return 0;
+    SYNCHRONIZE(cache_sync);
     struct UserNode *user = getUserByMask(from);
-    if(user == NULL) return 0;
+    if(user == NULL) {
+        DESYNCHRONIZE(cache_sync);
+        return 0;
+    }
     if(isBot(user)) {
-        if(client->user != user) return 1;
+        if(client->user != user) {
+            DESYNCHRONIZE(cache_sync);
+            return 1;
+        }
         client_renamed(client);
     }
-    else if(!is_firstBotSeeUser(client, user)) return 1; //we ignore it - but it's not a parse error
+    else if(!is_firstBotSeeUser(client, user)) {
+        DESYNCHRONIZE(cache_sync);
+        return 1; //we ignore it - but it's not a parse error
+    }
     event_nick(user, argv[0]);
     renameUser(user, argv[0]);
+    DESYNCHRONIZE(cache_sync);
     return 1;
 }
 
@@ -621,22 +643,38 @@ static IRC_CMD(raw_invite) {
 
 static IRC_CMD(raw_mode) {
     if(from == NULL || argc < 2) return 0;
+    SYNCHRONIZE(cache_sync);
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
         user = createTempUserMask(from);
-               if(!user) return 0;
+               if(!user) {
+            DESYNCHRONIZE(cache_sync);
+            return 0;
+        }
         user->flags |= USERFLAG_ISTMPUSER;
     }
     if(argv[0][0] == '#') {
         //ChannelMode
         struct ChanNode *chan = getChanByName(argv[0]);
-        if(!chan) return 0;
-        if(chan->chanbot != client->user) return 1;
+        if(!chan) {
+            DESYNCHRONIZE(cache_sync);
+            return 0;
+        }
+        if(chan->chanbot != client->user) {
+            DESYNCHRONIZE(cache_sync);
+            return 1;
+        }
         parseModes(chan->modes, argv[1], argv+2, argc-2);
         event_mode(user, chan, argv[1], argv+2, argc-2);
     } else {
         //UserMode
+        if(stricmp(client->user->nick, argv[0])) {
+            DESYNCHRONIZE(cache_sync);
+            return 0;
+        }
+        parseUserModes(client->user, argv[1]);
     }
+    DESYNCHRONIZE(cache_sync);
     return 1;
 }
 
@@ -721,10 +759,50 @@ static void client_renamed(struct ClientSocket *client) {
     }
 }
 
+static void raw_005_network(struct ClientSocket *client, char *value) {
+    if(!value) return;
+    //check all other networknames
+    //if they are NOT simular to value throw a warning
+    SYNCHRONIZE(cache_sync); //all bots connect to the same time so there is a higher chance that this code is running on multiple threads at the same time
+    if(client->network_name)
+        free(client->network_name);
+    client->network_name = strdup(value);
+    struct ClientSocket *bot;
+    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+        if(bot == client) continue;
+        if(!bot->network_name) continue;
+        if(stricmp(bot->network_name, value)) {
+            putlog(LOGLEVEL_ERROR, "WARNING: Network name '%s' (%s) differs from '%s' (%s)! Connecting to multiple IRC-Networks with one instance is NOT supported!\n", client->network_name, client->nick, bot->network_name, bot->nick);
+            break;
+        }
+    }
+    DESYNCHRONIZE(cache_sync);
+}
+
+static IRC_CMD(raw_005) {
+    char *ptr1 = merge_argv(argv, 1, argc);
+    char *ptr2, *name, *value;
+    do {
+        ptr2 = strchr(ptr1, ' ');
+        if(ptr2)
+            *ptr2 = '\0';
+        name = ptr1;
+        if((value = strchr(ptr1, '='))) {
+            *value = '\0';
+            value++;
+        }
+        if(!stricmp(name, "NETWORK")) raw_005_network(client, value);
+        if(ptr2)
+            ptr1 = ptr2 + 1;
+    } while(ptr2);
+    return 1;
+}
+
 void init_parser() {
     //all the raws we receive...
     register_irc_function("437", raw_437);
     register_irc_function("002", raw_002);
+    register_irc_function("005", raw_005);
     register_irc_function("251", raw_251);
     register_irc_function("254", raw_254);
     register_irc_function("324", raw_324);