4 static struct UserNode **userList;
7 userList = calloc(VALID_NICK_CHARS_FIRST_LEN, sizeof(*userList));
11 int is_valid_nick(const char *nick) {
13 //first char must be one of: a-zA-Z{|}~[\]^_`
14 if (!strchr(VALID_NICK_CHARS_FIRST, *nick))
16 //all other chars must be one of: a-zA-Z0-9{|}~[\]^_`
17 for (i = 0; nick[i]; ++i)
18 if (!strchr(VALID_NICK_CHARS, nick[i]))
20 if (strlen(nick) > NICKLEN)
25 static int get_nicklist_entry(int nick) {
27 char *valid_chars = VALID_NICK_CHARS_FIRST;
28 for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) {
29 if(valid_chars[i] == nick)
35 struct UserNode* getUserByNick(const char *nick) { //case sensitive
36 int userListIndex = get_nicklist_entry(*nick);
37 if(userListIndex == -1 || userList[userListIndex] == NULL)
39 struct UserNode *user;
40 for(user = userList[userListIndex]; user; user = user->next) {
41 if(!stricmp(nick, user->nick))
47 struct UserNode* getUserByMask(const char *mask) { //case sensitive
48 char cmask[strlen(mask)+1];
51 struct UserNode *user = NULL;
52 for(i = 0; i < strlen(mask); i++) {
55 user = getUserByNick(&cmask[0]);
57 } else if(cmask[i] == '.') {
65 struct UserNode* searchUserByNick(const char *nick) { //case insensitive
67 return getUserByNick(nick);
70 struct UserNode *user;
72 //search in the lower case "section"
73 userListIndex = get_nicklist_entry(tolower(*nick));
74 if(userListIndex != -1 && userList[userListIndex] != NULL) {
75 for(user = userList[userListIndex]; user; user = user->next) {
76 if(!stricmp(nick, user->nick))
80 //search in the upper case "section"
81 userListIndex = get_nicklist_entry(toupper(*nick));
82 if(userListIndex != -1 && userList[userListIndex] != NULL) {
83 for(user = userList[userListIndex]; user; user = user->next) {
84 if(!stricmp(nick, user->nick))
91 struct UserNode* addUser(const char *nick) {
92 int userListIndex = get_nicklist_entry(*nick);
93 if(userListIndex == -1 || !is_valid_nick(nick))
95 struct UserNode *user = malloc(sizeof(*user));
98 perror("malloc() failed");
101 strcpy(user->nick, nick);
104 user->realname[0] = 0;
106 user->channel = NULL;
107 user->next = userList[userListIndex];
108 userList[userListIndex] = user;
113 struct UserNode* addUserMask(const char *mask) {
114 char cmask[strlen(mask)+1];
117 struct UserNode *user = NULL;
118 for(i = 0; i < strlen(mask)+1; i++) {
119 if(cmask[i] == '!') {
121 user = addUser(&cmask[0]);
122 if(user == NULL) return NULL;
124 } else if(cmask[i] == '.' && !user) {
127 } else if(cmask[i] == '@') {
128 if(user == NULL) return NULL;
130 strcpy(user->ident, &cmask[ii]);
132 } else if(cmask[i] == '\0') {
133 if(user == NULL) return NULL;
134 strcpy(user->host, &cmask[ii]);
140 int renameUser(struct UserNode* user, const char *new_nick) {
141 if(!is_valid_nick(new_nick))
143 if(user->nick[0] == *new_nick) {
144 strcpy(user->nick, new_nick);
147 int userListIndex = get_nicklist_entry(*new_nick);
149 strcpy(user->nick, new_nick);
150 user->next = userList[userListIndex];
151 userList[userListIndex] = user;
155 void delUser(struct UserNode* user, int freeUser) {
156 int userListIndex = get_nicklist_entry(user->nick[0]);
157 if(userListIndex == -1) return;
158 struct UserNode *cuser, *last_user = NULL;
159 for(cuser = userList[userListIndex]; cuser; cuser = cuser->next) {
162 last_user->next = user->next;
164 userList[userListIndex] = user->next;
170 struct ChanUser *chanUser, *next;
171 for(chanUser = user->channel; chanUser; chanUser = next) {
172 next = chanUser->next_chan;
173 quitChanUser(chanUser, freeUser);