6 static struct UserNode **userList;
9 userList = calloc(VALID_NICK_CHARS_FIRST_LEN+1, sizeof(*userList));
12 void free_UserNode() {
13 //kamikaze free all users
14 //chanusers will be destroyed in free_ChanNode()
16 struct UserNode *user, *next;
17 for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN+1; i++) {
18 for(user = userList[i]; user; user = next) {
26 int is_valid_nick(const char *nick) {
28 //first char must be one of: a-zA-Z{|}~[\]^_`
29 if (!strchr(VALID_NICK_CHARS_FIRST, *nick))
31 //all other chars must be one of: a-zA-Z0-9{|}~[\]^_`
32 for (i = 0; nick[i]; ++i)
33 if (!strchr(VALID_NICK_CHARS, nick[i]))
35 if (strlen(nick) > NICKLEN)
40 static int get_nicklist_entry(int nick) {
42 char *valid_chars = VALID_NICK_CHARS_FIRST;
43 for(i = 0; i < VALID_NICK_CHARS_FIRST_LEN; i++) {
44 if(valid_chars[i] == nick)
50 struct UserNode* getUserByNick(const char *nick) { //case sensitive
51 int userListIndex = get_nicklist_entry(*nick);
52 if(userListIndex == -1 || userList[userListIndex] == NULL)
54 struct UserNode *user;
55 for(user = userList[userListIndex]; user; user = user->next) {
56 if(!stricmp(nick, user->nick))
62 struct UserNode* getUserByMask(const char *mask) { //case sensitive
63 char cmask[strlen(mask)+1];
66 struct UserNode *user = NULL;
67 for(i = 0; i < strlen(mask); i++) {
70 user = getUserByNick(&cmask[0]);
72 } else if(cmask[i] == '.') {
80 struct UserNode* searchUserByNick(const char *nick) { //case insensitive
82 return getUserByNick(nick);
85 struct UserNode *user;
87 //search in the lower case "section"
88 userListIndex = get_nicklist_entry(tolower(*nick));
89 if(userListIndex != -1 && userList[userListIndex] != NULL) {
90 for(user = userList[userListIndex]; user; user = user->next) {
91 if(!stricmp(nick, user->nick))
95 //search in the upper case "section"
96 userListIndex = get_nicklist_entry(toupper(*nick));
97 if(userListIndex != -1 && userList[userListIndex] != NULL) {
98 for(user = userList[userListIndex]; user; user = user->next) {
99 if(!stricmp(nick, user->nick))
106 struct UserNode* addUser(const char *nick) {
107 int userListIndex = get_nicklist_entry(*nick);
108 if(userListIndex == -1 || !is_valid_nick(nick))
110 struct UserNode *user = malloc(sizeof(*user));
113 perror("malloc() failed");
116 strcpy(user->nick, nick);
117 user->created = time(0);
120 user->realname[0] = 0;
122 user->channel = NULL;
123 user->next = userList[userListIndex];
124 userList[userListIndex] = user;
128 struct UserNode* addUserMask(const char *mask) {
129 char cmask[strlen(mask)+1];
132 struct UserNode *user = NULL;
133 for(i = 0; i < strlen(mask)+1; i++) {
134 if(cmask[i] == '!') {
136 user = addUser(cmask);
137 if(user == NULL) return NULL;
139 } else if(cmask[i] == '.' && !user) {
142 } else if(cmask[i] == '@') {
143 if(user == NULL) return NULL;
145 strcpy(user->ident, &cmask[ii]);
147 } else if(cmask[i] == '\0') {
148 if(user == NULL) return NULL;
149 strcpy(user->host, &cmask[ii]);
155 struct UserNode* createTempUser(const char *mask) {
156 //note: it could also be a server we have to create a temponary user for...
157 char cmask[strlen(mask)+1];
160 struct UserNode *user = NULL;
161 for(i = 0; i < strlen(mask)+1; i++) {
162 if(cmask[i] == '!') {
164 user = malloc(sizeof(*user));
167 perror("malloc() failed");
170 strcpy(user->nick, cmask);
171 user->created = time(0);
174 user->realname[0] = 0;
176 user->channel = NULL;
178 } else if(cmask[i] == '.' && !user) {
180 user = malloc(sizeof(*user));
183 perror("malloc() failed");
186 strcpy(user->host, cmask);
187 user->created = time(0);
190 user->realname[0] = 0;
191 user->flags = USERFLAG_ISSERVER;
192 user->channel = NULL;
194 } else if(cmask[i] == '@') {
195 if(user == NULL) return NULL;
197 strcpy(user->ident, &cmask[ii]);
199 } else if(cmask[i] == '\0') {
202 user = malloc(sizeof(*user));
205 perror("malloc() failed");
208 strcpy(user->nick, cmask);
209 user->created = time(0);
212 user->realname[0] = 0;
214 user->channel = NULL;
217 strcpy(user->host, &cmask[ii]);
223 int renameUser(struct UserNode* user, const char *new_nick) {
224 if(!is_valid_nick(new_nick))
226 if(user->nick[0] == *new_nick) {
227 strcpy(user->nick, new_nick);
230 int userListIndex = get_nicklist_entry(*new_nick);
232 strcpy(user->nick, new_nick);
233 user->next = userList[userListIndex];
234 userList[userListIndex] = user;
238 void delUser(struct UserNode* user, int freeUser) {
239 int userListIndex = get_nicklist_entry(user->nick[0]);
240 if(userListIndex == -1) return;
241 struct UserNode *cuser, *last_user = NULL;
242 for(cuser = userList[userListIndex]; cuser; cuser = cuser->next) {
245 last_user->next = user->next;
247 userList[userListIndex] = user->next;
253 struct ChanUser *chanUser, *next;
254 for(chanUser = user->channel; chanUser; chanUser = next) {
255 next = chanUser->next_chan;
256 removeChanUserFromLists(chanUser, 1, 0, freeUser);
265 void clearTempUsers() {
266 int userListIndex = TEMPUSER_LIST_INDEX;
267 struct UserNode *cuser, *last_user = NULL, *next;
268 time_t now = time(0);
269 for(cuser = userList[userListIndex]; cuser; cuser = next) {
271 if(cuser->flags & USERFLAG_FREETMPUSER || now - cuser->created >= 300) {
273 last_user->next = cuser->next;
275 userList[userListIndex] = cuser->next;
283 void load_user_settings(struct UserNode *user) {
284 if(!(user->flags & USERFLAG_ISAUTHED) || (user->flags & USERFLAG_LOADED_SETTINGS))
289 printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
291 if ((row = mysql_fetch_row(res)) != NULL) {
292 user->language = get_language_by_tag(row[0]);
293 if(user->language == NULL) user->language = get_default_language();
294 if(strcmp(row[1], "0"))
295 user->flags |= USERFLAG_REPLY_PRIVMSG;
296 if(strcmp(row[2], "0"))
297 user->flags |= USERFLAG_GOD_MODE;
299 user->language = get_default_language();
300 user->flags |= USERFLAG_LOADED_SETTINGS;
303 int isGodMode(struct UserNode *user) {
304 load_user_settings(user);
305 return (user->flags & USERFLAG_GOD_MODE);