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