charybdis.c

Go to the documentation of this file.
00001 /* Charybdis IRCD functions
00002  *
00003  * (C) 2006 William Pitcock <nenolod -at- charybdis.be>
00004  * (C) 2003-2007 Anope Team
00005  * Contact us at info@anope.org
00006  *
00007  * Please read COPYING and README for furhter details.
00008  *
00009  * Based on the original code of Epona by Lara.
00010  * Based on the original code of Services by Andy Church. 
00011  */
00012 
00013 #include "services.h"
00014 #include "pseudo.h"
00015 #include "charybdis.h"
00016 
00017 IRCDVar myIrcd[] = {
00018     {"Charybdis 1.0+",           /* ircd name */
00019      "+oiS",                     /* nickserv mode */
00020      "+oiS",                     /* chanserv mode */
00021      "+oiS",                     /* memoserv mode */
00022      "+oiS",                     /* hostserv mode */
00023      "+oaiS",                    /* operserv mode */
00024      "+oiS",                     /* botserv mode  */
00025      "+oiS",                     /* helpserv mode */
00026      "+oiS",                     /* Dev/Null mode */
00027      "+oiS",                     /* Global mode   */
00028      "+oiS",                     /* nickserv alias mode */
00029      "+oiS",                     /* chanserv alias mode */
00030      "+oiS",                     /* memoserv alias mode */
00031      "+oiS",                     /* hostserv alias mode */
00032      "+oaiS",                    /* operserv alias mode */
00033      "+oiS",                     /* botserv alias mode  */
00034      "+oiS",                     /* helpserv alias mode */
00035      "+oiS",                     /* Dev/Null alias mode */
00036      "+oiS",                     /* Global alias mode   */
00037      "+oiS",                     /* Used by BotServ Bots */
00038      2,                         /* Chan Max Symbols     */
00039      "-cilmnpstrgzQF",          /* Modes to Remove */
00040      "+o",                      /* Channel Umode used by Botserv bots */
00041      1,                         /* SVSNICK */
00042      1,                         /* Vhost  */
00043      0,                         /* Has Owner */
00044      NULL,                      /* Mode to set for an owner */
00045      NULL,                      /* Mode to unset for an owner */
00046      NULL,                      /* Mode to set for chan admin */
00047      NULL,                      /* Mode to unset for chan admin */
00048      NULL,                      /* Mode On Reg          */
00049      NULL,                      /* Mode on ID for Roots */
00050      NULL,                      /* Mode on ID for Admins */
00051      NULL,                      /* Mode on ID for Opers */
00052      NULL,                      /* Mode on UnReg        */
00053      NULL,                      /* Mode on Nick Change  */
00054      1,                         /* Supports SGlines     */
00055      1,                         /* Supports SQlines     */
00056      1,                         /* Supports SZlines     */
00057      0,                         /* Supports Halfop +h   */
00058      3,                         /* Number of server args */
00059      1,                         /* Join 2 Set           */
00060      1,                         /* Join 2 Message       */
00061      1,                         /* Has exceptions +e    */
00062      0,                         /* TS Topic Forward     */
00063      0,                         /* TS Topci Backward    */
00064      0,                         /* Protected Umode      */
00065      0,                         /* Has Admin            */
00066      1,                         /* Chan SQlines         */
00067      0,                         /* Quit on Kill         */
00068      0,                         /* SVSMODE unban        */
00069      0,                         /* Has Protect          */
00070      0,                         /* Reverse              */
00071      0,                         /* Chan Reg             */
00072      0,                         /* Channel Mode         */
00073      0,                         /* vidents              */
00074      1,                         /* svshold              */
00075      0,                         /* time stamp on mode   */
00076      0,                         /* NICKIP               */
00077      0,                         /* UMODE                */
00078      0,                         /* O:LINE               */
00079      1,                         /* VHOST ON NICK        */
00080      0,                         /* Change RealName      */
00081      CMODE_p,                   /* No Knock             */
00082      0,                         /* Admin Only           */
00083      DEFAULT_MLOCK,             /* Default MLOCK        */
00084      0,                         /* Vhost Mode           */
00085      1,                         /* +f                   */
00086      1,                         /* +L                   */
00087      CMODE_j,                   /* +f Mode                          */
00088      CMODE_f,                   /* +L Mode (+f <target>)            */
00089      1,                         /* On nick change check if they could be identified */
00090      0,                         /* No Knock requires +i */
00091      NULL,                      /* CAPAB Chan Modes             */
00092      0,                         /* We support TOKENS */
00093      1,                         /* TOKENS are CASE inSensitive */
00094      0,                         /* TIME STAMPS are BASE64 */
00095      1,                         /* +I support */
00096      0,                         /* SJOIN ban char */
00097      0,                         /* SJOIN except char */
00098      0,                         /* SJOIN invite char */
00099      0,                         /* Can remove User Channel Modes with SVSMODE */
00100      0,                         /* Sglines are not enforced until user reconnects */
00101      NULL,                      /* vhost char */
00102      1,                         /* ts6 */
00103      0,                         /* support helper umode */
00104      0,                         /* p10 */
00105      NULL,                      /* character set */
00106      0,                         /* reports sync state */
00107      }
00108     ,
00109     {NULL}
00110 };
00111 
00112 IRCDCAPAB myIrcdcap[] = {
00113     {
00114      0,                         /* NOQUIT       */
00115      0,                         /* TSMODE       */
00116      0,                         /* UNCONNECT    */
00117      0,                         /* NICKIP       */
00118      0,                         /* SJOIN        */
00119      CAPAB_ZIP,                 /* ZIP          */
00120      0,                         /* BURST        */
00121      CAPAB_TS5,                 /* TS5          */
00122      0,                         /* TS3          */
00123      0,                         /* DKEY         */
00124      0,                         /* PT4          */
00125      0,                         /* SCS          */
00126      CAPAB_QS,                  /* QS           */
00127      CAPAB_UID,                 /* UID          */
00128      CAPAB_KNOCK,               /* KNOCK        */
00129      0,                         /* CLIENT       */
00130      0,                         /* IPV6         */
00131      0,                         /* SSJ5         */
00132      0,                         /* SN2          */
00133      0,                         /* TOKEN        */
00134      0,                         /* VHOST        */
00135      0,                         /* SSJ3         */
00136      0,                         /* NICK2        */
00137      0,                         /* UMODE2       */
00138      0,                         /* VL           */
00139      0,                         /* TLKEXT       */
00140      0,                         /* DODKEY       */
00141      0,                         /* DOZIP        */
00142      0, 0, 0}
00143 };
00144 
00145 /*******************************************************************/
00146 
00147 void charybdis_set_umode(User * user, int ac, char **av)
00148 {
00149     int add = 1;                /* 1 if adding modes, 0 if deleting */
00150     char *modes = av[0];
00151 
00152     ac--;
00153 
00154     if (debug)
00155         alog("debug: Changing mode for %s to %s", user->nick, modes);
00156 
00157     while (*modes) {
00158 
00159         /* This looks better, much better than "add ? (do_add) : (do_remove)".
00160          * At least this is readable without paying much attention :) -GD
00161          */
00162         if (add)
00163             user->mode |= umodes[(int) *modes];
00164         else
00165             user->mode &= ~umodes[(int) *modes];
00166 
00167         switch (*modes++) {
00168         case '+':
00169             add = 1;
00170             break;
00171         case '-':
00172             add = 0;
00173             break;
00174         case 'o':
00175             if (add) {
00176                 opcnt++;
00177 
00178                 if (WallOper)
00179                     anope_cmd_global(s_OperServ,
00180                                      "\2%s\2 is now an IRC operator.",
00181                                      user->nick);
00182                 display_news(user, NEWS_OPER);
00183 
00184             } else {
00185                 opcnt--;
00186             }
00187             break;
00188         }
00189     }
00190 }
00191 
00192 unsigned long umodes[128] = {
00193     0, 0, 0,                    /* Unused */
00194     0, 0, 0,                    /* Unused */
00195     0, 0, 0,                    /* Unused, Unused, Horzontal Tab */
00196     0, 0, 0,                    /* Line Feed, Unused, Unused */
00197     0, 0, 0,                    /* Carriage Return, Unused, Unused */
00198     0, 0, 0,                    /* Unused */
00199     0, 0, 0,                    /* Unused */
00200     0, 0, 0,                    /* Unused */
00201     0, 0, 0,                    /* Unused */
00202     0, 0, 0,                    /* Unused */
00203     0, 0, 0,                    /* Unused, Unused, Space */
00204     0, 0, 0,                    /* ! " #  */
00205     0, 0, 0,                    /* $ % &  */
00206     0, 0, 0,                    /* ! ( )  */
00207     0, 0, 0,                    /* * + ,  */
00208     0, 0, 0,                    /* - . /  */
00209     0, 0,                       /* 0 1 */
00210     0, 0,                       /* 2 3 */
00211     0, 0,                       /* 4 5 */
00212     0, 0,                       /* 6 7 */
00213     0, 0,                       /* 8 9 */
00214     0, 0,                       /* : ; */
00215     0, 0, 0,                    /* < = > */
00216     0, 0,                       /* ? @ */
00217     0, 0, 0,                    /* A B C */
00218     0, 0, 0,                    /* D E F */
00219     0, 0, 0,                    /* G H I */
00220     0, 0, 0,                    /* J K L */
00221     0, 0, 0,                    /* M N O */
00222     0, UMODE_Q, UMODE_R,        /* P Q R */
00223     UMODE_S, 0, 0,              /* S T U */
00224     0, 0, 0,                    /* V W X */
00225     0,                          /* Y */
00226     0,                          /* Z */
00227     0, 0, 0,                    /* [ \ ] */
00228     0, 0, 0,                    /* ^ _ ` */
00229     UMODE_a, 0, 0,              /* a b c */
00230     0, 0, 0,                    /* d e f */
00231     UMODE_g, 0, UMODE_i,        /* g h i */
00232     0, 0, UMODE_l,              /* j k l */
00233     0, 0, UMODE_o,              /* m n o */
00234     0, 0, 0,                    /* p q r */
00235     UMODE_s, 0, 0,              /* s t u */
00236     0, UMODE_w, 0,              /* v w x */
00237     0,                          /* y */
00238     UMODE_z,                    /* z */
00239     0, 0, 0,                    /* { | } */
00240     0, 0                        /* ~ ‚ */
00241 };
00242 
00243 
00244 char myCsmodes[128] = {
00245     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00246     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00247 
00248     0,
00249     0,
00250     0, 0, 0,
00251     0,
00252     0, 0, 0, 0,
00253     0,
00254 
00255     'v', 0, 0, 0, 0,
00256     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00257 
00258     'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00259     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00260 
00261     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00262     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00263 };
00264 
00265 CMMode myCmmodes[128] = {
00266     {NULL}, {NULL}, {NULL},
00267     {NULL}, {NULL}, {NULL},
00268     {NULL}, {NULL}, {NULL},
00269     {NULL}, {NULL}, {NULL},
00270     {NULL}, {NULL}, {NULL},
00271     {NULL}, {NULL}, {NULL},
00272     {NULL}, {NULL}, {NULL},
00273     {NULL}, {NULL}, {NULL},
00274     {NULL}, {NULL}, {NULL},
00275     {NULL}, {NULL}, {NULL},
00276     {NULL}, {NULL}, {NULL},
00277     {NULL}, {NULL}, {NULL},
00278     {NULL}, {NULL}, {NULL},
00279     {NULL}, {NULL}, {NULL},
00280     {NULL}, {NULL}, {NULL},
00281     {NULL}, {NULL}, {NULL},
00282     {NULL}, {NULL}, {NULL},
00283     {NULL}, {NULL}, {NULL},
00284     {NULL}, {NULL}, {NULL},
00285     {NULL}, {NULL}, {NULL},
00286     {NULL}, {NULL}, {NULL},
00287     {NULL}, {NULL}, {NULL},
00288     {NULL}, {NULL}, {NULL},     /* BCD */
00289     {NULL}, {NULL}, {NULL},     /* EFG */
00290     {NULL},                     /* H */
00291     {add_invite, del_invite},
00292     {NULL},                     /* J */
00293     {NULL}, {NULL}, {NULL},     /* KLM */
00294     {NULL}, {NULL}, {NULL},     /* NOP */
00295     {NULL}, {NULL}, {NULL},     /* QRS */
00296     {NULL}, {NULL}, {NULL},     /* TUV */
00297     {NULL}, {NULL}, {NULL},     /* WXY */
00298     {NULL},                     /* Z */
00299     {NULL}, {NULL},             /* (char 91 - 92) */
00300     {NULL}, {NULL}, {NULL},     /* (char 93 - 95) */
00301     {NULL},                     /* ` (char 96) */
00302     {NULL},                     /* a (char 97) */
00303     {add_ban, del_ban},
00304     {NULL},
00305     {NULL},
00306     {add_exception, del_exception},
00307     {NULL},
00308     {NULL},
00309     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00310     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00311     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}
00312 };
00313 
00314 
00315 CBMode myCbmodes[128] = {
00316     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00317     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00318     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00319     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00320     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00321     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00322     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00323     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00324     {0},
00325     {0},                        /* A */
00326     {0},                        /* B */
00327     {0},                        /* C */
00328     {0},                        /* D */
00329     {0},                        /* E */
00330     {CMODE_F, 0, NULL, NULL},   /* F */
00331     {0},                        /* G */
00332     {0},                        /* H */
00333     {0},                        /* I */
00334     {0},                        /* J */
00335     {0},                        /* K */
00336     {CMODE_L, CBM_NO_USER_MLOCK, NULL, NULL},   /* L */
00337     {0},                        /* M */
00338     {0},                        /* N */
00339     {0},                        /* O */
00340     {CMODE_P, CBM_NO_USER_MLOCK, NULL, NULL},   /* P */
00341     {CMODE_Q, 0, NULL, NULL},   /* Q */
00342     {0},                        /* R */
00343     {0},                        /* S */
00344     {0},                        /* T */
00345     {0},                        /* U */
00346     {0},                        /* V */
00347     {0},                        /* W */
00348     {0},                        /* X */
00349     {0},                        /* Y */
00350     {0},                        /* Z */
00351     {0}, {0}, {0}, {0}, {0}, {0},
00352     {0},
00353     {0},                        /* b */
00354     {CMODE_c, 0, NULL, NULL},   /* c */
00355     {0},                        /* d */
00356     {0},                        /* e */
00357     {CMODE_f, 0, set_redirect, cs_set_redirect},  /* f */
00358     {CMODE_g, 0, NULL, NULL},   /* g */
00359     {0},                        /* h */
00360     {CMODE_i, 0, NULL, NULL},
00361     {CMODE_j, 0, set_flood, cs_set_flood},       /* j */
00362     {CMODE_k, 0, chan_set_key, cs_set_key},
00363     {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit},
00364     {CMODE_m, 0, NULL, NULL},
00365     {CMODE_n, 0, NULL, NULL},
00366     {0},                        /* o */
00367     {CMODE_p, 0, NULL, NULL},
00368     {0},                        /* q */
00369     {CMODE_r, 0, NULL, NULL},
00370     {CMODE_s, 0, NULL, NULL},
00371     {CMODE_t, 0, NULL, NULL},
00372     {0},
00373     {0},                        /* v */
00374     {0},                        /* w */
00375     {0},                        /* x */
00376     {0},                        /* y */
00377     {CMODE_z, 0, NULL, NULL},   /* z */
00378     {0}, {0}, {0}, {0}
00379 };
00380 
00381 CBModeInfo myCbmodeinfos[] = {
00382     {'c', CMODE_c, 0, NULL, NULL},
00383     {'f', CMODE_f, CBM_MINUS_NO_ARG, get_redirect, cs_get_redirect},
00384     {'g', CMODE_g, 0, NULL, NULL},
00385     {'i', CMODE_i, 0, NULL, NULL},
00386     {'j', CMODE_j, CBM_MINUS_NO_ARG, get_flood, cs_get_flood},
00387     {'k', CMODE_k, 0, get_key, cs_get_key},
00388     {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit},
00389     {'m', CMODE_m, 0, NULL, NULL},
00390     {'n', CMODE_n, 0, NULL, NULL},
00391     {'p', CMODE_p, 0, NULL, NULL},
00392     {'r', CMODE_r, 0, NULL, NULL},
00393     {'s', CMODE_s, 0, NULL, NULL},
00394     {'t', CMODE_t, 0, NULL, NULL},
00395     {'z', CMODE_z, 0, NULL, NULL},
00396     {'F', CMODE_F, 0, NULL, NULL},
00397     {'L', CMODE_L, 0, NULL, NULL},
00398     {'P', CMODE_P, 0, NULL, NULL},
00399     {'Q', CMODE_Q, 0, NULL, NULL},
00400     {0}
00401 };
00402 
00403 
00404 CUMode myCumodes[128] = {
00405     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00406     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00407     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00408     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00409 
00410     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00411     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00412     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00413     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00414 
00415     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00416     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00417     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00418     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00419 
00420     {0},
00421 
00422     {0},                        /* a */
00423     {0},                        /* b */
00424     {0},                        /* c */
00425     {0},                        /* d */
00426     {0},                        /* e */
00427     {0},                        /* f */
00428     {0},                        /* g */
00429     {0},
00430     {0},                        /* i */
00431     {0},                        /* j */
00432     {0},                        /* k */
00433     {0},                        /* l */
00434     {0},                        /* m */
00435     {0},                        /* n */
00436     {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op},
00437     {0},                        /* p */
00438     {0},                        /* q */
00439     {0},                        /* r */
00440     {0},                        /* s */
00441     {0},                        /* t */
00442     {0},                        /* u */
00443     {CUS_VOICE, 0, NULL},
00444     {0},                        /* w */
00445     {0},                        /* x */
00446     {0},                        /* y */
00447     {0},                        /* z */
00448     {0}, {0}, {0}, {0}, {0}
00449 };
00450 
00451 
00452 
00453 void charybdis_cmd_notice(char *source, char *dest, char *buf)
00454 {
00455     Uid *ud;
00456     User *u;
00457 
00458     if (!buf) {
00459         return;
00460     }
00461 
00462     if (NSDefFlags & NI_MSG) {
00463         charybdis_cmd_privmsg2(source, dest, buf);
00464     } else {
00465         ud = find_uid(source);
00466         u = finduser(dest);
00467         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source),
00468                  "NOTICE %s :%s", (UseTS6 ? (u ? u->uid : dest) : dest),
00469                  buf);
00470     }
00471 }
00472 
00473 void charybdis_cmd_notice2(char *source, char *dest, char *msg)
00474 {
00475     Uid *ud;
00476     User *u;
00477 
00478     ud = find_uid(source);
00479     u = finduser(dest);
00480     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "NOTICE %s :%s",
00481              (UseTS6 ? (u ? u->uid : dest) : dest), msg);
00482 }
00483 
00484 void charybdis_cmd_privmsg(char *source, char *dest, char *buf)
00485 {
00486     Uid *ud, *ud2;
00487 
00488     if (!buf) {
00489         return;
00490     }
00491     ud = find_uid(source);
00492     ud2 = find_uid(dest);
00493 
00494     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "PRIVMSG %s :%s",
00495              (UseTS6 ? (ud2 ? ud2->uid : dest) : dest), buf);
00496 }
00497 
00498 void charybdis_cmd_privmsg2(char *source, char *dest, char *msg)
00499 {
00500     Uid *ud, *ud2;
00501 
00502     ud = find_uid(source);
00503     ud2 = find_uid(dest);
00504 
00505     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "PRIVMSG %s :%s",
00506              (UseTS6 ? (ud2 ? ud2->uid : dest) : dest), msg);
00507 }
00508 
00509 void charybdis_cmd_serv_notice(char *source, char *dest, char *msg)
00510 {
00511     send_cmd(source, "NOTICE $$%s :%s", dest, msg);
00512 }
00513 
00514 void charybdis_cmd_serv_privmsg(char *source, char *dest, char *msg)
00515 {
00516     send_cmd(source, "PRIVMSG $$%s :%s", dest, msg);
00517 }
00518 
00519 
00520 void charybdis_cmd_global(char *source, char *buf)
00521 {
00522     Uid *u;
00523 
00524     if (!buf) {
00525         return;
00526     }
00527 
00528     if (source) {
00529         u = find_uid(source);
00530         if (u) {
00531             send_cmd((UseTS6 ? u->uid : source), "OPERWALL :%s", buf);
00532         } else {
00533             send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", buf);
00534         }
00535     } else {
00536         send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", buf);
00537     }
00538 }
00539 
00540 /* GLOBOPS - to handle old WALLOPS */
00541 void charybdis_cmd_global_legacy(char *source, char *fmt)
00542 {
00543     Uid *u;
00544 
00545     if (source) {
00546         u = find_uid(source);
00547         if (u) {
00548             send_cmd((UseTS6 ? u->uid : source), "OPERWALL :%s", fmt);
00549         } else {
00550             send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", fmt);
00551         }
00552     } else {
00553         send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", fmt);
00554     }
00555 
00556     send_cmd(source ? source : ServerName, "OPERWALL :%s", fmt);
00557 }
00558 
00559 int anope_event_sjoin(char *source, int ac, char **av)
00560 {
00561     do_sjoin(source, ac, av);
00562     return MOD_CONT;
00563 }
00564 
00565 /*
00566    Non TS6
00567 
00568    av[0] = nick
00569    av[1] = hop
00570    av[2] = ts
00571    av[3] = modes
00572    av[4] = user
00573    av[5] = host
00574    av[6] = server
00575    av[7] = info
00576 
00577    TS6
00578    av[0] = nick
00579    av[1] = hop
00580    av[2] = ts
00581    av[3] = modes
00582    av[4] = user
00583    av[5] = host
00584    av[6] = IP
00585    av[7] = UID
00586    av[8] = info
00587 
00588 */
00589 int anope_event_nick(char *source, int ac, char **av)
00590 {
00591     Server *s;
00592     User *user;
00593 
00594     if (UseTS6 && ac == 9) {
00595         s = findserver_uid(servlist, source);
00596         /* Source is always the server */
00597         *source = '\0';
00598         user = do_nick(source, av[0], av[4], av[5], s->name, av[8],
00599                        strtoul(av[2], NULL, 10), 0, 0, NULL, av[7]);
00600         if (user) {
00601             anope_set_umode(user, 1, &av[3]);
00602         }
00603     } else {
00604         if (ac != 2) {
00605             user = do_nick(source, av[0], av[4], av[5], av[6], av[7],
00606                            strtoul(av[2], NULL, 10), 0, 0, NULL, NULL);
00607             if (user)
00608                 anope_set_umode(user, 1, &av[3]);
00609         } else {
00610             do_nick(source, av[0], NULL, NULL, NULL, NULL,
00611                     strtoul(av[1], NULL, 10), 0, 0, NULL, NULL);
00612         }
00613     }
00614     return MOD_CONT;
00615 }
00616 
00617 /*
00618    TS6
00619    av[0] = nick
00620    av[1] = hop
00621    av[2] = ts
00622    av[3] = modes
00623    av[4] = user
00624    av[5] = vhost
00625    av[6] = IP
00626    av[7] = UID
00627    ac[8] = host or *
00628    ac[9] = services login
00629    av[10] = info
00630 
00631 */
00632 int anope_event_euid(char *source, int ac, char **av)
00633 {
00634     Server *s;
00635     User *user;
00636     time_t ts;
00637 
00638     if (UseTS6 && ac == 11) {
00639         s = findserver_uid(servlist, source);
00640         /* Source is always the server */
00641         *source = '\0';
00642     ts = strtoul(av[2], NULL, 10);
00643         user = do_nick(source, av[0], av[4], !strcmp(av[8], "*") ? av[5] : av[8], s->name, av[10],
00644                        ts, !stricmp(av[0], av[9]) ? ts : 0, 0, av[5], av[7]);
00645         if (user) {
00646             anope_set_umode(user, 1, &av[3]);
00647         }
00648     }
00649     return MOD_CONT;
00650 }
00651 
00652 int anope_event_topic(char *source, int ac, char **av)
00653 {
00654     User *u;
00655 
00656     if (ac == 4) {
00657         do_topic(source, ac, av);
00658     } else {
00659         Channel *c = findchan(av[0]);
00660         time_t topic_time = time(NULL);
00661 
00662         if (!c) {
00663             if (debug) {
00664                 alog("debug: TOPIC %s for nonexistent channel %s",
00665                      merge_args(ac - 1, av + 1), av[0]);
00666             }
00667             return MOD_CONT;
00668         }
00669 
00670         if (check_topiclock(c, topic_time))
00671             return MOD_CONT;
00672 
00673         if (c->topic) {
00674             free(c->topic);
00675             c->topic = NULL;
00676         }
00677         if (ac > 1 && *av[1])
00678             c->topic = sstrdup(av[1]);
00679 
00680         if (UseTS6) {
00681             u = find_byuid(source);
00682             if (u) {
00683                 strscpy(c->topic_setter, u->nick, sizeof(c->topic_setter));
00684             } else {
00685                 strscpy(c->topic_setter, source, sizeof(c->topic_setter));
00686             }
00687         } else {
00688             strscpy(c->topic_setter, source, sizeof(c->topic_setter));
00689         }
00690         c->topic_time = topic_time;
00691 
00692         record_topic(av[0]);
00693         
00694         if (ac > 1 && *av[1])
00695             send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[1]);
00696         else
00697             send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
00698     }
00699     return MOD_CONT;
00700 }
00701 
00702 int anope_event_tburst(char *source, int ac, char **av)
00703 {
00704     char *setter;
00705     Channel *c;
00706     time_t topic_time;
00707 
00708     if (ac != 4) {
00709         return MOD_CONT;
00710     }
00711 
00712     setter = myStrGetToken(av[2], '!', 0);
00713 
00714     c = findchan(av[0]);
00715     topic_time = strtol(av[1], NULL, 10);
00716 
00717     if (!c) {
00718         if (debug) {
00719             alog("debug: TOPIC %s for nonexistent channel %s",
00720                  merge_args(ac - 1, av + 1), av[0]);
00721         }
00722         if (setter)
00723             free(setter);
00724         return MOD_CONT;
00725     }
00726 
00727     if (check_topiclock(c, topic_time)) {
00728         if (setter)
00729             free(setter);
00730         return MOD_CONT;
00731     }
00732 
00733     if (c->topic) {
00734         free(c->topic);
00735         c->topic = NULL;
00736     }
00737     if (ac > 1 && *av[3])
00738         c->topic = sstrdup(av[3]);
00739 
00740     strscpy(c->topic_setter, setter, sizeof(c->topic_setter));
00741     c->topic_time = topic_time;
00742 
00743     record_topic(av[0]);
00744     
00745     if (ac > 1 && *av[3])
00746         send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[3]);
00747     else
00748         send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
00749             
00750     if (setter)
00751         free(setter);
00752     
00753     return MOD_CONT;
00754 }
00755 
00756 int anope_event_436(char *source, int ac, char **av)
00757 {
00758     if (ac < 1)
00759         return MOD_CONT;
00760 
00761     m_nickcoll(av[0]);
00762     return MOD_CONT;
00763 }
00764 
00765 
00766 /* *INDENT-OFF* */
00767 void moduleAddIRCDMsgs(void) 
00768 {
00769     Message *m;
00770     
00771     updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+","-");
00772 
00773     if (UseTS6) {
00774         TS6SID = sstrdup(Numeric);
00775     }
00776 
00777     m = createMessage("401",       anope_event_null); addCoreMessage(IRCD,m);
00778     m = createMessage("402",       anope_event_null); addCoreMessage(IRCD,m);
00779     m = createMessage("436",       anope_event_436); addCoreMessage(IRCD,m);
00780     m = createMessage("AWAY",      anope_event_away); addCoreMessage(IRCD,m);
00781     m = createMessage("INVITE",    anope_event_invite); addCoreMessage(IRCD,m);
00782     m = createMessage("JOIN",      anope_event_join); addCoreMessage(IRCD,m);
00783     m = createMessage("KICK",      anope_event_kick); addCoreMessage(IRCD,m);
00784     m = createMessage("KILL",      anope_event_kill); addCoreMessage(IRCD,m);
00785     m = createMessage("MODE",      anope_event_mode); addCoreMessage(IRCD,m);
00786     m = createMessage("TMODE",     anope_event_tmode); addCoreMessage(IRCD,m);
00787     m = createMessage("MOTD",      anope_event_motd); addCoreMessage(IRCD,m);
00788     m = createMessage("NICK",      anope_event_nick); addCoreMessage(IRCD,m);
00789     m = createMessage("BMASK",     anope_event_bmask); addCoreMessage(IRCD,m);
00790     m = createMessage("UID",       anope_event_nick); addCoreMessage(IRCD,m);
00791     m = createMessage("NOTICE",    anope_event_notice); addCoreMessage(IRCD,m);
00792     m = createMessage("PART",      anope_event_part); addCoreMessage(IRCD,m);
00793     m = createMessage("PASS",      anope_event_pass); addCoreMessage(IRCD,m);
00794     m = createMessage("PING",      anope_event_ping); addCoreMessage(IRCD,m);
00795     m = createMessage("PRIVMSG",   anope_event_privmsg); addCoreMessage(IRCD,m);
00796     m = createMessage("QUIT",      anope_event_quit); addCoreMessage(IRCD,m);
00797     m = createMessage("SERVER",    anope_event_server); addCoreMessage(IRCD,m);
00798     m = createMessage("SQUIT",     anope_event_squit); addCoreMessage(IRCD,m);
00799     m = createMessage("TOPIC",     anope_event_topic); addCoreMessage(IRCD,m);
00800     m = createMessage("TB",        anope_event_tburst); addCoreMessage(IRCD,m);
00801     m = createMessage("USER",      anope_event_null); addCoreMessage(IRCD,m);
00802     m = createMessage("WALLOPS",   anope_event_null); addCoreMessage(IRCD,m);
00803     m = createMessage("WHOIS",     anope_event_whois); addCoreMessage(IRCD,m);
00804     m = createMessage("SVSMODE",   anope_event_null); addCoreMessage(IRCD,m);
00805     m = createMessage("SVSNICK",   anope_event_null); addCoreMessage(IRCD,m);
00806     m = createMessage("CAPAB",     anope_event_capab); addCoreMessage(IRCD,m);
00807     m = createMessage("SJOIN",     anope_event_sjoin); addCoreMessage(IRCD,m);
00808     m = createMessage("SVINFO",    anope_event_svinfo); addCoreMessage(IRCD,m);
00809     m = createMessage("ADMIN",     anope_event_admin); addCoreMessage(IRCD,m);
00810     m = createMessage("ERROR",     anope_event_error); addCoreMessage(IRCD,m);
00811     m = createMessage("421",       anope_event_null); addCoreMessage(IRCD,m);
00812     m = createMessage("ENCAP",     anope_event_null); addCoreMessage(IRCD,m);    
00813     m = createMessage("SID",       anope_event_sid); addCoreMessage(IRCD,m);
00814     m = createMessage("EUID",      anope_event_euid); addCoreMessage(IRCD,m);
00815 }
00816 
00817 /* *INDENT-ON* */
00818 
00819 
00820 void charybdis_cmd_sqline(char *mask, char *reason)
00821 {
00822     Uid *ud;
00823 
00824     ud = find_uid(s_OperServ);
00825     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00826              "RESV * %s :%s", mask, reason);
00827 }
00828 
00829 void charybdis_cmd_unsgline(char *mask)
00830 {
00831     Uid *ud;
00832 
00833     ud = find_uid(s_OperServ);
00834     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00835              "UNXLINE * %s", mask);
00836 }
00837 
00838 void charybdis_cmd_unszline(char *mask)
00839 {
00840     /* not supported */
00841 }
00842 
00843 void charybdis_cmd_szline(char *mask, char *reason, char *whom)
00844 {
00845     /* not supported */
00846 }
00847 
00848 void charybdis_cmd_svsnoop(char *server, int set)
00849 {
00850     /* does not support */
00851 }
00852 
00853 void charybdis_cmd_svsadmin(char *server, int set)
00854 {
00855     charybdis_cmd_svsnoop(server, set);
00856 }
00857 
00858 void charybdis_cmd_sgline(char *mask, char *reason)
00859 {
00860     Uid *ud;
00861 
00862     ud = find_uid(s_OperServ);
00863     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00864              "XLINE * %s 0 :%s", mask, reason);
00865 }
00866 
00867 void charybdis_cmd_remove_akill(char *user, char *host)
00868 {
00869     Uid *ud;
00870 
00871     ud = find_uid(s_OperServ);
00872     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00873              "UNKLINE * %s %s", user, host);
00874 }
00875 
00876 void charybdis_cmd_topic(char *whosets, char *chan, char *whosetit,
00877                       char *topic, time_t when)
00878 {
00879     Uid *ud;
00880 
00881     ud = find_uid(whosets);
00882     send_cmd((UseTS6 ? (ud ? ud->uid : whosets) : whosets), "TOPIC %s :%s",
00883              chan, topic);
00884 }
00885 
00886 void charybdis_cmd_vhost_off(User * u)
00887 {
00888     send_cmd((UseTS6 ? TS6SID : ServerName), "ENCAP * CHGHOST %s :%s",
00889              u->nick, u->host);
00890 }
00891 
00892 void charybdis_cmd_vhost_on(char *nick, char *vIdent, char *vhost)
00893 {
00894     send_cmd((UseTS6 ? TS6SID : ServerName), "ENCAP * CHGHOST %s :%s",
00895              nick, vhost);
00896 }
00897 
00898 void charybdis_cmd_unsqline(char *user)
00899 {
00900     Uid *ud;
00901 
00902     ud = find_uid(s_OperServ);
00903     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00904              "UNRESV * %s", user);
00905 }
00906 
00907 void charybdis_cmd_join(char *user, char *channel, time_t chantime)
00908 {
00909     Uid *ud;
00910 
00911     ud = find_uid(user);
00912     send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) chantime,
00913              channel, (UseTS6 ? (ud ? ud->uid : user) : user));
00914 }
00915 
00916 /*
00917 oper:       the nick of the oper performing the kline
00918 target.server:  the server(s) this kline is destined for
00919 duration:   the duration if a tkline, 0 if permanent.
00920 user:       the 'user' portion of the kline
00921 host:       the 'host' portion of the kline
00922 reason:     the reason for the kline.
00923 */
00924 
00925 void charybdis_cmd_akill(char *user, char *host, char *who, time_t when,
00926                       time_t expires, char *reason)
00927 {
00928     Uid *ud;
00929 
00930     ud = find_uid(s_OperServ);
00931 
00932     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00933              "KLINE * %ld %s %s :%s",
00934              (long int) (expires - (long) time(NULL)), user, host, reason);
00935 }
00936 
00937 void charybdis_cmd_svskill(char *source, char *user, char *buf)
00938 {
00939     Uid *ud, *ud2;
00940 
00941     if (!buf) {
00942         return;
00943     }
00944 
00945     if (!source || !user) {
00946         return;
00947     }
00948 
00949     ud = find_uid(source);
00950     ud2 = find_uid(user);
00951     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "KILL %s :%s",
00952              (UseTS6 ? (ud2 ? ud2->uid : user) : user), buf);
00953 }
00954 
00955 void charybdis_cmd_svsmode(User * u, int ac, char **av)
00956 {
00957     send_cmd((UseTS6 ? TS6SID : ServerName), "SVSMODE %s %s", u->nick,
00958              av[0]);
00959 }
00960 
00961 /*
00962  * SVINFO
00963  *      parv[0] = sender prefix
00964  *      parv[1] = TS_CURRENT for the server
00965  *      parv[2] = TS_MIN for the server
00966  *      parv[3] = server is standalone or connected to non-TS only
00967  *      parv[4] = server's idea of UTC time
00968  */
00969 void charybdis_cmd_svinfo()
00970 {
00971     send_cmd(NULL, "SVINFO 6 3 0 :%ld", (long int) time(NULL));
00972 }
00973 
00974 void charybdis_cmd_svsinfo()
00975 {
00976 
00977 }
00978 
00979 /* CAPAB */
00980 /*
00981   QS       - Can handle quit storm removal
00982   EX       - Can do channel +e exemptions 
00983   CHW      - Can do channel wall @#
00984   LL       - Can do lazy links 
00985   IE       - Can do invite exceptions 
00986   EOB      - Can do EOB message
00987   KLN      - Can do KLINE message 
00988   GLN      - Can do GLINE message 
00989   HUB      - This server is a HUB 
00990   UID      - Can do UIDs
00991   ZIP      - Can do ZIPlinks
00992   ENC      - Can do ENCrypted links 
00993   KNOCK    - supports KNOCK 
00994   TBURST   - supports TBURST
00995   PARA     - supports invite broadcasting for +p
00996   ENCAP    - supports message encapsulation
00997   SERVICES - supports services-oriented TS6 extensions
00998   EUID     - supports EUID and non-ENCAP CHGHOST
00999 */
01000 void charybdis_cmd_capab()
01001 {
01002     send_cmd(NULL,
01003              "CAPAB :QS EX CHW IE KLN GLN KNOCK TB UNKLN CLUSTER ENCAP SERVICES EUID");
01004 }
01005 
01006 /* PASS */
01007 void charybdis_cmd_pass(char *pass)
01008 {
01009     if (UseTS6) {
01010         send_cmd(NULL, "PASS %s TS 6 :%s", pass, TS6SID);
01011     } else {
01012         send_cmd(NULL, "PASS %s :TS", pass);
01013     }
01014 }
01015 
01016 /* SERVER name hop descript */
01017 void charybdis_cmd_server(char *servname, int hop, char *descript)
01018 {
01019     send_cmd(NULL, "SERVER %s %d :%s", servname, hop, descript);
01020 }
01021 
01022 void charybdis_cmd_connect(int servernum)
01023 {
01024     /* Make myself known to myself in the serverlist */
01025     if (UseTS6) {
01026         me_server =
01027             new_server(NULL, ServerName, ServerDesc, SERVER_ISME, TS6SID);
01028     } else {
01029         me_server =
01030             new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL);
01031     }
01032     if (servernum == 1)
01033         charybdis_cmd_pass(RemotePassword);
01034     else if (servernum == 2)
01035         charybdis_cmd_pass(RemotePassword2);
01036     else if