hostserv.c

Go to the documentation of this file.
00001 /* HostServ functions
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  * $Id: hostserv.c 1265 2007-08-26 15:33:06Z geniusdex $ 
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;          /* head of the HostCore list */
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 /*  Start of Linked List routines                                        */
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             /* we know were not gonna find it now.... */
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);   /* delete the old entry */
00281             addHostCore(nick, vIdent, vhost, creator, tmp_time);        /* recursive call to add new entry */
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         /* Reflect this change in the database right away. */
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 /*  End of Linked List routines                  */
00347 /*************************************************************************/
00348 /*************************************************************************/
00349 /*  Start of Load/Save routines                  */
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);     /* could get a speed increase by not searching the list */
00397             free(nick);         /* as we know the db is in alphabetical order... */
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);      /* could get a speed increase by not searching the list */
00423             free(nick);         /* as we know the db is in alphabetical order... */
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);    /* could get a speed increase by not searching the list */
00451             free(nick);         /* as we know the db is in alphabetical order... */
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 /*  End of Load/Save Functions                   */
00535 /*************************************************************************/
00536 /*************************************************************************/
00537 /*  Start of Generic Functions                   */
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 {                               /* we've assumed that the user exists etc.. */
00556     char *vHost;                /* as were only gonna call this from nsid routine */
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     /* Look through all user's aliases (0000412) */
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);   /* only here incase we want to split them up later */
00609 }
00610 
00611 /*
00612  * Sets the last_usermak properly. Using virtual ident and/or host 
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 }

Generated on Sun Dec 30 09:26:48 2007 for Anope by  doxygen 1.5.1-20070107