00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "services.h"
00016 #include "pseudo.h"
00017
00018
00019
00020 #define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
00021
00022 NickAlias *nalists[1024];
00023 NickCore *nclists[1024];
00024 NickRequest *nrlists[1024];
00025
00026 unsigned int guestnum;
00027
00028 #define TO_COLLIDE 0
00029 #define TO_RELEASE 1
00030
00031
00032
00033 static void add_ns_timeout(NickAlias * na, int type, time_t delay);
00034
00035
00036
00037 void moduleAddNickServCmds(void) {
00038 modules_core_init(NickServCoreNumber, NickServCoreModules);
00039 }
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 void listnicks(int count_only, const char *nick)
00050 {
00051 int count = 0;
00052 NickAlias *na;
00053 int i;
00054 char *end;
00055
00056 if (count_only) {
00057
00058 for (i = 0; i < 1024; i++) {
00059 for (na = nalists[i]; na; na = na->next)
00060 count++;
00061 }
00062 printf("%d nicknames registered.\n", count);
00063
00064 } else if (nick) {
00065
00066 struct tm *tm;
00067 char buf[512];
00068 static const char commastr[] = ", ";
00069 int need_comma = 0;
00070
00071 if (!(na = findnick(nick))) {
00072 printf("%s not registered.\n", nick);
00073 return;
00074 } else if (na->status & NS_VERBOTEN) {
00075 printf("%s is FORBIDden.\n", nick);
00076 return;
00077 }
00078 printf("%s is %s\n", nick, na->last_realname);
00079 printf("Last seen address: %s\n", na->last_usermask);
00080 tm = localtime(&na->time_registered);
00081 strftime(buf, sizeof(buf),
00082 getstring(NULL, STRFTIME_DATE_TIME_FORMAT), tm);
00083 printf(" Time registered: %s\n", buf);
00084 tm = localtime(&na->last_seen);
00085 strftime(buf, sizeof(buf),
00086 getstring(NULL, STRFTIME_DATE_TIME_FORMAT), tm);
00087 printf(" Last seen time: %s\n", buf);
00088 if (na->nc->url)
00089 printf(" URL: %s\n", na->nc->url);
00090 if (na->nc->email)
00091 printf(" E-mail address: %s\n", na->nc->email);
00092 if (na->nc->icq)
00093 printf(" ICQ #: %d\n", na->nc->icq);
00094 if (na->nc->greet)
00095 printf(" Greet: %s\n", na->nc->greet);
00096 *buf = 0;
00097 end = buf;
00098 if (na->nc->flags & NI_KILLPROTECT) {
00099 end +=
00100 snprintf(end, sizeof(buf) - (end - buf),
00101 "Kill protection");
00102 need_comma = 1;
00103 }
00104 if (na->nc->flags & NI_SECURE) {
00105 end += snprintf(end, sizeof(buf) - (end - buf), "%sSecurity",
00106 need_comma ? commastr : "");
00107 need_comma = 1;
00108 }
00109 if (na->nc->flags & NI_PRIVATE) {
00110 end += snprintf(end, sizeof(buf) - (end - buf), "%sPrivate",
00111 need_comma ? commastr : "");
00112 need_comma = 1;
00113 }
00114 if (na->status & NS_NO_EXPIRE) {
00115 end += snprintf(end, sizeof(buf) - (end - buf), "%sNo Expire",
00116 need_comma ? commastr : "");
00117 need_comma = 1;
00118 }
00119 printf(" Options: %s\n", *buf ? buf : "None");
00120
00121 if (na->nc->flags & NI_SUSPENDED) {
00122 if (na->last_quit) {
00123 printf
00124 ("This nickname is currently suspended, reason: %s\n",
00125 na->last_quit);
00126 } else {
00127 printf("This nickname is currently suspended.\n");
00128 }
00129 }
00130
00131
00132 } else {
00133
00134 for (i = 0; i < 1024; i++) {
00135 for (na = nalists[i]; na; na = na->next) {
00136 printf(" %s %-20s %s\n",
00137 na->status & NS_NO_EXPIRE ? "!" : " ",
00138 na->nick, na->status & NS_VERBOTEN ?
00139 "Disallowed (FORBID)" : (na->nc->
00140 flags & NI_SUSPENDED ?
00141 "Disallowed (SUSPENDED)" :
00142 na->last_usermask));
00143 count++;
00144 }
00145 }
00146 printf("%d nicknames registered.\n", count);
00147
00148 }
00149 }
00150
00151
00152
00153
00154
00155 void get_aliases_stats(long *nrec, long *memuse)
00156 {
00157 long count = 0, mem = 0;
00158 int i;
00159 NickAlias *na;
00160
00161 for (i = 0; i < 1024; i++) {
00162 for (na = nalists[i]; na; na = na->next) {
00163 count++;
00164 mem += sizeof(*na);
00165 if (na->nick)
00166 mem += strlen(na->nick) + 1;
00167 if (na->last_usermask)
00168 mem += strlen(na->last_usermask) + 1;
00169 if (na->last_realname)
00170 mem += strlen(na->last_realname) + 1;
00171 if (na->last_quit)
00172 mem += strlen(na->last_quit) + 1;
00173 }
00174 }
00175 *nrec = count;
00176 *memuse = mem;
00177 }
00178
00179
00180
00181
00182
00183 void get_core_stats(long *nrec, long *memuse)
00184 {
00185 long count = 0, mem = 0;
00186 int i, j;
00187 NickCore *nc;
00188 char **accptr;
00189
00190 for (i = 0; i < 1024; i++) {
00191 for (nc = nclists[i]; nc; nc = nc->next) {
00192 count++;
00193 mem += sizeof(*nc);
00194
00195 if (nc->display)
00196 mem += strlen(nc->display) + 1;
00197 if (nc->pass)
00198 mem += strlen(nc->pass) + 1;
00199
00200 if (nc->url)
00201 mem += strlen(nc->url) + 1;
00202 if (nc->email)
00203 mem += strlen(nc->email) + 1;
00204 if (nc->greet)
00205 mem += strlen(nc->greet) + 1;
00206
00207 mem += sizeof(char *) * nc->accesscount;
00208 for (accptr = nc->access, j = 0; j < nc->accesscount;
00209 accptr++, j++) {
00210 if (*accptr)
00211 mem += strlen(*accptr) + 1;
00212 }
00213
00214 mem += nc->memos.memocount * sizeof(Memo);
00215 for (j = 0; j < nc->memos.memocount; j++) {
00216 if (nc->memos.memos[j].text)
00217 mem += strlen(nc->memos.memos[j].text) + 1;
00218 }
00219
00220 mem += sizeof(void *) * nc->aliases.count;
00221 }
00222 }
00223 *nrec = count;
00224 *memuse = mem;
00225 }
00226
00227
00228
00229
00230
00231
00232 void ns_init(void)
00233 {
00234 moduleAddNickServCmds();
00235 guestnum = time(NULL);
00236 while (guestnum > 9999999)
00237 guestnum -= 10000000;
00238 }
00239
00240
00241
00242
00243
00244 void nickserv(User * u, char *buf)
00245 {
00246 char *cmd, *s;
00247
00248 cmd = strtok(buf, " ");
00249
00250 if (!cmd) {
00251 return;
00252 } else if (stricmp(cmd, "\1PING") == 0) {
00253 if (!(s = strtok(NULL, ""))) {
00254 s = "";
00255 }
00256 anope_cmd_ctcp(s_NickServ, u->nick, "PING %s", s);
00257 } else if (skeleton) {
00258 notice_lang(s_NickServ, u, SERVICE_OFFLINE, s_NickServ);
00259 } else {
00260 mod_run_cmd(s_NickServ, u, NICKSERV, cmd);
00261 }
00262
00263 }
00264
00265
00266
00267
00268
00269
00270 #define SAFE(x) do { \
00271 if ((x) < 0) { \
00272 if (!forceload) \
00273 fatal("Read error on %s", NickDBName); \
00274 failed = 1; \
00275 break; \
00276 } \
00277 } while (0)
00278
00279
00280
00281 void load_old_ns_dbase(void)
00282 {
00283 dbFILE *f;
00284 int ver, i, j, c;
00285 NickAlias *na, *na2, *next;
00286 NickCore *nc;
00287 int failed = 0;
00288
00289 uint16 tmp16;
00290 uint32 tmp32;
00291
00292 char bufn[NICKMAX], bufp[PASSMAX];
00293 char *email, *greet, *url, *forbidby, *forbidreason;
00294 uint32 icq;
00295
00296 if (!(f = open_db(s_NickServ, NickDBName, "r", NICK_VERSION)))
00297 return;
00298
00299 ver = get_file_version(f);
00300 if (ver <= 4) {
00301 fatal("Unsupported version number (%d) on %s", ver, NickDBName);
00302 close_db(f);
00303 return;
00304 }
00305
00306 for (i = 0; i < 256 && !failed; i++) {
00307 while ((c = getc_db(f)) == 1) {
00308 if (c != 1)
00309 fatal("Invalid format in %s", NickDBName);
00310
00311 na = scalloc(sizeof(NickAlias), 1);
00312
00313 SAFE(read_buffer(bufn, f));
00314 na->nick = sstrdup(bufn);
00315 SAFE(read_buffer(bufp, f));
00316
00317 SAFE(read_string(&url, f));
00318 SAFE(read_string(&email, f));
00319 if (ver >= 10)
00320 SAFE(read_int32(&icq, f));
00321 else
00322 icq = 0;
00323 if (ver >= 9)
00324 SAFE(read_string(&greet, f));
00325 else
00326 greet = NULL;
00327
00328 SAFE(read_string(&na->last_usermask, f));
00329 SAFE(read_string(&na->last_realname, f));
00330 SAFE(read_string(&na->last_quit, f));
00331
00332 SAFE(read_int32(&tmp32, f));
00333 na->time_registered = tmp32;
00334 SAFE(read_int32(&tmp32, f));
00335 na->last_seen = tmp32;
00336
00337 SAFE(read_int16(&na->status, f));
00338 na->status &= ~NS_TEMPORARY;
00339
00340 if (ver >= 9) {
00341 SAFE(read_string(&forbidby, f));
00342 SAFE(read_string(&forbidreason, f));
00343
00344 if (forbidby && *forbidby == '@') {
00345 free(forbidby);
00346 forbidby = NULL;
00347 }
00348 if (forbidreason && *forbidreason == 0) {
00349 free(forbidreason);
00350 forbidreason = NULL;
00351 }
00352 } else {
00353 forbidby = NULL;
00354 forbidreason = NULL;
00355 }
00356
00357 if (na->status & NS_VERBOTEN) {
00358 if (na->last_usermask)
00359 free(na->last_usermask);
00360 if (na->last_realname)
00361 free(na->last_realname);
00362
00363 na->last_usermask = forbidby;
00364 na->last_realname = forbidreason;
00365 } else {
00366 if (!na->last_usermask)
00367 na->last_usermask = sstrdup("");
00368 if (!na->last_realname)
00369 na->last_realname = sstrdup("");
00370 }
00371
00372
00373 SAFE(read_string((char **) &na->nc, f));
00374 SAFE(read_int16(&tmp16, f));
00375
00376 if (na->nc) {
00377 SAFE(read_int16(&tmp16, f));
00378 } else {
00379
00380
00381
00382 nc = scalloc(1, sizeof(NickCore));
00383 slist_init(&nc->aliases);
00384
00385
00386 nc->display = sstrdup(na->nick);
00387
00388
00389 if (*bufp)
00390 memcpy(nc->pass, bufp, PASSMAX);
00391 else
00392 memset(nc->pass, 0, PASSMAX);
00393
00394 nc->email = email;
00395 nc->greet = greet;
00396 nc->icq = icq;
00397 nc->url = url;
00398
00399
00400
00401
00402 if (ver <= 10 && nc->email && !MailValidate(nc->email)) {
00403 free(nc->email);
00404 nc->email = NULL;
00405 }
00406
00407 SAFE(read_int32(&nc->flags, f));
00408 if (!NSAllowKillImmed)
00409 nc->flags &= ~NI_KILL_IMMED;
00410
00411
00412 if (na->status & NS_OLD_ENCRYPTEDPW) {
00413 nc->flags |= NI_ENCRYPTEDPW;
00414 na->status &= ~NS_OLD_ENCRYPTEDPW;
00415 }
00416
00417
00418
00419 if (ver >= 10) {
00420 if (nc->flags & NI_SERVICES_ADMIN)
00421 slist_add(&servadmins, nc);
00422 if (nc->flags & NI_SERVICES_OPER)
00423 slist_add(&servopers, nc);
00424 }
00425
00426
00427 if (nc)
00428 for (j = 0; j < RootNumber; j++)
00429 if (!stricmp(ServicesRoots[j], na->nick))
00430 nc->flags |= NI_SERVICES_ROOT;
00431
00432 SAFE(read_int16(&nc->accesscount, f));
00433 if (nc->accesscount) {
00434 char **access;
00435 access = scalloc(sizeof(char *) * nc->accesscount, 1);
00436 nc->access = access;
00437 for (j = 0; j < nc->accesscount; j++, access++)
00438 SAFE(read_string(access, f));
00439 }
00440
00441 SAFE(read_int16(&tmp16, f));
00442 nc->memos.memocount = (int16) tmp16;
00443 SAFE(read_int16(&tmp16, f));
00444 nc->memos.memomax = (int16) tmp16;
00445 if (nc->memos.memocount) {
00446 Memo *memos;
00447 memos = scalloc(sizeof(Memo) * nc->memos.memocount, 1);
00448 nc->memos.memos = memos;
00449
00450 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00451 SAFE(read_int32(&memos->number, f));
00452 SAFE(read_int16(&memos->flags, f));
00453 SAFE(read_int32(&tmp32, f));
00454 memos->time = tmp32;
00455 SAFE(read_buffer(memos->sender, f));
00456 SAFE(read_string(&memos->text, f));
00457 memos->moduleData = NULL;
00458 }
00459 }
00460
00461
00462
00463 SAFE(read_int16(&tmp16, f));
00464 SAFE(read_int16(&nc->channelmax, f));
00465 if (ver == 5)
00466 nc->channelmax = CSMaxReg;
00467
00468 SAFE(read_int16(&nc->language, f));
00469
00470 if (ver >= 11 && ver < 13) {
00471 char *s;
00472
00473 SAFE(read_int16(&tmp16, f));
00474 SAFE(read_int32(&tmp32, f));
00475 SAFE(read_int16(&tmp16, f));
00476 SAFE(read_string(&s, f));
00477 }
00478
00479
00480
00481 na->status |= NS_MASTER;
00482 na->nc = nc;
00483 slist_add(&nc->aliases, na);
00484
00485
00486 insert_core(nc);
00487 }
00488
00489 alpha_insert_alias(na);
00490
00491 }
00492 }
00493
00494
00495 for (i = 0; i < 1024; i++) {
00496 for (na = nalists[i]; na; na = next) {
00497 next = na->next;
00498
00499
00500 if (na->status & NS_MASTER)
00501 continue;
00502
00503 na2 = na;
00504
00505 while ((na2 = findnick((char *) na2->nc))
00506 && !(na2->status & NS_MASTER));
00507
00508
00509
00510 if (!na2) {
00511 alog("%s: while loading database: %s was linked to inexistant %s", s_NickServ, na->nick, (char *) na->nc);
00512 delnick(na);
00513 continue;
00514 }
00515
00516
00517
00518 na->nc = na2->nc;
00519 na->status |= NS_MASTER;
00520 slist_add(&na->nc->aliases, na);
00521 }
00522 }
00523
00524 close_db(f);
00525 }
00526
00527 void load_ns_req_db(void)
00528 {
00529 dbFILE *f;
00530 int i, c, ver;
00531 NickRequest *nr;
00532 uint32 tmp32;
00533 int failed = 0, len;
00534 char *pass;
00535
00536 if (!(f = open_db(s_NickServ, PreNickDBName, "r", PRE_NICK_VERSION)))
00537 return;
00538 ver = get_file_version(f);
00539 for (i = 0; i < 1024 && !failed; i++) {
00540 while ((c = getc_db(f)) == 1) {
00541 if (c != 1)
00542 fatal("Invalid format in %s", PreNickDBName);
00543 nr = scalloc(1, sizeof(NickRequest));
00544 SAFE(read_string(&nr->nick, f));
00545 SAFE(read_string(&nr->passcode, f));
00546 if (ver < 2) {
00547 SAFE(read_string(&pass, f));
00548 len = strlen(pass);
00549 enc_encrypt(pass, len, nr->password, PASSMAX);
00550 memset(pass, 0, len);
00551 free(pass);
00552 } else
00553 SAFE(read_buffer(nr->password, f));
00554 SAFE(read_string(&nr->email, f));
00555 SAFE(read_int32(&tmp32, f));
00556 nr->requested = tmp32;
00557 insert_requestnick(nr);
00558 }
00559 }
00560 close_db(f);
00561 }
00562
00563 void load_ns_dbase(void)
00564 {
00565 dbFILE *f;
00566 int ver, i, j, c;
00567 NickAlias *na, **nalast, *naprev;
00568 NickCore *nc, **nclast, *ncprev;
00569 int failed = 0;
00570 uint16 tmp16;
00571 uint32 tmp32;
00572 char *s, *pass;
00573
00574 if (!(f = open_db(s_NickServ, NickDBName, "r", NICK_VERSION)))
00575 return;
00576
00577 ver = get_file_version(f);
00578
00579 if (ver <= 11) {
00580 close_db(f);
00581 load_old_ns_dbase();
00582 return;
00583 }
00584
00585
00586 for (i = 0; i < 1024 && !failed; i++) {
00587 nclast = &nclists[i];
00588 ncprev = NULL;
00589
00590 while ((c = getc_db(f)) == 1) {
00591 if (c != 1)
00592 fatal("Invalid format in %s", NickDBName);
00593
00594 nc = scalloc(1, sizeof(NickCore));
00595 *nclast = nc;
00596 nclast = &nc->next;
00597 nc->prev = ncprev;
00598 ncprev = nc;
00599
00600 slist_init(&nc->aliases);
00601
00602 SAFE(read_string(&nc->display, f));
00603 if (ver < 14) {
00604 SAFE(read_string(&pass, f));
00605 if (pass) {
00606 memset(nc->pass, 0, PASSMAX);
00607 memcpy(nc->pass, pass, strlen(pass));
00608 } else
00609 memset(nc->pass, 0, PASSMAX);
00610 } else
00611 SAFE(read_buffer(nc->pass, f));
00612
00613 SAFE(read_string(&nc->email, f));
00614 SAFE(read_string(&nc->greet, f));
00615 SAFE(read_int32(&nc->icq, f));
00616 SAFE(read_string(&nc->url, f));
00617
00618 SAFE(read_int32(&nc->flags, f));
00619 if (!NSAllowKillImmed)
00620 nc->flags &= ~NI_KILL_IMMED;
00621 SAFE(read_int16(&nc->language, f));
00622
00623
00624
00625 if (nc->flags & NI_SERVICES_ADMIN)
00626 slist_add(&servadmins, nc);
00627 if (nc->flags & NI_SERVICES_OPER)
00628 slist_add(&servopers, nc);
00629
00630 SAFE(read_int16(&nc->accesscount, f));
00631 if (nc->accesscount) {
00632 char **access;
00633 access = scalloc(sizeof(char *) * nc->accesscount, 1);
00634 nc->access = access;
00635 for (j = 0; j < nc->accesscount; j++, access++)
00636 SAFE(read_string(access, f));
00637 }
00638
00639 SAFE(read_int16(&tmp16, f));
00640 nc->memos.memocount = (int16) tmp16;
00641 SAFE(read_int16(&tmp16, f));
00642 nc->memos.memomax = (int16) tmp16;
00643 if (nc->memos.memocount) {
00644 Memo *memos;
00645 memos = scalloc(sizeof(Memo) * nc->memos.memocount, 1);
00646 nc->memos.memos = memos;
00647 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00648 SAFE(read_int32(&memos->number, f));
00649 SAFE(read_int16(&memos->flags, f));
00650 SAFE(read_int32(&tmp32, f));
00651 memos->time = tmp32;
00652 SAFE(read_buffer(memos->sender, f));
00653 SAFE(read_string(&memos->text, f));
00654 memos->moduleData = NULL;
00655 }
00656 }
00657
00658 SAFE(read_int16(&nc->channelcount, f));
00659 SAFE(read_int16(&tmp16, f));
00660 nc->channelmax = CSMaxReg;
00661
00662 if (ver < 13) {
00663
00664 SAFE(read_int16(&tmp16, f));
00665 SAFE(read_int32(&tmp32, f));
00666 SAFE(read_int16(&tmp16, f));
00667 SAFE(read_string(&s, f));
00668 }
00669
00670 }
00671 *nclast = NULL;
00672 }
00673
00674 for (i = 0; i < 1024 && !failed; i++) {
00675 nalast = &nalists[i];
00676 naprev = NULL;
00677 while ((c = getc_db(f)) == 1) {
00678 if (c != 1)
00679 fatal("Invalid format in %s", NickDBName);
00680
00681 na = scalloc(1, sizeof(NickAlias));
00682
00683 SAFE(read_string(&na->nick, f));
00684
00685 SAFE(read_string(&na->last_usermask, f));
00686 SAFE(read_string(&na->last_realname, f));
00687 SAFE(read_string(&na->last_quit, f));
00688
00689 SAFE(read_int32(&tmp32, f));
00690 na->time_registered = tmp32;
00691 SAFE(read_int32(&tmp32, f));
00692 na->last_seen = tmp32;
00693 SAFE(read_int16(&na->status, f));
00694 na->status &= ~NS_TEMPORARY;
00695
00696 SAFE(read_string(&s, f));
00697 na->nc = findcore(s);
00698 free(s);
00699
00700 slist_add(&na->nc->aliases, na);
00701
00702 if (!(na->status & NS_VERBOTEN)) {
00703 if (!na->last_usermask)
00704 na->last_usermask = sstrdup("");
00705 if (!na->last_realname)
00706 na->last_realname = sstrdup("");
00707 }
00708
00709 na->nc->flags &= ~NI_SERVICES_ROOT;
00710
00711 *nalast = na;
00712 nalast = &na->next;
00713 na->prev = naprev;
00714 naprev = na;
00715
00716 }
00717
00718 *nalast = NULL;
00719 }
00720
00721 close_db(f);
00722
00723 for (i = 0; i < 1024; i++) {
00724 NickAlias *next;
00725
00726 for (na = nalists[i]; na; na = next) {
00727 next = na->next;
00728
00729 if (!na->nc) {
00730 alog("%s: while loading database: %s has no core! We delete it.", s_NickServ, na->nick);
00731 delnick(na);
00732 continue;
00733 }
00734
00735
00736 for (j = 0; j < RootNumber; j++)
00737 if (!stricmp(ServicesRoots[j], na->nick))
00738 na->nc->flags |= NI_SERVICES_ROOT;
00739 }
00740 }
00741 }
00742
00743 #undef SAFE
00744
00745
00746
00747 #define SAFE(x) do { \
00748 if ((x) < 0) { \
00749 restore_db(f); \
00750 log_perror("Write error on %s", NickDBName); \
00751 if (time(NULL) - lastwarn > WarningTimeout) { \
00752 anope_cmd_global(NULL, "Write error on %s: %s", NickDBName, \
00753 strerror(errno)); \
00754 lastwarn = time(NULL); \
00755 } \
00756 return; \
00757 } \
00758 } while (0)
00759
00760
00761
00762 void save_ns_dbase(void)
00763 {
00764 dbFILE *f;
00765 int i, j;
00766 NickAlias *na;
00767 NickCore *nc;
00768 char **access;
00769 Memo *memos;
00770 static time_t lastwarn = 0;
00771
00772 if (!(f = open_db(s_NickServ, NickDBName, "w", NICK_VERSION)))
00773 return;
00774
00775 for (i = 0; i < 1024; i++) {
00776 for (nc = nclists[i]; nc; nc = nc->next) {
00777 SAFE(write_int8(1, f));
00778
00779 SAFE(write_string(nc->display, f));
00780 SAFE(write_buffer(nc->pass, f));
00781
00782 SAFE(write_string(nc->email, f));
00783 SAFE(write_string(nc->greet, f));
00784 SAFE(write_int32(nc->icq, f));
00785 SAFE(write_string(nc->url, f));
00786
00787 SAFE(write_int32(nc->flags, f));
00788 SAFE(write_int16(nc->language, f));
00789
00790 SAFE(write_int16(nc->accesscount, f));
00791 for (j = 0, access = nc->access; j < nc->accesscount;
00792 j++, access++)
00793 SAFE(write_string(*access, f));
00794
00795 SAFE(write_int16(nc->memos.memocount, f));
00796 SAFE(write_int16(nc->memos.memomax, f));
00797 memos = nc->memos.memos;
00798 for (j = 0; j < nc->memos.memocount; j++, memos++) {
00799 SAFE(write_int32(memos->number, f));
00800 SAFE(write_int16(memos->flags, f));
00801 SAFE(write_int32(memos->time, f));
00802 SAFE(write_buffer(memos->sender, f));
00803 SAFE(write_string(memos->text, f));
00804 }
00805
00806 SAFE(write_int16(nc->channelcount, f));
00807 SAFE(write_int16(nc->channelmax, f));
00808
00809 }
00810
00811 SAFE(write_int8(0, f));
00812
00813 }
00814
00815 for (i = 0; i < 1024; i++) {
00816 for (na = nalists[i]; na; na = na->next) {
00817 SAFE(write_int8(1, f));
00818
00819 SAFE(write_string(na->nick, f));
00820
00821 SAFE(write_string(na->last_usermask, f));
00822 SAFE(write_string(na->last_realname, f));
00823 SAFE(write_string(na->last_quit, f));
00824
00825 SAFE(write_int32(na->time_registered, f));
00826 SAFE(write_int32(na->last_seen, f));
00827
00828 SAFE(write_int16(na->status, f));
00829
00830 SAFE(write_string(na->nc->display, f));
00831
00832 }
00833 SAFE(write_int8(0, f));
00834 }
00835
00836 close_db(f);
00837
00838 }
00839
00840 void save_ns_req_dbase(void)
00841 {
00842 dbFILE *f;
00843 int i;
00844 NickRequest *nr;
00845 static time_t lastwarn = 0;
00846
00847 if (!(f = open_db(s_NickServ, PreNickDBName, "w", PRE_NICK_VERSION)))
00848 return;
00849
00850 for (i = 0; i < 1024; i++) {
00851 for (nr = nrlists[i]; nr; nr = nr->next) {
00852 SAFE(write_int8(1, f));
00853 SAFE(write_string(nr->nick, f));
00854 SAFE(write_string(nr->passcode, f));
00855 SAFE(write_buffer(nr->password, f));
00856 SAFE(write_string(nr->email, f));
00857 SAFE(write_int32(nr->requested, f));
00858 SAFE(write_int8(0, f));
00859 }
00860 }
00861 close_db(f);
00862
00863 }
00864
00865 #undef SAFE
00866
00867 void save_ns_rdb_dbase(void)
00868 {
00869 #ifdef USE_RDB
00870 int i;
00871 NickAlias *na;
00872 NickCore *nc;
00873
00874 if (!rdb_open())
00875 return;
00876
00877 if (rdb_tag_table("anope_ns_core") == 0) {
00878 alog("Unable to tag 'anope_ns_core' - NickServ RDB save failed.");
00879 rdb_close();
00880 return;
00881 }
00882 if (rdb_tag_table("anope_ns_alias") == 0) {
00883 alog("Unable to tag 'anope_ns_alias' - NickServ RDB save failed.");
00884 rdb_close();
00885 return;
00886 }
00887 if (rdb_tag_table("anope_ns_access") == 0) {
00888 alog("Unable to tag 'anope_ns_access' - NickServ RDB save failed.");
00889 rdb_close();
00890 return;
00891 }
00892 if (rdb_tag_table_where("anope_ms_info", "serv='NICK'") == 0) {
00893 alog("Unable to tag 'anope_ms_info' - NickServ RDB save failed.");
00894 rdb_close();
00895 return;
00896 }
00897
00898 for (i = 0; i < 1024; i++) {
00899 for (nc = nclists[i]; nc; nc = nc->next) {
00900 if (rdb_save_ns_core(nc) == 0) {
00901 alog("Unable to save NickCore for '%s' - NickServ RDB save failed.", nc->display);
00902 rdb_close();
00903 return;
00904 }
00905 }
00906 }
00907
00908 for (i = 0; i < 1024; i++) {
00909 for (na = nalists[i]; na; na = na->next) {
00910 if (rdb_save_ns_alias(na) == 0) {
00911 alog("Unable to save NickAlias for '%s' - NickServ RDB save failed.", na->nick);
00912 rdb_close();
00913 return;
00914 }
00915 }
00916 }
00917
00918 if (rdb_clean_table("anope_ns_core") == 0) {
00919 alog("Unable to clean table 'anope_ns_core' - NickServ RDB save failed.");
00920 rdb_close();
00921 return;
00922 }
00923 if (rdb_clean_table("anope_ns_alias") == 0) {
00924 alog("Unable to clean table 'anope_ns_alias' - NickServ RDB save failed.");
00925 rdb_close();
00926 return;
00927 }
00928 if (rdb_clean_table("anope_ns_access") == 0) {
00929 alog("Unable to clean table 'anope_ns_access' - NickServ RDB save failed.");
00930 rdb_close();
00931 return;
00932 }
00933 if (rdb_clean_table_where("anope_ms_info", "serv='NICK'") == 0)
00934 alog("Unable to clean table 'anope_ms_info' - NickServ RDB save failed.");
00935
00936 rdb_close();
00937 #endif
00938 }
00939
00940 void save_ns_req_rdb_dbase(void)
00941 {
00942 #ifdef USE_RDB
00943 int i;
00944 NickRequest *nr;
00945
00946 if (!rdb_open())
00947 return;
00948
00949 if (rdb_tag_table("anope_ns_request") == 0) {
00950 alog("Unable to tag table 'anope_ns_request' - NickServ Request RDB save failed.");
00951 rdb_close();
00952 return;
00953 }
00954
00955 for (i = 0; i < 1024; i++) {
00956 for (nr = nrlists[i]; nr; nr = nr->next) {
00957 if (rdb_save_ns_req(nr) == 0) {
00958
00959 alog("Unable to save NickRequest (nick '%s') - NickServ Request RDB save failed.", nr->nick);
00960 rdb_close();
00961 return;
00962 }
00963 }
00964 }
00965
00966 if (rdb_clean_table("anope_ns_request") == 0)
00967 alog("Unable to clean table 'anope_ns_request' - NickServ Request RDB save failed.");
00968
00969 rdb_close();
00970 #endif
00971
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 int validate_user(User * u)
00985 {
00986 NickAlias *na;
00987 NickRequest *nr;
00988
00989 int on_access;
00990
00991 if ((nr = findrequestnick(u->nick))) {
00992 notice_lang(s_NickServ, u, NICK_IS_PREREG);
00993 }
00994
00995 if (!(na = u->na))
00996 return 0;
00997
00998 if (na->status & NS_VERBOTEN) {
00999 notice_lang(s_NickServ, u, NICK_MAY_NOT_BE_USED);
01000 collide(na, 0);
01001 return 0;
01002 }
01003
01004 if (na->nc->flags & NI_SUSPENDED) {
01005 notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick);
01006 collide(na, 0);
01007 return 0;
01008 }
01009
01010 if (na->status & NS_IDENTIFIED)
01011 return 1;
01012
01013 on_access = is_on_access(u, na->nc);
01014 if (on_access)
01015 na->status |= NS_ON_ACCESS;
01016
01017 if (!(na->nc->flags & NI_SECURE) && on_access) {
01018 na->status |= NS_RECOGNIZED;
01019 na->last_seen = time(NULL);
01020 if (na->last_usermask)
01021 free(na->last_usermask);
01022 na->last_usermask =
01023 scalloc(strlen(common_get_vident(u)) +
01024 strlen(common_get_vhost(u)) + 2, 1);
01025 sprintf(na->last_usermask, "%s@%s", common_get_vident(u),
01026 common_get_vhost(u));
01027 if (na->last_realname)
01028 free(na->last_realname);
01029 na->last_realname = sstrdup(u->realname);
01030 return 1;
01031 }
01032
01033 if (on_access || !(na->nc->flags & NI_KILL_IMMED)) {
01034 if (na->nc->flags & NI_SECURE)
01035 notice_lang(s_NickServ, u, NICK_IS_SECURE, s_NickServ);
01036 else
01037 notice_lang(s_NickServ, u, NICK_IS_REGISTERED, s_NickServ);
01038 }
01039
01040 if ((na->nc->flags & NI_KILLPROTECT) && !on_access) {
01041 if (na->nc->flags & NI_KILL_IMMED) {
01042 notice_lang(s_NickServ, u, FORCENICKCHANGE_NOW);
01043 collide(na, 0);
01044 } else if (na->nc->flags & NI_KILL_QUICK) {
01045 notice_lang(s_NickServ, u, FORCENICKCHANGE_IN_20_SECONDS);
01046 add_ns_timeout(na, TO_COLLIDE, 20);
01047 } else {
01048 notice_lang(s_NickServ, u, FORCENICKCHANGE_IN_1_MINUTE);
01049 add_ns_timeout(na, TO_COLLIDE, 60);
01050 }
01051 }
01052
01053 return 0;
01054 }
01055
01056
01057
01058
01059
01060
01061 void cancel_user(User * u)
01062 {
01063 NickAlias *na = u->na;
01064
01065 if (na) {
01066 if (na->status & NS_GUESTED) {
01067 if (ircd->svshold) {
01068 if (UseSVSHOLD) {
01069 anope_cmd_svshold(na->nick);
01070 } else {
01071 if (ircd->svsnick) {
01072 anope_cmd_guest_nick(u->nick, NSEnforcerUser,
01073 NSEnforcerHost,
01074 "Services Enforcer", "+");
01075 add_ns_timeout(na, TO_RELEASE, NSReleaseTimeout);
01076 } else {
01077 anope_cmd_svskill(s_NickServ, u->nick,
01078 "Killing to enforce nick");
01079 }
01080 }
01081 } else {
01082 if (ircd->svsnick) {
01083 anope_cmd_guest_nick(u->nick, NSEnforcerUser,
01084 NSEnforcerHost,
01085 "Services Enforcer", "+");
01086 add_ns_timeout(na, TO_RELEASE, NSReleaseTimeout);
01087 } else {
01088 anope_cmd_svskill(s_NickServ, u->nick,
01089 "Killing to enforce nick");
01090 }
01091 }
01092 na->status &= ~NS_TEMPORARY;
01093 na->status |= NS_KILL_HELD;
01094 } else {
01095 na->status &= ~NS_TEMPORARY;
01096 }
01097 del_ns_timeout(na, TO_COLLIDE);
01098 }
01099 }
01100
01101
01102
01103
01104
01105 int nick_identified(User * u)
01106 {
01107 if (u) {
01108 if (u->na) {
01109 if (u->na->status) {
01110 return (u->na->status & NS_IDENTIFIED);
01111 } else {
01112 return 0;
01113 }
01114 } else {
01115 return 0;
01116 }
01117 }
01118 return 0;
01119 }
01120
01121
01122
01123
01124
01125 int nick_recognized(User * u)
01126 {
01127 if (u) {
01128 if (u->na) {
01129 if (u->na->status) {
01130 return (u->na->status & (NS_IDENTIFIED | NS_RECOGNIZED));
01131 } else {
01132 return 0;
01133 }
01134 } else {
01135 return 0;
01136 }
01137 }
01138 return 0;
01139 }
01140
01141
01142
01143
01144
01145 int group_identified(User * u, NickCore * nc)
01146 {
01147 return nick_identified(u) && u->na->nc == nc;
01148 }
01149
01150
01151
01152
01153
01154
01155
01156 void expire_nicks()
01157 {
01158 int i;
01159 NickAlias *na, *next;
01160 time_t now = time(NULL);
01161 char *tmpnick;
01162
01163 for (i = 0; i < 1024; i++) {
01164 for (na = nalists[i]; na; na = next) {
01165 next = na->next;
01166
01167 if (na->u
01168 && ((na->nc->flags & NI_SECURE) ? nick_identified(na->u) :
01169 nick_recognized(na->u))) {
01170 if (debug >= 2)
01171 alog("debug: NickServ: updating last seen time for %s",
01172 na->nick);
01173 na->last_seen = now;
01174 continue;
01175 }
01176
01177 if (NSExpire && now - na->last_seen >= NSExpire
01178 && !(na->status & (NS_VERBOTEN | NS_NO_EXPIRE))
01179 && !(na->nc->flags & (NI_SUSPENDED))) {
01180 alog("Expiring nickname %s (group: %s) (e-mail: %s)",
01181 na->nick, na->nc->display,
01182 (na->nc->email ? na->nc->email : "none"));
01183 tmpnick = sstrdup(na->nick);
01184 delnick(na);
01185 send_event(EVENT_NICK_EXPIRE, 1, tmpnick);
01186 free(tmpnick);
01187 }
01188 }
01189 }
01190 }
01191
01192 void expire_requests()
01193 {
01194 int i;
01195 NickRequest *nr, *next;
01196 time_t now = time(NULL);
01197 for (i = 0; i < 1024; i++) {
01198 for (nr = nrlists[i]; nr; nr = next) {
01199 next = nr->next;
01200 if (NSRExpire && now - nr->requested >= NSRExpire) {
01201 alog("Request for nick %s expiring", nr->nick);
01202 delnickrequest(nr);
01203 }
01204 }
01205 }
01206 }
01207
01208
01209
01210
01211
01212 NickRequest *findrequestnick(const char *nick)
01213 {
01214 NickRequest *nr;
01215
01216 if (!*nick || !nick) {
01217 if (debug) {
01218 alog("debug: findrequestnick() called with NULL values");
01219 }
01220 return NULL;
01221 }
01222
01223 for (nr = nrlists[HASH(nick)]; nr; nr = nr->next) {
01224 if (stricmp(nr->nick, nick) == 0)
01225 return nr;
01226 }
01227 return NULL;
01228 }
01229
01230
01231
01232
01233 NickAlias *findnick(const char *nick)
01234 {
01235 NickAlias *na;
01236
01237 if (!nick || !*nick) {
01238 if (debug) {
01239 alog("debug: findnick() called with NULL values");
01240 }
01241 return NULL;
01242 }
01243
01244 for (na = nalists[HASH(nick)]; na; na = na->next) {
01245 if (stricmp(na->nick, nick) == 0)
01246 return na;
01247 }
01248
01249 return NULL;
01250 }
01251
01252
01253
01254
01255
01256
01257 NickCore *findcore(const char *nick)
01258 {
01259 NickCore *nc;
01260
01261 if (!nick || !*nick) {
01262 if (debug) {
01263 alog("debug: findcore() called with NULL values");
01264 }
01265 return NULL;
01266 }
01267
01268 for (nc = nclists[HASH(nick)]; nc; nc = nc->next) {
01269 if (stricmp(nc->display, nick) == 0)
01270 return nc;
01271 }
01272
01273 return NULL;
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283 int is_on_access(User * u, NickCore * nc)
01284 {
01285 int i;
01286 char *buf, *buf2 = NULL, *buf3 = NULL;
01287
01288 if (nc->accesscount == 0)
01289 return 0;
01290
01291 buf = scalloc(strlen(u->username) + strlen(u->host) + 2, 1);
01292 sprintf(buf, "%s@%s", u->username, u->host);
01293 if (ircd->vhost) {
01294 if (u->vhost) {
01295 buf2 = scalloc(strlen(u->vident) + strlen(u->vhost) + 2, 1);
01296 sprintf(buf2, "%s@%s", u->vident, u->vhost);
01297 }
01298 if (u->chost)
01299 {
01300 buf3 = scalloc(strlen(u->username) + strlen(u->chost) + 2, 1);
01301 sprintf(buf3, "%s@%s", u->username, u->chost);
01302 }
01303 }
01304
01305 for (i = 0; i < nc->accesscount; i++) {
01306 if (match_wild_nocase(nc->access[i], buf) || (buf2 && match_wild_nocase(nc->access[i], buf2)) || (buf3 && match_wild_nocase(nc->access[i], buf3)))
01307 {
01308 free(buf);
01309 if (ircd->vhost) {
01310 if (u->vhost) {
01311 free(buf2);
01312 }
01313 if (u->chost)
01314 free(buf3);
01315 }
01316 return 1;
01317 }
01318 }
01319 free(buf);
01320 if (buf2)
01321 free(buf2);
01322 if (buf3)
01323 free(buf3);
01324
01325 return 0;
01326 }
01327
01328
01329
01330
01331
01332 void alpha_insert_alias(NickAlias * na)
01333 {
01334 NickAlias *ptr, *prev;
01335 char *nick;
01336 int index;
01337
01338 if (!na) {
01339 if (debug) {
01340 alog("debug: alpha_insert_alias called with NULL values");
01341 }
01342 return;
01343 }
01344
01345 nick = na->nick;
01346 index = HASH(nick);
01347
01348 for (prev = NULL, ptr = nalists[index];
01349 ptr && stricmp(ptr->nick, nick) < 0; prev = ptr, ptr = ptr->next);
01350 na->prev = prev;
01351 na->next = ptr;
01352 if (!prev)
01353 nalists[index] = na;
01354 else
01355 prev->next = na;
01356 if (ptr)
01357 ptr->prev = na;
01358 }
01359
01360
01361
01362
01363
01364 void insert_core(NickCore * nc)
01365 {
01366 int index;
01367
01368 if (!nc) {
01369 if (debug) {
01370 alog("debug: insert_core called with NULL values");
01371 }
01372 return;
01373 }
01374
01375 index = HASH(nc->display);
01376
01377 nc->prev = NULL;
01378 nc->next = nclists[index];
01379 if (nc->next)
01380 nc->next->prev = nc;
01381 nclists[index] = nc;
01382 }
01383
01384
01385 void insert_requestnick(NickRequest * nr)
01386 {
01387 int index;
01388 if (!nr) {
01389 if (debug) {
01390 alog("debug: insert_requestnick called with NULL values");
01391 }
01392 return;
01393 }
01394
01395 index = HASH(nr->nick);
01396
01397 nr->prev = NULL;
01398 nr->next = nrlists[index];
01399 if (nr->next)
01400 nr->next->prev = nr;
01401 nrlists[index] = nr;
01402 }
01403
01404
01405
01406
01407
01408
01409
01410 void change_core_display(NickCore * nc, char *newdisplay)
01411 {
01412 if (!newdisplay) {
01413 NickAlias *na;
01414
01415 if (nc->aliases.count <= 0)
01416 return;
01417
01418 na = nc->aliases.list[0];
01419 newdisplay = na->nick;
01420 }
01421
01422
01423 alog("%s: changing %s nickname group display to %s", s_NickServ,
01424 nc->display, newdisplay);
01425 send_event(EVENT_CORE_NEWDISPLAY, 2, nc->display, newdisplay);
01426
01427 #ifdef USE_RDB
01428
01429
01430
01431
01432 if (rdb_open()) {
01433 if (rdb_ns_set_display(newdisplay, nc->display) == 0) {
01434 alog("Unable to update display for %s - Nick Display RDB update failed.", nc->display);
01435 }
01436 rdb_close();
01437 }
01438 #endif
01439
01440
01441 if (nc->next)
01442 nc->next->prev = nc->prev;
01443 if (nc->prev)
01444 nc->prev->next = nc->next;
01445 else
01446 nclists[HASH(nc->display)] = nc->next;
01447
01448 free(nc->display);
01449 nc->display = sstrdup(newdisplay);
01450 insert_core(nc);
01451
01452 }
01453
01454
01455
01456
01457
01458
01459
01460
01461 static int delcore(NickCore * nc)
01462 {
01463 int i;
01464 #ifdef USE_RDB
01465 static char clause[128];
01466 char *q_display;
01467 #endif
01468
01469
01470
01471
01472 send_event(EVENT_CORE_DROPPED, 1, nc->display);
01473
01474 cs_remove_nick(nc);
01475 os_remove_nick(nc);
01476
01477
01478 if (nc->next)
01479 nc->next->prev = nc->prev;
01480 if (nc->prev)
01481 nc->prev->next = nc->next;
01482 else
01483 nclists[HASH(nc->display)] = nc->next;
01484
01485
01486 alog("%s: deleting nickname group %s", s_NickServ, nc->display);
01487
01488 #ifdef USE_RDB
01489
01490 if (rdb_open()) {
01491 q_display = rdb_quote(nc->display);
01492 snprintf(clause, sizeof(clause), "display='%s'", q_display);
01493 if (rdb_scrub_table("anope_ns_access", clause) == 0)
01494 alog("Unable to scrub table 'anope_ns_access' - RDB update failed.");
01495 else if (rdb_scrub_table("anope_ns_core", clause) == 0)
01496 alog("Unable to scrub table 'anope_ns_core' - RDB update failed.");
01497 else if (rdb_scrub_table("anope_cs_access", clause) == 0)
01498 alog("Unable to scrub table 'anope_cs_access' - RDB update failed.");
01499 else {
01500
01501
01502 snprintf(clause, sizeof(clause),
01503 "receiver='%s' AND serv='NICK'", q_display);
01504 if (rdb_scrub_table("anope_ms_info", clause) == 0)
01505 alog("Unable to scrub table 'anope_ms_info' - RDB update failed.");
01506 }
01507 rdb_close();
01508 free(q_display);
01509 }
01510 #endif
01511
01512
01513 free(nc->display);
01514
01515 if (nc->email)
01516 free(nc->email);
01517 if (nc->greet)
01518 free(nc->greet);
01519 if (nc->url)
01520 free(nc->url);
01521
01522 if (nc->access) {
01523 for (i = 0; i < nc->accesscount; i++) {
01524 if (nc->access[i])
01525 free(nc->access[i]);
01526 }
01527 free(nc->access);
01528 }
01529
01530 if (nc->memos.memos) {
01531 for (i = 0; i < nc->memos.memocount; i++) {
01532 if (nc->memos.memos[i].text)
01533 free(nc->memos.memos[i].text);
01534 moduleCleanStruct(&nc->memos.memos[i].moduleData);
01535 }
01536 free(nc->memos.memos);
01537 }
01538
01539 moduleCleanStruct(&nc->moduleData);
01540
01541 free(nc);
01542
01543 return 1;
01544 }
01545
01546
01547
01548 int delnickrequest(NickRequest * nr)
01549 {
01550 if (nr) {
01551 if (nr->next)
01552 nr->next->prev = nr->prev;
01553 if (nr->prev)
01554 nr->prev->next = nr->next;
01555 else
01556 nrlists[HASH(nr->nick)] = nr->next;
01557
01558 if (nr->nick)
01559 free(nr->nick);
01560 if (nr->passcode)
01561 free(nr->passcode);
01562 if (nr->email)
01563 free(nr->email);
01564 free(nr);
01565 }
01566
01567 return 0;
01568 }
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580 int delnick(NickAlias * na)
01581 {
01582 #ifdef USE_RDB
01583 static char clause[128];
01584 char *q_nick;
01585 #endif
01586
01587 clean_ns_timeouts(na);
01588
01589
01590
01591
01592 if (na->u) {
01593 na->u->na = NULL;
01594
01595 if (ircd->modeonunreg)
01596 common_svsmode(na->u, ircd->modeonunreg, "1");
01597
01598 }
01599
01600 delHostCore(na->nick);
01601
01602
01603 if (na->nc) {
01604
01605 slist_remove(&na->nc->aliases, na);
01606 if (na->nc->aliases.count == 0) {
01607 if (!delcore(na->nc))
01608 return 0;
01609 na->nc = NULL;
01610 } else {
01611
01612 if (!stricmp(na->nick, na->nc->display))
01613 change_core_display(na->nc, NULL);
01614 }
01615 }
01616
01617
01618 if (na->next)
01619 na->next->prev = na->prev;
01620 if (na->prev)
01621 na->prev->next = na->next;
01622 else
01623 nalists[HASH(na->nick)] = na->next;
01624
01625 #ifdef USE_RDB
01626
01627 if (rdb_open()) {
01628 q_nick = rdb_quote(na->nick);
01629 snprintf(clause, sizeof(clause), "nick='%s'", q_nick);
01630 if (rdb_scrub_table("anope_ns_alias", clause) == 0)
01631 alog("Unable to scrub table 'anope_ns_alias' - RDB update failed");
01632 rdb_close();
01633 free(q_nick);
01634 }
01635 #endif
01636
01637 free(na->nick);
01638 if (na->last_usermask)
01639 free(na->last_usermask);
01640 if (na->last_realname)
01641 free(na->last_realname);
01642 if (na->last_quit)
01643 free(na->last_quit);
01644
01645 moduleCleanStruct(&na->moduleData);
01646
01647 free(na);
01648
01649
01650 return 1;
01651 }
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665 void collide(NickAlias * na, int from_timeout)
01666 {
01667 char guestnick[NICKMAX];
01668
01669 if (!from_timeout)
01670 del_ns_timeout(na, TO_COLLIDE);
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680 if (ircd->svsnick) {
01681
01682 do {
01683 snprintf(guestnick, sizeof(guestnick), "%s%d",
01684 NSGuestNickPrefix, getrandom16());
01685 } while (finduser(guestnick));
01686 notice_lang(s_NickServ, na->u, FORCENICKCHANGE_CHANGING,
01687 guestnick);
01688 anope_cmd_svsnick(na->nick, guestnick, time(NULL));
01689 na->status |= NS_GUESTED;
01690 } else {
01691 kill_user(s_NickServ, na->nick, "Services nickname-enforcer kill");
01692 }
01693 }
01694
01695
01696
01697
01698
01699 void release(NickAlias * na, int from_timeout)
01700 {
01701 if (!from_timeout)
01702 del_ns_timeout(na, TO_RELEASE);
01703 if (ircd->svshold) {
01704 if (UseSVSHOLD) {
01705 anope_cmd_release_svshold(na->nick);
01706 } else {
01707 anope_cmd_quit(na->nick, NULL);
01708 }
01709 } else {
01710 anope_cmd_quit(na->nick, NULL);
01711 }
01712 na->status &= ~NS_KILL_HELD;
01713 }
01714
01715
01716
01717
01718 static struct my_timeout {
01719 struct my_timeout *next, *prev;
01720 NickAlias *na;
01721 Timeout *to;
01722 int type;
01723 } *my_timeouts;
01724
01725
01726
01727
01728
01729 static void rem_ns_timeout(NickAlias * na, int type)
01730 {
01731 struct my_timeout *t, *t2;
01732
01733 t = my_timeouts;
01734 while (t) {
01735 if (t->na == na && t->type == type) {
01736 t2 = t->next;
01737 if (t->next)
01738 t->next->prev = t->prev;
01739 if (t->prev)
01740 t->prev->next = t->next;
01741 else
01742 my_timeouts = t->next;
01743 free(t);
01744 t = t2;
01745 } else {
01746 t = t->next;
01747 }
01748 }
01749 }
01750
01751
01752
01753
01754
01755 static void timeout_collide(Timeout * t)
01756 {
01757 NickAlias *na = t->data;
01758
01759 rem_ns_timeout(na, TO_COLLIDE);
01760
01761 if ((na->status & NS_IDENTIFIED) || !na->u
01762 || na->u->my_signon > t->settime)
01763 return;
01764
01765
01766
01767 collide(na, 1);
01768 }
01769
01770
01771
01772
01773
01774 static void timeout_release(Timeout * t)
01775 {
01776 NickAlias *na = t->data;
01777
01778 rem_ns_timeout(na, TO_RELEASE);
01779 release(na, 1);
01780 }
01781
01782
01783
01784
01785
01786 static void add_ns_timeout(NickAlias * na, int type, time_t delay)
01787 {
01788 Timeout *to;
01789 struct my_timeout *t;
01790 void (*timeout_routine) (Timeout *);
01791
01792 if (type == TO_COLLIDE)
01793 timeout_routine = timeout_collide;
01794 else if (type == TO_RELEASE)
01795 timeout_routine = timeout_release;
01796 else {
01797 alog("NickServ: unknown timeout type %d! na=0x%p (%s), delay=%ld",
01798 type, (void *) na, na->nick, (long int) delay);
01799 return;
01800 }
01801
01802 to = add_timeout(delay, timeout_routine, 0);
01803 to->data = na;
01804
01805 t = scalloc(sizeof(struct my_timeout), 1);
01806 t->na = na;
01807 t->to = to;
01808 t->type = type;
01809
01810 t->prev = NULL;
01811 t->next = my_timeouts;
01812 my_timeouts = t;
01813
01814
01815
01816
01817 if (t->next)
01818 t->next->prev = t;
01819 }
01820
01821
01822
01823
01824
01825 void del_ns_timeout(NickAlias * na, int type)
01826 {
01827 struct my_timeout *t, *t2;
01828
01829 t = my_timeouts;
01830 while (t) {
01831 if (t->na == na && t->type == type) {
01832 t2 = t->next;
01833 if (t->next)
01834 t->next->prev = t->prev;
01835 if (t->prev)
01836 t->prev->next = t->next;
01837 else
01838 my_timeouts = t->next;
01839 del_timeout(t->to);
01840 free(t);
01841 t = t2;
01842 } else {
01843 t = t->next;
01844 }
01845 }
01846 }
01847
01848
01849
01850
01851
01852
01853
01854 void clean_ns_timeouts(NickAlias * na)
01855 {
01856 struct my_timeout *t, *next;
01857
01858 for (t = my_timeouts; t; t = next) {
01859 next = t->next;
01860 if (t->na == na) {
01861 if (debug)
01862 alog("debug: %s deleting timeout type %d from %s",
01863 s_NickServ, t->type, t->na->nick);
01864
01865 if (t->type == TO_RELEASE)
01866 release(na, 1);
01867 if (t->next)
01868 t->next->prev = t->prev;
01869 if (t->prev)
01870 t->prev->next = t->next;
01871 else
01872 my_timeouts = t->next;
01873 del_timeout(t->to);
01874 free(t);
01875 }
01876 }
01877 }
01878
01879
01880
01881
01882
01883
01884
01885 int should_mode_change(int16 status, int16 mode)
01886 {
01887 switch (mode) {
01888 case CUS_OP:
01889 if (status & CUS_OP) {
01890 return 0;
01891 }
01892 break;
01893 case CUS_VOICE:
01894 if (status & CUS_OP) {
01895 return 0;
01896 }
01897 if (status & CUS_HALFOP) {
01898 return 0;
01899 }
01900 if (status & CUS_VOICE) {
01901 return 0;
01902 }
01903 return 1;
01904 break;
01905 case CUS_HALFOP:
01906 if (status & CUS_OP) {
01907 return 0;
01908 }
01909 if (status & CUS_HALFOP) {
01910 return 0;
01911 }
01912 return 1;
01913 break;
01914 case CUS_OWNER:
01915 if (ircd->owner) {
01916 if (status & CUS_OWNER) {
01917 return 0;
01918 }
01919 }
01920 break;
01921 case CUS_PROTECT:
01922 if (ircd->protect) {
01923 if (status & CUS_PROTECT) {
01924 return 0;
01925 }
01926 }
01927 break;
01928 }
01929 return 1;
01930 }
01931
01932
01933
01934 int do_setmodes(User * u)
01935 {
01936 struct u_chanlist *uc;
01937 Channel *c;
01938
01939
01940 for (uc = u->chans; uc; uc = uc->next) {
01941 if ((c = uc->chan))
01942 chan_set_correct_modes(u, c, 1);
01943 }
01944 return MOD_CONT;
01945 }
01946
01947
01948
01949
01950
01951
01956 void nsStartNickTracking(User * u)
01957 {
01958 NickCore *nc;
01959
01960
01961 if (nick_identified(u)) {
01962 nc = u->na->nc;
01963
01964
01965 if (u->nickTrack)
01966 free(u->nickTrack);
01967
01968
01969
01970 u->nickTrack = sstrdup(nc->display);
01971 }
01972 }
01973
01978 void nsStopNickTracking(User * u)
01979 {
01980
01981 if (u->nickTrack) {
01982 free(u->nickTrack);
01983 u->nickTrack = NULL;
01984 }
01985 }
01986
01992 int nsCheckNickTracking(User * u)
01993 {
01994 NickCore *nc;
01995 NickAlias *na;
01996 char *nick;
01997
01998
01999 if ((!(na = u->na)) || (!(nick = na->nick))) {
02000 return 0;
02001 }
02002
02003
02004 if (na->status & NS_VERBOTEN) {
02005 return 0;
02006 }
02007
02008
02009 nc = na->nc;
02010
02011
02012
02013
02014 if (nc && u->nickTrack && (strcmp(nc->display, u->nickTrack) == 0))
02015 return 1;
02016 else
02017 return 0;
02018 }