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