00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "services.h"
00016
00017 #define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
00018 User *userlist[1024];
00019
00020 #define HASH2(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
00021 Uid *uidlist[1024];
00022
00023 int32 usercnt = 0, opcnt = 0;
00024 uint32 maxusercnt = 0;
00025 time_t maxusertime;
00026
00027
00028
00029
00030
00031
00032
00033
00034 static User *new_user(const char *nick)
00035 {
00036 User *user, **list;
00037
00038 user = scalloc(sizeof(User), 1);
00039 if (!nick)
00040 nick = "";
00041 strscpy(user->nick, nick, NICKMAX);
00042 list = &userlist[HASH(user->nick)];
00043 user->next = *list;
00044 if (*list)
00045 (*list)->prev = user;
00046 *list = user;
00047 user->na = findnick(nick);
00048 if (user->na)
00049 user->na->u = user;
00050 usercnt++;
00051 if (usercnt > maxusercnt) {
00052 maxusercnt = usercnt;
00053 maxusertime = time(NULL);
00054 if (LogMaxUsers)
00055 alog("user: New maximum user count: %d", maxusercnt);
00056 }
00057 user->isSuperAdmin = 0;
00058 user->nickTrack = NULL;
00059 return user;
00060 }
00061
00062
00063
00064
00065
00066 static void change_user_nick(User * user, const char *nick)
00067 {
00068 User **list;
00069 int is_same;
00070
00071
00072 if (!user || !nick || !*nick) {
00073 return;
00074 }
00075
00076 is_same = (!stricmp(user->nick, nick) ? 1 : 0);
00077
00078 if (user->prev)
00079 user->prev->next = user->next;
00080 else
00081 userlist[HASH(user->nick)] = user->next;
00082 if (user->next)
00083 user->next->prev = user->prev;
00084 user->nick[1] = 0;
00085 strscpy(user->nick, nick, NICKMAX);
00086 list = &userlist[HASH(user->nick)];
00087 user->next = *list;
00088 user->prev = NULL;
00089 if (*list)
00090 (*list)->prev = user;
00091 *list = user;
00092
00093
00094 if (!is_same) {
00095 if (user->na)
00096 user->na->u = NULL;
00097 user->na = findnick(nick);
00098 if (user->na)
00099 user->na->u = user;
00100 }
00101 }
00102
00103
00104
00105 void update_host(User * user)
00106 {
00107 if (user->na && (nick_identified(user)
00108 || (!(user->na->nc->flags & NI_SECURE)
00109 && nick_recognized(user)))) {
00110 if (user->na->last_usermask)
00111 free(user->na->last_usermask);
00112
00113 user->na->last_usermask =
00114 smalloc(strlen(common_get_vident(user)) +
00115 strlen(common_get_vhost(user)) + 2);
00116 sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user),
00117 common_get_vhost(user));
00118 }
00119
00120 if (debug)
00121 alog("debug: %s changes its host to %s", user->nick,
00122 common_get_vhost(user));
00123 }
00124
00125
00126
00127
00128
00129
00130 void change_user_host(User * user, const char *host)
00131 {
00132 if (user->vhost)
00133 free(user->vhost);
00134 user->vhost = sstrdup(host);
00135
00136 if (debug)
00137 alog("debug: %s changes its vhost to %s", user->nick, host);
00138
00139
00140
00141 update_host(user);
00142 }
00143
00144
00145
00146
00147
00148 void change_user_realname(User * user, const char *realname)
00149 {
00150 if (user->realname)
00151 free(user->realname);
00152 user->realname = sstrdup(realname);
00153
00154 if (user->na && (nick_identified(user)
00155 || (!(user->na->nc->flags & NI_SECURE)
00156 && nick_recognized(user)))) {
00157 if (user->na->last_realname)
00158 free(user->na->last_realname);
00159 user->na->last_realname = sstrdup(realname);
00160 }
00161
00162 if (debug)
00163 alog("debug: %s changes its realname to %s", user->nick, realname);
00164 }
00165
00166
00167
00168
00169
00170
00171 void change_user_username(User * user, const char *username)
00172 {
00173 if (user->vident)
00174 free(user->vident);
00175 user->vident = sstrdup(username);
00176 if (user->na && (nick_identified(user)
00177 || (!(user->na->nc->flags & NI_SECURE)
00178 && nick_recognized(user)))) {
00179 if (user->na->last_usermask)
00180 free(user->na->last_usermask);
00181
00182 user->na->last_usermask =
00183 smalloc(strlen(common_get_vident(user)) +
00184 strlen(common_get_vhost(user)) + 2);
00185 sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user),
00186 common_get_vhost(user));
00187 }
00188 if (debug)
00189 alog("debug: %s changes its username to %s", user->nick, username);
00190 }
00191
00192
00193
00194
00195
00196 void delete_user(User * user)
00197 {
00198 struct u_chanlist *c, *c2;
00199 struct u_chaninfolist *ci, *ci2;
00200 char *realname;
00201
00202 if (LogUsers) {
00203 realname = normalizeBuffer(user->realname);
00204 if (ircd->vhost) {
00205 alog("LOGUSERS: %s (%s@%s => %s) (%s) left the network (%s).",
00206 user->nick, user->username, user->host,
00207 (user->vhost ? user->vhost : "(none)"),
00208 realname, user->server->name);
00209 } else {
00210 alog("LOGUSERS: %s (%s@%s) (%s) left the network (%s).",
00211 user->nick, user->username, user->host,
00212 realname, user->server->name);
00213 }
00214 free(realname);
00215 }
00216 send_event(EVENT_USER_LOGOFF, 1, user->nick);
00217
00218 if (debug >= 2)
00219 alog("debug: delete_user() called");
00220 usercnt--;
00221 if (is_oper(user))
00222 opcnt--;
00223 if (debug >= 2)
00224 alog("debug: delete_user(): free user data");
00225 free(user->username);
00226 free(user->host);
00227 if (user->vhost)
00228 free(user->vhost);
00229 if (user->vident)
00230 free(user->vident);
00231 if (user->uid) {
00232 free(user->uid);
00233 }
00234 Anope_Free(user->realname);
00235 Anope_Free(user->hostip);
00236 if (debug >= 2) {
00237 alog("debug: delete_user(): remove from channels");
00238 }
00239 c = user->chans;
00240 while (c) {
00241 c2 = c->next;
00242 chan_deluser(user, c->chan);
00243 free(c);
00244 c = c2;
00245 }
00246
00247 cancel_user(user);
00248 if (user->na)
00249 user->na->u = NULL;
00250 if (debug >= 2)
00251 alog("debug: delete_user(): free founder data");
00252 ci = user->founder_chans;
00253 while (ci) {
00254 ci2 = ci->next;
00255 free(ci);
00256 ci = ci2;
00257 }
00258
00259 if (user->nickTrack)
00260 free(user->nickTrack);
00261
00262 moduleCleanStruct(&user->moduleData);
00263
00264 if (debug >= 2)
00265 alog("debug: delete_user(): delete from list");
00266 if (user->prev)
00267 user->prev->next = user->next;
00268 else
00269 userlist[HASH(user->nick)] = user->next;
00270 if (user->next)
00271 user->next->prev = user->prev;
00272 if (debug >= 2)
00273 alog("debug: delete_user(): free user structure");
00274 free(user);
00275 if (debug >= 2)
00276 alog("debug: delete_user() done");
00277 }
00278
00279
00280
00281
00282
00283
00284 void get_user_stats(long *nusers, long *memuse)
00285 {
00286 long count = 0, mem = 0;
00287 int i;
00288 User *user;
00289 struct u_chanlist *uc;
00290 struct u_chaninfolist *uci;
00291
00292 for (i = 0; i < 1024; i++) {
00293 for (user = userlist[i]; user; user = user->next) {
00294 count++;
00295 mem += sizeof(*user);
00296 if (user->username)
00297 mem += strlen(user->username) + 1;
00298 if (user->host)
00299 mem += strlen(user->host) + 1;
00300 if (ircd->vhost) {
00301 if (user->vhost)
00302 mem += strlen(user->vhost) + 1;
00303 }
00304 if (user->realname)
00305 mem += strlen(user->realname) + 1;
00306 if (user->server->name)
00307 mem += strlen(user->server->name) + 1;
00308 for (uc = user->chans; uc; uc = uc->next)
00309 mem += sizeof(*uc);
00310 for (uci = user->founder_chans; uci; uci = uci->next)
00311 mem += sizeof(*uci);
00312 }
00313 }
00314 *nusers = count;
00315 *memuse = mem;
00316 }
00317
00318
00319
00320
00321
00322 User *finduser(const char *nick)
00323 {
00324 User *user;
00325
00326 if (!nick || !*nick) {
00327 if (debug) {
00328 alog("debug: finduser() called with NULL values");
00329 }
00330 return NULL;
00331 }
00332
00333 if (debug >= 3)
00334 alog("debug: finduser(%p)", nick);
00335 user = userlist[HASH(nick)];
00336 while (user && stricmp(user->nick, nick) != 0)
00337 user = user->next;
00338 if (debug >= 3)
00339 alog("debug: finduser(%s) -> 0x%p", nick, (void *) user);
00340 return user;
00341 }
00342
00343
00344
00345
00346
00347
00348 static User *current;
00349 static int next_index;
00350
00351 User *firstuser(void)
00352 {
00353 next_index = 0;
00354 current = NULL;
00355 while (next_index < 1024 && current == NULL)
00356 current = userlist[next_index++];
00357 if (debug)
00358 alog("debug: firstuser() returning %s",
00359 current ? current->nick : "NULL (end of list)");
00360 return current;
00361 }
00362
00363 User *nextuser(void)
00364 {
00365 if (current)
00366 current = current->next;
00367 if (!current && next_index < 1024) {
00368 while (next_index < 1024 && current == NULL)
00369 current = userlist[next_index++];
00370 }
00371 if (debug)
00372 alog("debug: nextuser() returning %s",
00373 current ? current->nick : "NULL (end of list)");
00374 return current;
00375 }
00376
00377 User *find_byuid(const char *uid)
00378 {
00379 User *u, *next;
00380
00381 if (!uid) {
00382 if (debug)
00383 alog("debug: find_byuid() called with NULL-value");
00384 return NULL;
00385 }
00386
00387 u = first_uid();
00388 while (u) {
00389 next = next_uid();
00390 if (u->uid) {
00391 if (!stricmp(uid, u->uid)) {
00392 return u;
00393 }
00394 }
00395 u = next;
00396 }
00397 return NULL;
00398 }
00399
00400 static User *current_uid;
00401 static int next_index_uid;
00402
00403 User *first_uid(void)
00404 {
00405 next_index_uid = 0;
00406 current_uid = NULL;
00407 while (next_index_uid < 1024 && current_uid == NULL) {
00408 current_uid = userlist[next_index_uid++];
00409 }
00410 if (debug >= 2) {
00411 alog("debug: first_uid() returning %s %s",
00412 current_uid ? current_uid->nick : "NULL (end of list)",
00413 current_uid ? current_uid->uid : "");
00414 }
00415 return current_uid;
00416 }
00417
00418 User *next_uid(void)
00419 {
00420 if (current_uid)
00421 current_uid = current_uid->next;
00422 if (!current_uid && next_index_uid < 1024) {
00423 while (next_index_uid < 1024 && current_uid == NULL)
00424 current_uid = userlist[next_index_uid++];
00425 }
00426 if (debug >= 2) {
00427 alog("debug: next_uid() returning %s %s",
00428 current_uid ? current_uid->nick : "NULL (end of list)",
00429 current_uid ? current_uid->uid : "");
00430 }
00431 return current_uid;
00432 }
00433
00434 Uid *new_uid(const char *nick, char *uid)
00435 {
00436 Uid *u, **list;
00437
00438 u = scalloc(sizeof(Uid), 1);
00439 if (!nick || !uid) {
00440 return NULL;
00441 }
00442 strscpy(u->nick, nick, NICKMAX);
00443 list = &uidlist[HASH2(u->nick)];
00444 u->next = *list;
00445 if (*list)
00446 (*list)->prev = u;
00447 *list = u;
00448 u->uid = sstrdup(uid);
00449 return u;
00450 }
00451
00452 Uid *find_uid(const char *nick)
00453 {
00454 Uid *u;
00455 int i;
00456
00457 for (i = 0; i < 1024; i++) {
00458 for (u = uidlist[i]; u; u = u->next) {
00459 if (!stricmp(nick, u->nick)) {
00460 return u;
00461 }
00462 }
00463 }
00464 return NULL;
00465 }
00466
00467 Uid *find_nickuid(const char *uid)
00468 {
00469 Uid *u;
00470 int i;
00471
00472 for (i = 0; i < 1024; i++) {
00473 for (u = uidlist[i]; u; u = u->next) {
00474 if (!stricmp(uid, u->uid)) {
00475 return u;
00476 }
00477 }
00478 }
00479 return NULL;
00480 }
00481
00482
00483
00484
00485
00486
00487 User *do_nick(const char *source, char *nick, char *username, char *host,
00488 char *server, char *realname, time_t ts, uint32 svid,
00489 uint32 ip, char *vhost, char *uid)
00490 {
00491 User *user = NULL;
00492
00493 char *tmp = NULL;
00494 NickAlias *old_na;
00495 int nc_changed = 1;
00496 int status = 0;
00497 char mask[USERMAX + HOSTMAX + 2];
00498 char *logrealname;
00499
00500 if (!*source) {
00501 char ipbuf[16];
00502 struct in_addr addr;
00503
00504 if (ircd->nickvhost) {
00505 if (vhost) {
00506 if (!strcmp(vhost, "*")) {
00507 vhost = NULL;
00508 if (debug)
00509 alog("debug: new user with no vhost in NICK command: %s", nick);
00510 }
00511 }
00512 }
00513
00514
00515 if (debug)
00516 alog("debug: new user: %s", nick);
00517
00518 if (ircd->nickip) {
00519 addr.s_addr = htonl(ip);
00520 ntoa(addr, ipbuf, sizeof(ipbuf));
00521 }
00522
00523
00524 if (LogUsers) {
00528 if (realname) {
00529 tmp = strchr(realname, '%');
00530 while (tmp) {
00531 *tmp = '-';
00532 tmp = strchr(realname, '%');
00533 }
00534 }
00535 logrealname = normalizeBuffer(realname);
00536
00541 if (ircd->nickvhost) {
00542 if (ircd->nickip) {
00543 alog("LOGUSERS: %s (%s@%s => %s) (%s) [%s] connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, ipbuf, server);
00544 } else {
00545 alog("LOGUSERS: %s (%s@%s => %s) (%s) connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, server);
00546 }
00547 } else {
00548 if (ircd->nickip) {
00549 alog("LOGUSERS: %s (%s@%s) (%s) [%s] connected to the network (%s).", nick, username, host, logrealname, ipbuf, server);
00550 } else {
00551 alog("LOGUSERS: %s (%s@%s) (%s) connected to the network (%s).", nick, username, host, logrealname, server);
00552 }
00553 }
00554 Anope_Free(logrealname);
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 if (check_akill(nick, username, host, vhost, ipbuf)) {
00571
00572 }
00573
00578
00579 if (is_sync(findserver(servlist, server))
00580 && checkDefCon(DEFCON_AKILL_NEW_CLIENTS)) {
00581 strncpy(mask, "*@", 3);
00582 strncat(mask, host, HOSTMAX);
00583 alog("DEFCON: adding akill for %s", mask);
00584 add_akill(NULL, mask, s_OperServ,
00585 time(NULL) + dotime(DefConAKILL),
00586 DefConAkillReason ? DefConAkillReason :
00587 "DEFCON AKILL");
00588 if (check_akill(nick, username, host, vhost, ipbuf)) {
00589
00590 }
00591 }
00592
00593
00594 if (ircd->sgline) {
00595 if (check_sgline(nick, realname))
00596 return NULL;
00597 }
00598
00599
00600 if (ircd->sqline) {
00601 if (check_sqline(nick, 0))
00602 return NULL;
00603 }
00604
00605
00606 if (ircd->szline && ircd->nickip) {
00607 if (check_szline(nick, ipbuf))
00608 return NULL;
00609 }
00610
00611 if (LimitSessions && !add_session(nick, host, ipbuf))
00612 return NULL;
00613
00614
00615 user = new_user(nick);
00616 user->username = sstrdup(username);
00617 user->host = sstrdup(host);
00618 user->server = findserver(servlist, server);
00619 user->realname = sstrdup(realname);
00620 user->timestamp = ts;
00621 user->my_signon = time(NULL);
00622 user->vhost = vhost ? sstrdup(vhost) : sstrdup(host);
00623 if (uid) {
00624 user->uid = sstrdup(uid);
00625 } else {
00626 user->uid = NULL;
00627 }
00628 user->vident = sstrdup(username);
00629
00630
00631 if (ircd->nickip) {
00632 user->hostip = sstrdup(ipbuf);
00633 } else {
00634 user->hostip = NULL;
00635 }
00636
00637 if (svid == 0) {
00638 display_news(user, NEWS_LOGON);
00639 display_news(user, NEWS_RANDOM);
00640 }
00641
00642 if (svid == ts && user->na) {
00643
00644 user->svid = svid;
00645 user->na->status |= NS_IDENTIFIED;
00646 check_memos(user);
00647 nc_changed = 0;
00648
00649
00650 if (NSNickTracking)
00651 nsStartNickTracking(user);
00652
00653 } else if (svid != 1) {
00654
00655 user->svid = 1;
00656
00657 anope_cmd_svid_umode(user->nick, user->timestamp);
00658
00659 } else {
00660 user->svid = 1;
00661 }
00662 send_event(EVENT_NEWNICK, 1, nick);
00663
00664 } else {
00665
00666 if (UseTS6)
00667 user = find_byuid(source);
00668
00669 if (!user)
00670 user = finduser(source);
00671
00672 if (!user) {
00673 alog("user: NICK from nonexistent nick %s", source);
00674 return NULL;
00675 }
00676 user->isSuperAdmin = 0;
00677 if (debug)
00678 alog("debug: %s changes nick to %s", source, nick);
00679
00680 if (LogUsers) {
00681 logrealname = normalizeBuffer(user->realname);
00682 if (ircd->vhost) {
00683 alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, (user->vhost ? user->vhost : "(none)"), logrealname, nick, user->server->name);
00684 } else {
00685 alog("LOGUSERS: %s (%s@%s) (%s) changed nick to %s (%s).",
00686 user->nick, user->username, user->host, logrealname,
00687 nick, user->server->name);
00688 }
00689 if (logrealname) {
00690 free(logrealname);
00691 }
00692 }
00693
00694 user->timestamp = ts;
00695
00696 if (stricmp(nick, user->nick) == 0) {
00697
00698 change_user_nick(user, nick);
00699 nc_changed = 0;
00700 } else {
00701
00702 user->my_signon = time(NULL);
00703
00704 old_na = user->na;
00705 if (old_na) {
00706 if (nick_recognized(user))
00707 user->na->last_seen = time(NULL);
00708 status = old_na->status & NS_TRANSGROUP;
00709 cancel_user(user);
00710 }
00711
00712 change_user_nick(user, nick);
00713 send_event(EVENT_CHANGE_NICK, 1, nick);
00714
00715 if ((old_na ? old_na->nc : NULL) ==
00716 (user->na ? user->na->nc : NULL))
00717 nc_changed = 0;
00718
00719 if (!nc_changed && (user->na))
00720 user->na->status |= status;
00721 else {
00722 anope_cmd_nc_change(user);
00723 }
00724 }
00725
00726 if (ircd->sqline) {
00727 if (!is_oper(user) && check_sqline(user->nick, 1))
00728 return NULL;
00729 }
00730
00731 }
00732
00733
00734 if (NSNickTracking && nsCheckNickTracking(user)) {
00735 user->na->status |= NS_IDENTIFIED;
00736 nc_changed = 0;
00737 }
00738
00739 if (nc_changed || !nick_recognized(user)) {
00740 if (validate_user(user))
00741 check_memos(user);
00742
00743 } else {
00744 if (nick_identified(user)) {
00745 char tsbuf[16];
00746 user->na->last_seen = time(NULL);
00747
00748 if (user->na->last_usermask)
00749 free(user->na->last_usermask);
00750 user->na->last_usermask =
00751 smalloc(strlen(common_get_vident(user)) +
00752 strlen(common_get_vhost(user)) + 2);
00753 sprintf(user->na->last_usermask, "%s@%s",
00754 common_get_vident(user), common_get_vhost(user));
00755
00756 snprintf(tsbuf, sizeof(tsbuf), "%lu",
00757 (unsigned long int) user->timestamp);
00758 anope_cmd_svid_umode2(user, tsbuf);
00759
00760 alog("%s: %s!%s@%s automatically identified for nick %s",
00761 s_NickServ, user->nick, user->username,
00762 user->host, user->nick);
00763 }
00764 }
00765
00766
00767 if (ircd->check_nick_id) {
00768 if (nick_identified(user)) {
00769 char tsbuf[16];
00770 snprintf(tsbuf, sizeof(tsbuf), "%lu",
00771 (unsigned long int) user->timestamp);
00772 anope_cmd_svid_umode3(user, tsbuf);
00773 }
00774 }
00775
00776 return user;
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786 void do_umode(const char *source, int ac, char **av)
00787 {
00788 User *user;
00789
00790 user = finduser(av[0]);
00791 if (!user) {
00792 alog("user: MODE %s for nonexistent nick %s: %s", av[1], av[0],
00793 merge_args(ac, av));
00794 return;
00795 }
00796
00797 anope_set_umode(user, ac - 1, &av[1]);
00798 }
00799
00800
00801
00802
00803
00804 void do_umode2(const char *source, int ac, char **av)
00805 {
00806 User *user;
00807
00808 user = finduser(source);
00809 if (!user) {
00810 alog("user: MODE %s for nonexistent nick %s: %s", av[0], source,
00811 merge_args(ac, av));
00812 return;
00813 }
00814
00815 anope_set_umode(user, ac, &av[0]);
00816 }
00817
00818
00819
00820
00821
00822
00823
00824 void do_quit(const char *source, int ac, char **av)
00825 {
00826 User *user;
00827 NickAlias *na;
00828
00829 user = finduser(source);
00830 if (!user) {
00831 alog("user: QUIT from nonexistent user %s: %s", source,
00832 merge_args(ac, av));
00833 return;
00834 }
00835 if (debug) {
00836 alog("debug: %s quits", source);
00837 }
00838 if ((na = user->na) && (!(na->status & NS_VERBOTEN))
00839 && (!(na->nc->flags & NI_SUSPENDED))
00840 && (na->status & (NS_IDENTIFIED | NS_RECOGNIZED))) {
00841 na->last_seen = time(NULL);
00842 if (na->last_quit)
00843 free(na->last_quit);
00844 na->last_quit = *av[0] ? sstrdup(av[0]) : NULL;
00845 }
00846 if (LimitSessions) {
00847 del_session(user->host);
00848 }
00849 delete_user(user);
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859 void do_kill(char *nick, char *msg)
00860 {
00861 User *user;
00862 NickAlias *na;
00863
00864 user = finduser(nick);
00865 if (!user) {
00866 if (debug) {
00867 alog("debug: KILL of nonexistent nick: %s", nick);
00868 }
00869 return;
00870 }
00871 if (debug) {
00872 alog("debug: %s killed", nick);
00873 }
00874 if ((na = user->na) && (!(na->status & NS_VERBOTEN))
00875 && (!(na->nc->flags & NI_SUSPENDED))
00876 && (na->status & (NS_IDENTIFIED | NS_RECOGNIZED))) {
00877 na->last_seen = time(NULL);
00878 if (na->last_quit)
00879 free(na->last_quit);
00880 na->last_quit = *msg ? sstrdup(msg) : NULL;
00881
00882 }
00883 if (LimitSessions) {
00884 del_session(user->host);
00885 }
00886 delete_user(user);
00887 }
00888
00889
00890
00891
00892
00893
00894 int is_protected(User * user)
00895 {
00896 if (ircd->protectedumode) {
00897 return (user->mode & ircd->protectedumode);
00898 } else {
00899 return 0;
00900 }
00901 }
00902
00903
00904
00905
00906
00907 int is_oper(User * user)
00908 {
00909 if (user) {
00910 return (user->mode & anope_get_oper_mode());
00911 } else {
00912 return 0;
00913 }
00914 }
00915
00916
00917
00918
00919
00920 int is_excepted(ChannelInfo * ci, User * user)
00921 {
00922 int count, i;
00923 int isexcepted = 0;
00924 char **excepts;
00925
00926 if (!ci->c)
00927 return 0;
00928
00929 if (!ircd->except) {
00930 return 0;
00931 }
00932
00933 count = ci->c->exceptcount;
00934 excepts = scalloc(sizeof(char *) * count, 1);
00935 memcpy(excepts, ci->c->excepts, sizeof(char *) * count);
00936
00937 for (i = 0; i < count; i++) {
00938 if (match_usermask(excepts[i], user)
00939 || match_userip(excepts[i], user, user->hostip)) {
00940 isexcepted = 1;
00941 break;
00942 }
00943 }
00944 free(excepts);
00945 return isexcepted;
00946 }
00947
00948
00949
00950
00951 int is_excepted_mask(ChannelInfo * ci, char *mask)
00952 {
00953 int count, i;
00954 int isexcepted = 0;
00955 char **excepts;
00956
00957 if (!ci->c)
00958 return 0;
00959
00960 if (!ircd->except) {
00961 return 0;
00962 }
00963
00964 count = ci->c->exceptcount;
00965 excepts = scalloc(sizeof(char *) * count, 1);
00966 memcpy(excepts, ci->c->excepts, sizeof(char *) * count);
00967
00968 for (i = 0; i < count; i++) {
00969 if (match_wild_nocase(excepts[i], mask)) {
00970 isexcepted = 1;
00971 }
00972 }
00973 free(excepts);
00974 return isexcepted;
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984 int match_usermask(const char *mask, User * user)
00985 {
00986 char *mask2;
00987 char *nick, *username, *host;
00988 int result;
00989
00990 if (!mask || !*mask) {
00991 return 0;
00992 }
00993
00994 mask2 = sstrdup(mask);
00995
00996 if (strchr(mask2, '!')) {
00997 nick = strtok(mask2, "!");
00998 username = strtok(NULL, "@");
00999 } else {
01000 nick = NULL;
01001 username = strtok(mask2, "@");
01002 }
01003 host = strtok(NULL, "");
01004 if (!username || !host) {
01005 free(mask2);
01006 return 0;
01007 }
01008
01009 if (nick) {
01010 result = match_wild_nocase(nick, user->nick)
01011 && match_wild_nocase(username, user->username)
01012 && (match_wild_nocase(host, user->host)
01013 || match_wild_nocase(host, user->vhost));
01014 } else {
01015 result = match_wild_nocase(username, user->username)
01016 && (match_wild_nocase(host, user->host)
01017 || match_wild_nocase(host, user->vhost));
01018 }
01019
01020 free(mask2);
01021 return result;
01022 }
01023
01024
01025
01026
01027
01028
01029 int match_userip(const char *mask, User * user, char *iphost)
01030 {
01031 char *mask2;
01032 char *nick, *username, *host;
01033 int result;
01034
01035 if (!mask || !*mask) {
01036 return 0;
01037 }
01038
01039 mask2 = sstrdup(mask);
01040
01041 if (strchr(mask2, '!')) {
01042 nick = strtok(mask2, "!");
01043 username = strtok(NULL, "@");
01044 } else {
01045 nick = NULL;
01046 username = strtok(mask2, "@");
01047 }
01048 host = strtok(NULL, "");
01049 if (!username || !host) {
01050 free(mask2);
01051 return 0;
01052 }
01053
01054 if (nick) {
01055 result = match_wild_nocase(nick, user->nick)
01056 && match_wild_nocase(username, user->username)
01057 && (match_wild_nocase(host, iphost)
01058 || match_wild_nocase(host, user->vhost));
01059 } else {
01060 result = match_wild_nocase(username, user->username)
01061 && (match_wild_nocase(host, iphost)
01062 || match_wild_nocase(host, user->vhost));
01063 }
01064
01065 free(mask2);
01066 return result;
01067 }
01068
01069
01070
01071