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') {
200 if(user == NULL) return NULL;
201 strcpy(user->host, &cmask[ii]);
207 int renameUser(struct UserNode* user, const char *new_nick) {
208 if(!is_valid_nick(new_nick))
210 if(user->nick[0] == *new_nick) {
211 strcpy(user->nick, new_nick);
214 int userListIndex = get_nicklist_entry(*new_nick);
216 strcpy(user->nick, new_nick);
217 user->next = userList[userListIndex];
218 userList[userListIndex] = user;
222 void delUser(struct UserNode* user, int freeUser) {
223 int userListIndex = get_nicklist_entry(user->nick[0]);
224 if(userListIndex == -1) return;
225 struct UserNode *cuser, *last_user = NULL;
226 for(cuser = userList[userListIndex]; cuser; cuser = cuser->next) {
229 last_user->next = user->next;
231 userList[userListIndex] = user->next;
237 struct ChanUser *chanUser, *next;
238 for(chanUser = user->channel; chanUser; chanUser = next) {
239 next = chanUser->next_chan;
240 removeChanUserFromLists(chanUser, 1, 0, freeUser);
249 void clearTempUsers() {
250 int userListIndex = TEMPUSER_LIST_INDEX;
251 struct UserNode *cuser, *last_user = NULL, *next;
252 time_t now = time(0);
253 for(cuser = userList[userListIndex]; cuser; cuser = next) {
255 if(cuser->flags & USERFLAG_FREETMPUSER || now - cuser->created >= 300) {
257 last_user->next = cuser->next;
259 userList[userListIndex] = cuser->next;
267 void load_user_settings(struct UserNode *user) {
268 if(!(user->flags & USERFLAG_ISAUTHED) || (user->flags & USERFLAG_LOADED_SETTINGS))
273 printf_mysql_query("SELECT `user_lang`, `user_reply_privmsg`, `user_god` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
275 if ((row = mysql_fetch_row(res)) != NULL) {
276 user->language = get_language_by_tag(row[0]);
277 if(user->language == NULL) user->language = get_default_language();
278 if(strcmp(row[1], "0"))
279 user->flags |= USERFLAG_REPLY_PRIVMSG;
280 if(strcmp(row[2], "0"))
281 user->flags |= USERFLAG_GOD_MODE;
283 user->language = get_default_language();
284 user->flags |= USERFLAG_LOADED_SETTINGS;
287 int isGodMode(struct UserNode *user) {
288 load_user_settings();
289 return (user->flags & USERFLAG_GOD_MODE);