*push*
[NeonServV5.git] / UserNode.c
1 #include "UserNode.h"
2
3 static struct UserNode **userList;
4
5 void init_UserNode() {
6     userList = calloc(VALID_NICK_CHARS_FIRST_LEN, sizeof(*userList));
7     
8 }
9
10 int is_valid_nick(const char *nick) {
11     unsigned int i;
12     //first char must be one of: a-zA-Z{|}~[\]^_`
13     if (!strchr(VALID_NICK_CHARS_FIRST, *nick))
14         return 0;
15     //all other chars must be one of: a-zA-Z0-9{|}~[\]^_`
16     for (i = 0; nick[i]; ++i)
17         if (!strchr(VALID_NICK_CHARS, nick[i]))
18             return 0;
19     if (strlen(nick) > NICKLEN)
20         return 0;
21     return 1;
22 }
23
24 static int get_nicklist_entry(int nick) {
25     int i;
26     char *valid_chars = VALID_NICK_CHARS_FIRST;
27     for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) {
28         if(valid_chars[i] == nick)
29             return i;
30     }
31     return -1; //ERROR!
32 }
33
34 struct UserNode* getUserByNick(const char *nick) { //case sensitive
35     int userListIndex = get_nicklist_entry(*nick);
36     if(userListIndex == -1 || userList[userListIndex] == NULL)
37         return NULL;
38     struct UserNode *user;
39     for(user = userList[userListIndex]; user; user = user->next) {
40         if(!stricmp(nick, user->nick))
41             return user;
42     }
43     return NULL;
44 }
45
46 struct UserNode* searchUserByNick(const char *nick) { //case insensitive
47     if(!isalpha(*nick)) 
48         return getUserByNick(nick);
49
50     int userListIndex;
51     struct UserNode *user;
52
53     //search in the lower case "section"
54     userListIndex = get_nicklist_entry(tolower(*nick));
55     if(userListIndex != -1 && userList[userListIndex] != NULL) {
56         for(user = userList[userListIndex]; user; user = user->next) {
57             if(!stricmp(nick, user->nick))
58                 return user;
59         }
60     }
61     //search in the upper case "section"
62     userListIndex = get_nicklist_entry(toupper(*nick));
63     if(userListIndex != -1 && userList[userListIndex] != NULL) {
64         for(user = userList[userListIndex]; user; user = user->next) {
65             if(!stricmp(nick, user->nick))
66                 return user;
67         }
68     }
69     return NULL;
70 }
71
72 struct UserNode* addUser(const char *nick) {
73     int userListIndex = get_nicklist_entry(*nick);
74     if(userListIndex == -1 || !is_valid_nick(nick))
75         return NULL;
76     struct UserNode *user = malloc(sizeof(*user));
77     if (!user)
78     {
79         perror("malloc() failed");
80         return NULL;
81     }
82     strcpy(user->nick, nick);
83     user->ident[0] = 0;
84     user->host[0] = 0;
85     user->realname[0] = 0;
86     user->flags = 0;
87     user->channel = NULL;
88     user->next = userList[userListIndex];
89     userList[userListIndex] = user;
90 }
91
92 int renameUser(struct UserNode* user, const char *new_nick) {
93     if(!is_valid_nick(new_nick))
94         return 0;
95     if(user->nick[0] == *new_nick) {
96         strcpy(user->nick, new_nick);
97         return 1;
98     }
99     int userListIndex = get_nicklist_entry(*new_nick);
100     delUser(user, 0);
101     strcpy(user->nick, new_nick);
102     user->next = userList[userListIndex];
103     userList[userListIndex] = user;
104     return 1;
105 }
106
107 void delUser(struct UserNode* user, int freeUser) {
108     int userListIndex = get_nicklist_entry(user->nick[0]);
109     if(userListIndex == -1) return;
110     struct UserNode *cuser, *last_user = NULL;
111     for(cuser = userList[userListIndex]; cuser; cuser = cuser->next) {
112         if(cuser == user) {
113             if(last_user)
114                 last_user->next = user->next;
115             else
116                 userList[userListIndex] = user->next;
117             break;
118         } else
119             last_user = cuser;
120     }
121     if(freeUser)
122         free(user);
123     else
124         user->next = NULL;
125 }