fixed temporary user management
authorpk910 <philipp@zoelle1.de>
Sun, 8 Jan 2012 05:04:04 +0000 (06:04 +0100)
committerpk910 <philipp@zoelle1.de>
Sun, 8 Jan 2012 05:29:01 +0000 (06:29 +0100)
src/IRCParser.c
src/UserNode.c
src/UserNode.h
src/cmd_neonserv_unban.c

index 6e6c61318a7a2104920bc1b331a4c35f766559b9..750ac7b783c871643de7fe85ecb1b04cf7a491ee 100644 (file)
@@ -395,7 +395,7 @@ static IRC_CMD(raw_kick) {
     int keep_channel = 1;
     if(isUserOnChan(target, chan) && (chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
         if(user == NULL) {
-            user = createTempUser(from);
+            user = createTempUserMask(from);
                        if(!user) return 0;
             user->flags |= USERFLAG_ISTMPUSER;
         }
@@ -425,7 +425,7 @@ static IRC_CMD(raw_topic) {
     if(chan == NULL) return 0;
     if(chan->chanbot != client->user) return 1; //just ignore it to prevent event duplicates
     if(user == NULL) {
-        user = createTempUser(from);
+        user = createTempUserMask(from);
                if(!user) return 0;
         user->flags |= USERFLAG_ISTMPUSER;
     }
@@ -438,7 +438,7 @@ static IRC_CMD(raw_privmsg) {
     if(from == NULL || argc < 2) return 0;
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
-        user = createTempUser(from);
+        user = createTempUserMask(from);
                if(!user) return 0;
         user->flags |= USERFLAG_ISTMPUSER;
     }
@@ -496,7 +496,7 @@ static IRC_CMD(raw_notice) {
     if(from == NULL || argc < 2) return 0;
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
-        user = createTempUser(from);
+        user = createTempUserMask(from);
                if(!user) return 0;
         user->flags |= USERFLAG_ISTMPUSER;
     }
@@ -551,7 +551,7 @@ static IRC_CMD(raw_invite) {
     if(from == NULL || argc < 2) return 0;
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
-        user = createTempUser(from);
+        user = createTempUserMask(from);
                if(!user) return 0;
         user->flags |= USERFLAG_ISTMPUSER;
     }
@@ -563,7 +563,7 @@ static IRC_CMD(raw_mode) {
     if(from == NULL || argc < 2) return 0;
     struct UserNode *user = getUserByMask(from);
     if(user == NULL) {
-        user = createTempUser(from);
+        user = createTempUserMask(from);
                if(!user) return 0;
         user->flags |= USERFLAG_ISTMPUSER;
     }
index 739722ad4009d8755d512b62f8aa50546588b44d..3f20a13eccdf93a8a7a85409bc405f0f8d87fbd2 100644 (file)
@@ -122,7 +122,7 @@ struct UserNode* searchUserByNick(const char *nick) { //case insensitive
 int countUsersWithHost(char *host) {
     int i, count = 0;
     struct UserNode *user;
-    for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) {
+    for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) {
         for(user = userList[i]; user; user = user->next) {
             if(!strcmp(user->host, host)) {
                 count++;
@@ -135,7 +135,7 @@ int countUsersWithHost(char *host) {
 char *getAuthFakehost(char *auth) {
     int i;
     struct UserNode *user;
-    for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) {
+    for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) {
         for(user = userList[i]; user; user = user->next) {
             if((user->flags & USERFLAG_ISAUTHED) && !strcmp(user->auth, auth) && isFakeHost(user->host)) {
                 return user->host;
@@ -152,7 +152,7 @@ struct UserNode* getAllUsers(struct UserNode *last) {
             cindex = 0;
         else
             cindex = get_nicklist_entry(last->nick[0]) + 1;
-        while(userList[cindex] == NULL && cindex <= VALID_NICK_CHARS_FIRST_LEN)
+        while(userList[cindex] == NULL && cindex < VALID_NICK_CHARS_FIRST_LEN)
             cindex++;
         if(cindex > VALID_NICK_CHARS_FIRST_LEN) return NULL;
         return userList[cindex];
@@ -177,7 +177,7 @@ struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last) {
 int getUserCount() {
     int i, count = 0;
     struct UserNode *user;
-    for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) {
+    for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) {
         for(user = userList[i]; user; user = user->next) {
             count++;
         }
@@ -235,32 +235,80 @@ struct UserNode* addUserMask(const char *mask) {
     return user;
 }
 
-struct UserNode* createTempUser(const char *mask) {
+struct UserNode* createTempUser(const char *nick) {
+    int already_on_list = 0;
+    struct UserNode *user = NULL;
+    if(!is_valid_nick(nick)) {
+        return NULL;
+    }
+    for(user = userList[TEMPUSER_LIST_INDEX]; user; user = user->next) {
+        if(!stricmp(user->nick, nick)) {
+            already_on_list = 1;
+            break;
+        }
+    }
+    if(!user) {
+        user = malloc(sizeof(*user));
+        if (!user) {
+            perror("malloc() failed");
+            return NULL;
+        }
+        user->ident[0] = 0;
+        user->host[0] = 0;
+        user->realname[0] = 0;
+        user->flags = 0;
+        user->channel = NULL;
+        user->last_who = 0;
+    } else
+        user->flags &= ~USERFLAG_FREETMPUSER;
+    user->created = time(0);
+    if(user->created - user->last_who > REWHO_TIMEOUT)
+        user->flags &= ~USERFLAG_ISAUTHED; //remove authed flag (security reasons)
+    strcpy(user->nick, nick);
+    if(!already_on_list) {
+        user->next = userList[TEMPUSER_LIST_INDEX];
+        userList[TEMPUSER_LIST_INDEX] = user;
+    }
+    return user;
+}
+
+struct UserNode* createTempUserMask(const char *mask) {
     //note: it could also be a server we have to create a temponary user for...
     char cmask[strlen(mask)+1];
     strcpy(cmask, mask);
     int i, ii = 0;
+    int already_on_list = 0;
     struct UserNode *user = NULL;
     for(i = 0; i < strlen(mask)+1; i++) {
         if(cmask[i] == '!') {
             cmask[i] = 0;
-                       if(!is_valid_nick(cmask)) {
-                               return NULL;
-                       }
-            user = malloc(sizeof(*user));
-            if (!user)
-            {
-                perror("malloc() failed");
+            if(!is_valid_nick(cmask)) {
                 return NULL;
             }
-            strcpy(user->nick, cmask);
+            for(user = userList[TEMPUSER_LIST_INDEX]; user; user = user->next) {
+                if(!stricmp(user->nick, cmask)) {
+                    already_on_list = 1;
+                    break;
+                }
+            }
+            if(!user) {
+                user = malloc(sizeof(*user));
+                if (!user) {
+                    perror("malloc() failed");
+                    return NULL;
+                }
+                user->ident[0] = 0;
+                user->host[0] = 0;
+                user->realname[0] = 0;
+                user->flags = 0;
+                user->channel = NULL;
+                user->last_who = 0;
+            } else
+                user->flags &= ~USERFLAG_FREETMPUSER;
             user->created = time(0);
-            user->ident[0] = 0;
-            user->host[0] = 0;
-            user->realname[0] = 0;
-            user->flags = 0;
-            user->channel = NULL;
-            user->last_who = 0;
+            if(user->created - user->last_who > REWHO_TIMEOUT)
+                user->flags &= ~USERFLAG_ISAUTHED; //remove authed flag (security reasons)
+            strcpy(user->nick, cmask);
             ii = i+1;
         } else if(cmask[i] == '.' && !user) {
             //it's a server
@@ -301,11 +349,15 @@ struct UserNode* createTempUser(const char *mask) {
                 user->flags = 0;
                 user->channel = NULL;
                 user->last_who = 0;
-                return user;
+                break;
             }
             strcpy(user->host, &cmask[ii]);
         }
     }
+    if(!already_on_list) {
+        user->next = userList[TEMPUSER_LIST_INDEX];
+        userList[TEMPUSER_LIST_INDEX] = user;
+    }
     return user;
 }
 
@@ -340,7 +392,7 @@ int renameUser(struct UserNode* user, const char *new_nick) {
 }
 
 void delUser(struct UserNode* user, int freeUser) {
-    int userListIndex = get_nicklist_entry(user->nick[0]);
+    int userListIndex = ((user->flags & USERFLAG_ISTMPUSER) ? TEMPUSER_LIST_INDEX : get_nicklist_entry(user->nick[0]));
     if(userListIndex == -1) return;
     event_freeuser(user);
     struct UserNode *cuser, *last_user = NULL;
@@ -354,10 +406,10 @@ void delUser(struct UserNode* user, int freeUser) {
         } else
             last_user = cuser;
     }
-       if(freeUser && (user->flags & USERFLAG_IS_ON_WHO_QUEUE)) {
-               user->flags |= USERFLAG_FREE_AFTER_WHO;
-               freeUser = 0;
-       }
+    if(freeUser && (user->flags & USERFLAG_IS_ON_WHO_QUEUE)) {
+        user->flags |= USERFLAG_FREE_AFTER_WHO;
+        freeUser = 0;
+    }
     if(user->channel) {
         struct ChanUser *chanUser, *next;
         for(chanUser = user->channel; chanUser; chanUser = next) {
@@ -373,17 +425,12 @@ void delUser(struct UserNode* user, int freeUser) {
 
 void clearTempUsers() {
     int userListIndex = TEMPUSER_LIST_INDEX;
-    struct UserNode *cuser, *last_user = NULL, *next;
+    struct UserNode *cuser, *next;
     time_t now = time(0);
     for(cuser = userList[userListIndex]; cuser; cuser = next) {
         next = cuser->next;
         if(cuser->flags & USERFLAG_FREETMPUSER || now - cuser->created >= 300) {
-            if(last_user)
-                last_user->next = cuser->next;
-            else
-                userList[userListIndex] = cuser->next;
-            break;
-        } else
-            last_user = cuser;
+            delUser(cuser, 1);
+        }
     }
 }
index 699c53990041aa255a6b94b4b350e1d25eb10e51..bb794b7c81ed81772431c40eca740da600e22bc7 100644 (file)
@@ -70,7 +70,8 @@ struct UserNode* getUsersWithAuth(const char *auth, struct UserNode *last);
 int getUserCount();
 struct UserNode* addUser(const char *nick);
 struct UserNode* addUserMask(const char *mask);
-struct UserNode* createTempUser(const char *mask);
+struct UserNode* createTempUser(const char *nick);
+struct UserNode* createTempUserMask(const char *mask);
 int renameUser(struct UserNode* user, const char *new_nick);
 void delUser(struct UserNode* user, int freeUser);
 void clearTempUsers();
index 3df515059fe0ea77ae8f9790070e148866903e6d..f88033b308e80cce06e4dc8f58e0698f43c0dd89 100644 (file)
@@ -63,7 +63,7 @@ CMD_BIND(neonserv_cmd_unban) {
         if(is_valid_nick(mask)) {
             struct UserNode *cuser = getUserByNick(mask);
             if(!cuser) {
-                cuser = createTempUser(mask);
+                cuser = createTempUserMask(mask);
                                if(!cuser) {
                                        break; //internal bot error
                                }