4 static struct UserNode **userList;
7 userList = calloc(VALID_NICK_CHARS_FIRST_LEN+1, sizeof(*userList));
10 int is_valid_nick(const char *nick) {
12 //first char must be one of: a-zA-Z{|}~[\]^_`
13 if (!strchr(VALID_NICK_CHARS_FIRST, *nick))
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]))
19 if (strlen(nick) > NICKLEN)
24 static int get_nicklist_entry(int nick) {
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)
34 struct UserNode* getUserByNick(const char *nick) { //case sensitive
35 int userListIndex = get_nicklist_entry(*nick);
36 if(userListIndex == -1 || userList[userListIndex] == NULL)
38 struct UserNode *user;
39 for(user = userList[userListIndex]; user; user = user->next) {
40 if(!stricmp(nick, user->nick))
46 struct UserNode* getUserByMask(const char *mask) { //case sensitive
47 char cmask[strlen(mask)+1];
50 struct UserNode *user = NULL;
51 for(i = 0; i < strlen(mask); i++) {
54 user = getUserByNick(&cmask[0]);
56 } else if(cmask[i] == '.') {
64 struct UserNode* searchUserByNick(const char *nick) { //case insensitive
66 return getUserByNick(nick);
69 struct UserNode *user;
71 //search in the lower case "section"
72 userListIndex = get_nicklist_entry(tolower(*nick));
73 if(userListIndex != -1 && userList[userListIndex] != NULL) {
74 for(user = userList[userListIndex]; user; user = user->next) {
75 if(!stricmp(nick, user->nick))
79 //search in the upper case "section"
80 userListIndex = get_nicklist_entry(toupper(*nick));
81 if(userListIndex != -1 && userList[userListIndex] != NULL) {
82 for(user = userList[userListIndex]; user; user = user->next) {
83 if(!stricmp(nick, user->nick))
90 struct UserNode* addUser(const char *nick) {
91 int userListIndex = get_nicklist_entry(*nick);
92 if(userListIndex == -1 || !is_valid_nick(nick))
94 struct UserNode *user = malloc(sizeof(*user));
97 perror("malloc() failed");
100 strcpy(user->nick, nick);
101 user->created = time(0);
104 user->realname[0] = 0;
106 user->channel = NULL;
107 user->next = userList[userListIndex];
108 userList[userListIndex] = user;
112 struct UserNode* addUserMask(const char *mask) {
113 char cmask[strlen(mask)+1];
116 struct UserNode *user = NULL;
117 for(i = 0; i < strlen(mask)+1; i++) {
118 if(cmask[i] == '!') {
120 user = addUser(cmask);
121 if(user == NULL) return NULL;
123 } else if(cmask[i] == '.' && !user) {
126 } else if(cmask[i] == '@') {
127 if(user == NULL) return NULL;
129 strcpy(user->ident, &cmask[ii]);
131 } else if(cmask[i] == '\0') {
132 if(user == NULL) return NULL;
133 strcpy(user->host, &cmask[ii]);
139 struct UserNode* createTempUser(const char *mask) {
140 //note: it could also be a server we have to create a temponary user for...
141 char cmask[strlen(mask)+1];
144 struct UserNode *user = NULL;
145 for(i = 0; i < strlen(mask)+1; i++) {
146 if(cmask[i] == '!') {
148 user = malloc(sizeof(*user));
151 perror("malloc() failed");
154 strcpy(user->nick, cmask);
155 user->created = time(0);
158 user->realname[0] = 0;
160 user->channel = NULL;
162 } else if(cmask[i] == '.' && !user) {
164 user = malloc(sizeof(*user));
167 perror("malloc() failed");
170 strcpy(user->host, cmask);
171 user->created = time(0);
174 user->realname[0] = 0;
175 user->flags = USERFLAG_ISSERVER;
176 user->channel = NULL;
178 } else if(cmask[i] == '@') {
179 if(user == NULL) return NULL;
181 strcpy(user->ident, &cmask[ii]);
183 } else if(cmask[i] == '\0') {
184 if(user == NULL) return NULL;
185 strcpy(user->host, &cmask[ii]);
191 int renameUser(struct UserNode* user, const char *new_nick) {
192 if(!is_valid_nick(new_nick))
194 if(user->nick[0] == *new_nick) {
195 strcpy(user->nick, new_nick);
198 int userListIndex = get_nicklist_entry(*new_nick);
200 strcpy(user->nick, new_nick);
201 user->next = userList[userListIndex];
202 userList[userListIndex] = user;
206 void delUser(struct UserNode* user, int freeUser) {
207 int userListIndex = get_nicklist_entry(user->nick[0]);
208 if(userListIndex == -1) return;
209 struct UserNode *cuser, *last_user = NULL;
210 for(cuser = userList[userListIndex]; cuser; cuser = cuser->next) {
213 last_user->next = user->next;
215 userList[userListIndex] = user->next;
221 struct ChanUser *chanUser, *next;
222 for(chanUser = user->channel; chanUser; chanUser = next) {
223 next = chanUser->next_chan;
224 removeChanUserFromLists(chanUser, 1, 0, freeUser);
233 void clearTempUsers() {
234 int userListIndex = TEMPUSER_LIST_INDEX;
235 struct UserNode *cuser, *last_user = NULL, *next;
236 time_t now = time(0);
237 for(cuser = userList[userListIndex]; cuser; cuser = next) {
239 if(cuser->flags & USERFLAG_FREETMPUSER || now - cuser->created >= 300) {
241 last_user->next = cuser->next;
243 userList[userListIndex] = cuser->next;