00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "services.h"
00016 #include "pseudo.h"
00017
00018 #define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
00019
00020 void load_hs_dbase_v1(dbFILE * f);
00021 void load_hs_dbase_v2(dbFILE * f);
00022 void load_hs_dbase_v3(dbFILE * f);
00023
00024 HostCore *head = NULL;
00025
00026 E int do_hs_sync(NickCore * nc, char *vIdent, char *hostmask,
00027 char *creator, time_t time);
00028
00029 E void moduleAddHostServCmds(void);
00030
00031
00032
00033 void moduleAddHostServCmds(void)
00034 {
00035 modules_core_init(HostServCoreNumber, HostServCoreModules);
00036 }
00037
00038
00039
00045 void get_hostserv_stats(long *nrec, long *memuse)
00046 {
00047 long count = 0, mem = 0;
00048 HostCore *hc;
00049
00050 for (hc = head; hc; hc = hc->next) {
00051 count++;
00052 mem += sizeof(*hc);
00053 if (hc->nick)
00054 mem += strlen(hc->nick) + 1;
00055 if (hc->vIdent)
00056 mem += strlen(hc->vIdent) + 1;
00057 if (hc->vHost)
00058 mem += strlen(hc->vHost) + 1;
00059 if (hc->creator)
00060 mem += strlen(hc->creator) + 1;
00061 }
00062
00063 *nrec = count;
00064 *memuse = mem;
00065 }
00066
00067
00068
00073 void hostserv_init(void)
00074 {
00075 if (s_HostServ) {
00076 moduleAddHostServCmds();
00077 }
00078 }
00079
00080
00081
00088 void hostserv(User * u, char *buf)
00089 {
00090 char *cmd, *s;
00091
00092 cmd = strtok(buf, " ");
00093
00094 if (!cmd) {
00095 return;
00096 } else if (stricmp(cmd, "\1PING") == 0) {
00097 if (!(s = strtok(NULL, ""))) {
00098 s = "";
00099 }
00100 anope_cmd_ctcp(s_HostServ, u->nick, "PING %s", s);
00101 } else if (skeleton) {
00102 notice_lang(s_HostServ, u, SERVICE_OFFLINE, s_HostServ);
00103 } else {
00104 if (ircd->vhost) {
00105 mod_run_cmd(s_HostServ, u, HOSTSERV, cmd);
00106 } else {
00107 notice_lang(s_HostServ, u, SERVICE_OFFLINE, s_HostServ);
00108 }
00109 }
00110 }
00111
00112
00113
00114
00115
00116 HostCore *hostCoreListHead()
00117 {
00118 return head;
00119 }
00120
00131 HostCore *createHostCorelist(HostCore * next, char *nick, char *vIdent,
00132 char *vHost, char *creator, int32 tmp_time)
00133 {
00134
00135 next = malloc(sizeof(HostCore));
00136 if (next == NULL) {
00137 anope_cmd_global(s_HostServ,
00138 "Unable to allocate memory to create the vHost LL, problems i sense..");
00139 } else {
00140 next->nick = malloc(sizeof(char) * strlen(nick) + 1);
00141 next->vHost = malloc(sizeof(char) * strlen(vHost) + 1);
00142 next->creator = malloc(sizeof(char) * strlen(creator) + 1);
00143 if (vIdent)
00144 next->vIdent = malloc(sizeof(char) * strlen(vIdent) + 1);
00145 if ((next->nick == NULL) || (next->vHost == NULL)
00146 || (next->creator == NULL)) {
00147 anope_cmd_global(s_HostServ,
00148 "Unable to allocate memory to create the vHost LL, problems i sense..");
00149 return NULL;
00150 }
00151 strcpy(next->nick, nick);
00152 strcpy(next->vHost, vHost);
00153 strcpy(next->creator, creator);
00154 if (vIdent) {
00155 if ((next->vIdent == NULL)) {
00156 anope_cmd_global(s_HostServ,
00157 "Unable to allocate memory to create the vHost LL, problems i sense..");
00158 return NULL;
00159 }
00160 strcpy(next->vIdent, vIdent);
00161 } else {
00162 next->vIdent = NULL;
00163 }
00164 next->time = tmp_time;
00165 next->next = NULL;
00166 return next;
00167 }
00168 return NULL;
00169 }
00170
00171
00180 HostCore *findHostCore(HostCore * head, char *nick, boolean * found)
00181 {
00182 HostCore *previous, *current;
00183
00184 *found = false;
00185 current = head;
00186 previous = current;
00187
00188 if (!nick) {
00189 return NULL;
00190 }
00191
00192 while (current != NULL) {
00193 if (stricmp(nick, current->nick) == 0) {
00194 *found = true;
00195 break;
00196 } else if (stricmp(nick, current->nick) < 0) {
00197
00198 break;
00199 } else {
00200 previous = current;
00201 current = current->next;
00202 }
00203 }
00204 if (current == head) {
00205 return NULL;
00206 } else {
00207 return previous;
00208 }
00209 }
00210
00211
00212 HostCore *insertHostCore(HostCore * head, HostCore * prev, char *nick,
00213 char *vIdent, char *vHost, char *creator,
00214 int32 tmp_time)
00215 {
00216
00217 HostCore *newCore, *tmp;
00218
00219 if (!nick || !vHost || !creator) {
00220 return NULL;
00221 }
00222
00223 newCore = malloc(sizeof(HostCore));
00224 if (newCore == NULL) {
00225 anope_cmd_global(s_HostServ,
00226 "Unable to allocate memory to insert into the vHost LL, problems i sense..");
00227 return NULL;
00228 } else {
00229 newCore->nick = malloc(sizeof(char) * strlen(nick) + 1);
00230 newCore->vHost = malloc(sizeof(char) * strlen(vHost) + 1);
00231 newCore->creator = malloc(sizeof(char) * strlen(creator) + 1);
00232 if (vIdent)
00233 newCore->vIdent = malloc(sizeof(char) * strlen(vIdent) + 1);
00234 if ((newCore->nick == NULL) || (newCore->vHost == NULL)
00235 || (newCore->creator == NULL)) {
00236 anope_cmd_global(s_HostServ,
00237 "Unable to allocate memory to create the vHost LL, problems i sense..");
00238 return NULL;
00239 }
00240 strcpy(newCore->nick, nick);
00241 strcpy(newCore->vHost, vHost);
00242 strcpy(newCore->creator, creator);
00243 if (vIdent) {
00244 if ((newCore->vIdent == NULL)) {
00245 anope_cmd_global(s_HostServ,
00246 "Unable to allocate memory to create the vHost LL, problems i sense..");
00247 return NULL;
00248 }
00249 strcpy(newCore->vIdent, vIdent);
00250 } else {
00251 newCore->vIdent = NULL;
00252 }
00253 newCore->time = tmp_time;
00254 if (prev == NULL) {
00255 tmp = head;
00256 head = newCore;
00257 newCore->next = tmp;
00258 } else {
00259 tmp = prev->next;
00260 prev->next = newCore;
00261 newCore->next = tmp;
00262 }
00263 }
00264 return head;
00265 }
00266
00267
00268 HostCore *deleteHostCore(HostCore * head, HostCore * prev)
00269 {
00270
00271 HostCore *tmp;
00272
00273 if (prev == NULL) {
00274 tmp = head;
00275 head = head->next;
00276 } else {
00277 tmp = prev->next;
00278 prev->next = tmp->next;
00279 }
00280 free(tmp->vHost);
00281 free(tmp->nick);
00282 free(tmp->creator);
00283 if (tmp->vIdent) {
00284 free(tmp->vIdent);
00285 }
00286 free(tmp);
00287 return head;
00288 }
00289
00290
00291 void addHostCore(char *nick, char *vIdent, char *vhost, char *creator,
00292 int32 tmp_time)
00293 {
00294 HostCore *tmp;
00295 boolean found = false;
00296
00297 if (head == NULL) {
00298 head =
00299 createHostCorelist(head, nick, vIdent, vhost, creator,
00300 tmp_time);
00301 } else {
00302 tmp = findHostCore(head, nick, &found);
00303 if (!found) {
00304 head =
00305 insertHostCore(head, tmp, nick, vIdent, vhost, creator,
00306 tmp_time);
00307 } else {
00308 head = deleteHostCore(head, tmp);
00309 addHostCore(nick, vIdent, vhost, creator, tmp_time);
00310 }
00311 }
00312 }
00313
00314
00315 char *getvHost(char *nick)
00316 {
00317 HostCore *tmp;
00318 boolean found = false;
00319 tmp = findHostCore(head, nick, &found);
00320 if (found) {
00321 if (tmp == NULL)
00322 return head->vHost;
00323 else
00324 return tmp->next->vHost;
00325 }
00326 return NULL;
00327 }
00328
00329
00330 char *getvIdent(char *nick)
00331 {
00332 HostCore *tmp;
00333 boolean found = false;
00334 tmp = findHostCore(head, nick, &found);
00335 if (found) {
00336 if (tmp == NULL)
00337 return head->vIdent;
00338 else
00339 return tmp->next->vIdent;
00340 }
00341 return NULL;
00342 }
00343
00344
00345 void delHostCore(char *nick)
00346 {
00347 #ifdef USE_RDB
00348 static char clause[128];
00349 char *q_nick;
00350 #endif
00351 HostCore *tmp;
00352 boolean found = false;
00353 tmp = findHostCore(head, nick, &found);
00354 if (found) {
00355 head = deleteHostCore(head, tmp);
00356
00357 #ifdef USE_RDB
00358
00359 if (rdb_open()) {
00360 q_nick = rdb_quote(nick);
00361 snprintf(clause, sizeof(clause), "nick='%s'", q_nick);
00362 if (rdb_scrub_table("anope_hs_core", clause) == 0)
00363 alog("Unable to scrub table 'anope_hs_core' - HostServ RDB update failed.");
00364 rdb_close();
00365 free(q_nick);
00366 }
00367 #endif
00368
00369 }
00370
00371 }
00372
00373
00374
00375
00376
00377
00378
00379 #define SAFE(x) do { \
00380 if ((x) < 0) { \
00381 if (!forceload) \
00382 fatal("Read error on %s", HostDBName); \
00383 failed = 1; \
00384 break; \
00385 } \
00386 } while (0)
00387
00388 void load_hs_dbase(void)
00389 {
00390 dbFILE *f;
00391 int ver;
00392
00393 if (!(f = open_db(s_HostServ, HostDBName, "r", HOST_VERSION))) {
00394 return;
00395 }
00396 ver = get_file_version(f);
00397
00398 if (ver == 1) {
00399 load_hs_dbase_v1(f);
00400 } else if (ver == 2) {
00401 load_hs_dbase_v2(f);
00402 } else if (ver == 3) {
00403 load_hs_dbase_v3(f);
00404 }
00405 close_db(f);
00406 }
00407
00408 void load_hs_dbase_v1(dbFILE * f)
00409 {
00410 int c;
00411 int failed = 0;
00412 int32 tmp;
00413
00414 char *nick;
00415 char *vHost;
00416
00417 tmp = time(NULL);
00418
00419 while (!failed && (c = getc_db(f)) == 1) {
00420
00421 if (c == 1) {
00422 SAFE(read_string(&nick, f));
00423 SAFE(read_string(&vHost, f));
00424 addHostCore(nick, NULL, vHost, "Unknown", tmp);
00425 free(nick);
00426 free(vHost);
00427 } else {
00428 fatal("Invalid format in %s %d", HostDBName, c);
00429 }
00430 }
00431 }
00432
00433 void load_hs_dbase_v2(dbFILE * f)
00434 {
00435 int c;
00436 int failed = 0;
00437
00438 char *nick;
00439 char *vHost;
00440 char *creator;
00441 uint32 time;
00442
00443 while (!failed && (c = getc_db(f)) == 1) {
00444
00445 if (c == 1) {
00446 SAFE(read_string(&nick, f));
00447 SAFE(read_string(&vHost, f));
00448 SAFE(read_string(&creator, f));
00449 SAFE(read_int32(&time, f));
00450 addHostCore(nick, NULL, vHost, creator, time);
00451 free(nick);
00452 free(vHost);
00453 free(creator);
00454 } else {
00455 fatal("Invalid format in %s %d", HostDBName, c);
00456 }
00457 }
00458 }
00459
00460 void load_hs_dbase_v3(dbFILE * f)
00461 {
00462 int c;
00463 int failed = 0;
00464
00465 char *nick;
00466 char *vHost;
00467 char *creator;
00468 char *vIdent;
00469 uint32 time;
00470
00471 while (!failed && (c = getc_db(f)) == 1) {
00472 if (c == 1) {
00473 SAFE(read_string(&nick, f));
00474 SAFE(read_string(&vIdent, f));
00475 SAFE(read_string(&vHost, f));
00476 SAFE(read_string(&creator, f));
00477 SAFE(read_int32(&time, f));
00478 addHostCore(nick, vIdent, vHost, creator, time);
00479 free(nick);
00480 free(vHost);
00481 free(creator);
00482 free(vIdent);
00483 } else {
00484 fatal("Invalid format in %s %d", HostDBName, c);
00485 }
00486 }
00487 }
00488
00489 #undef SAFE
00490
00491 #define SAFE(x) do { \
00492 if ((x) < 0) { \
00493 restore_db(f); \
00494 log_perror("Write error on %s", HostDBName); \
00495 if (time(NULL) - lastwarn > WarningTimeout) { \
00496 anope_cmd_global(NULL, "Write error on %s: %s", HostDBName, \
00497 strerror(errno)); \
00498 lastwarn = time(NULL); \
00499 } \
00500 return; \
00501 } \
00502 } while (0)
00503
00504 void save_hs_dbase(void)
00505 {
00506 dbFILE *f;
00507 static time_t lastwarn = 0;
00508 HostCore *current;
00509
00510 if (!(f = open_db(s_HostServ, HostDBName, "w", HOST_VERSION)))
00511 return;
00512
00513 current = head;
00514 while (current != NULL) {
00515 SAFE(write_int8(1, f));
00516 SAFE(write_string(current->nick, f));
00517 SAFE(write_string(current->vIdent, f));
00518 SAFE(write_string(current->vHost, f));
00519 SAFE(write_string(current->creator, f));
00520 SAFE(write_int32(current->time, f));
00521 current = current->next;
00522 }
00523 SAFE(write_int8(0, f));
00524 close_db(f);
00525
00526 }
00527
00528 #undef SAFE
00529
00530 void save_hs_rdb_dbase(void)
00531 {
00532 #ifdef USE_RDB
00533 HostCore *current;
00534
00535 if (!rdb_open())
00536 return;
00537
00538 if (rdb_tag_table("anope_hs_core") == 0) {
00539 alog("Unable to tag table 'anope_hs_core' - HostServ RDB save failed.");
00540 rdb_close();
00541 return;
00542 }
00543
00544 current = head;
00545 while (current != NULL) {
00546 if (rdb_save_hs_core(current) == 0) {
00547 alog("Unable to save HostCore for %s - HostServ RDB save failed.", current->nick);
00548 rdb_close();
00549 return;
00550 }
00551 current = current->next;
00552 }
00553
00554 if (rdb_clean_table("anope_hs_core") == 0)
00555 alog("Unable to clean table 'anope_hs_core' - HostServ RDB save failed.");
00556
00557 rdb_close();
00558 #endif
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568 int do_hs_sync(NickCore * nc, char *vIdent, char *hostmask, char *creator,
00569 time_t time)
00570 {
00571 int i;
00572 NickAlias *na;
00573
00574 for (i = 0; i < nc->aliases.count; i++) {
00575 na = nc->aliases.list[i];
00576 addHostCore(na->nick, vIdent, hostmask, creator, time);
00577 }
00578 return MOD_CONT;
00579 }
00580
00581
00582 int do_on_id(User * u)
00583 {
00584 char *vHost;
00585 char *vIdent;
00586 vHost = getvHost(u->nick);
00587 vIdent = getvIdent(u->nick);
00588 if (vHost != NULL) {
00589 if (vIdent) {
00590 notice_lang(s_HostServ, u, HOST_IDENT_ACTIVATED, vIdent,
00591 vHost);
00592 } else {
00593 notice_lang(s_HostServ, u, HOST_ACTIVATED, vHost);
00594 }
00595 anope_cmd_vhost_on(u->nick, vIdent, vHost);
00596 if (ircd->vhost) {
00597 if (u->vhost)
00598 free(u->vhost);
00599 u->vhost = sstrdup(vHost);
00600 }
00601 if (ircd->vident) {
00602 if (vIdent) {
00603 if (u->vident)
00604 free(u->vident);
00605 u->vident = sstrdup(vIdent);
00606 }
00607 }
00608 set_lastmask(u);
00609 }
00610 return MOD_CONT;
00611 }
00612
00613
00614 int is_host_setter(User * u)
00615 {
00616 int i, j;
00617 NickAlias *na;
00618
00619 if (is_services_oper(u)) {
00620 return 1;
00621 }
00622 if (!nick_identified(u)) {
00623 return 0;
00624 }
00625
00626
00627 for (i = 0; i < u->na->nc->aliases.count; i++) {
00628 na = u->na->nc->aliases.list[i];
00629 for (j = 0; j < HostNumber; j++) {
00630 if (stricmp(HostSetters[j], na->nick) == 0) {
00631 return 1;
00632 }
00633 }
00634 }
00635
00636 return 0;
00637 }
00638
00639 int is_host_remover(User * u)
00640 {
00641 return is_host_setter(u);
00642 }
00643
00644
00645
00646
00647 void set_lastmask(User * u)
00648 {
00649 if (u->na->last_usermask)
00650 free(u->na->last_usermask);
00651
00652 u->na->last_usermask =
00653 smalloc(strlen(common_get_vident(u)) +
00654 strlen(common_get_vhost(u)) + 2);
00655 sprintf(u->na->last_usermask, "%s@%s", common_get_vident(u),
00656 common_get_vhost(u));
00657
00658 }