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-2013 Anope Team
00005  * Contact us at team@anope.org
00006  *
00007  * Please read COPYING and README for further 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 #include "version.h"
00017 
00018 IRCDVar myIrcd[] = {
00019     {"Charybdis 1.0+",           /* ircd name */
00020      "+oiS",                     /* nickserv mode */
00021      "+oiS",                     /* chanserv mode */
00022      "+oiS",                     /* memoserv mode */
00023      "+oiS",                     /* hostserv mode */
00024      "+oaiS",                    /* operserv mode */
00025      "+oiS",                     /* botserv mode  */
00026      "+oiS",                     /* helpserv mode */
00027      "+oiS",                     /* Dev/Null mode */
00028      "+oiS",                     /* Global mode   */
00029      "+oiS",                     /* nickserv alias mode */
00030      "+oiS",                     /* chanserv alias mode */
00031      "+oiS",                     /* memoserv alias mode */
00032      "+oiS",                     /* hostserv alias mode */
00033      "+oaiS",                    /* operserv alias mode */
00034      "+oiS",                     /* botserv alias mode  */
00035      "+oiS",                     /* helpserv alias mode */
00036      "+oiS",                     /* Dev/Null alias mode */
00037      "+oiS",                     /* Global alias mode   */
00038      "+oiS",                     /* Used by BotServ Bots */
00039      2,                         /* Chan Max Symbols     */
00040      "-cijlmnpstrgzQF",         /* Modes to Remove */
00041      "+o",                      /* Channel Umode used by Botserv bots */
00042      1,                         /* SVSNICK */
00043      1,                         /* Vhost  */
00044      0,                         /* Has Owner */
00045      NULL,                      /* Mode to set for an owner */
00046      NULL,                      /* Mode to unset for an owner */
00047      NULL,                      /* Mode to set for chan admin */
00048      NULL,                      /* Mode to unset for chan admin */
00049      NULL,                      /* Mode On Reg          */
00050      NULL,                      /* Mode on ID for Roots */
00051      NULL,                      /* Mode on ID for Admins */
00052      NULL,                      /* Mode on ID for Opers */
00053      NULL,                      /* Mode on UnReg        */
00054      NULL,                      /* Mode on Nick Change  */
00055      1,                         /* Supports SGlines     */
00056      1,                         /* Supports SQlines     */
00057      1,                         /* Supports SZlines     */
00058      0,                         /* Supports Halfop +h   */
00059      3,                         /* Number of server args */
00060      1,                         /* Join 2 Set           */
00061      1,                         /* Join 2 Message       */
00062      1,                         /* Has exceptions +e    */
00063      0,                         /* TS Topic Forward     */
00064      0,                         /* TS Topci Backward    */
00065      0,                         /* Protected Umode      */
00066      0,                         /* Has Admin            */
00067      1,                         /* Chan SQlines         */
00068      0,                         /* Quit on Kill         */
00069      0,                         /* SVSMODE unban        */
00070      0,                         /* Has Protect          */
00071      0,                         /* Reverse              */
00072      0,                         /* Chan Reg             */
00073      0,                         /* Channel Mode         */
00074      0,                         /* vidents              */
00075      1,                         /* svshold              */
00076      0,                         /* time stamp on mode   */
00077      0,                         /* NICKIP               */
00078      0,                         /* UMODE                */
00079      0,                         /* O:LINE               */
00080      1,                         /* VHOST ON NICK        */
00081      0,                         /* Change RealName      */
00082      CMODE_p,                   /* No Knock             */
00083      0,                         /* Admin Only           */
00084      DEFAULT_MLOCK,             /* Default MLOCK        */
00085      0,                         /* Vhost Mode           */
00086      1,                         /* +f                   */
00087      1,                         /* +L                   */
00088      CMODE_j,                   /* +f Mode                          */
00089      CMODE_f,                   /* +L Mode (+f <target>)            */
00090      1,                         /* On nick change check if they could be identified */
00091      0,                         /* No Knock requires +i */
00092      NULL,                      /* CAPAB Chan Modes             */
00093      0,                         /* We support TOKENS */
00094      1,                         /* TOKENS are CASE inSensitive */
00095      0,                         /* TIME STAMPS are BASE64 */
00096      1,                         /* +I support */
00097      0,                         /* SJOIN ban char */
00098      0,                         /* SJOIN except char */
00099      0,                         /* SJOIN invite char */
00100      0,                         /* Can remove User Channel Modes with SVSMODE */
00101      0,                         /* Sglines are not enforced until user reconnects */
00102      NULL,                      /* vhost char */
00103      1,                         /* ts6 */
00104      0,                         /* support helper umode */
00105      0,                         /* p10 */
00106      NULL,                      /* character set */
00107      0,                         /* reports sync state */
00108      1,                         /* CIDR channelbans */
00109      0,                         /* +j */
00110      0,                         /* +j Mode */
00111      0,                         /* Use delayed client introduction. */
00112      }
00113     ,
00114     {NULL}
00115 };
00116 
00117 IRCDCAPAB myIrcdcap[] = {
00118     {
00119      0,                         /* NOQUIT       */
00120      0,                         /* TSMODE       */
00121      0,                         /* UNCONNECT    */
00122      0,                         /* NICKIP       */
00123      0,                         /* SJOIN        */
00124      CAPAB_ZIP,                 /* ZIP          */
00125      0,                         /* BURST        */
00126      CAPAB_TS5,                 /* TS5          */
00127      0,                         /* TS3          */
00128      0,                         /* DKEY         */
00129      0,                         /* PT4          */
00130      0,                         /* SCS          */
00131      CAPAB_QS,                  /* QS           */
00132      CAPAB_UID,                 /* UID          */
00133      CAPAB_KNOCK,               /* KNOCK        */
00134      0,                         /* CLIENT       */
00135      0,                         /* IPV6         */
00136      0,                         /* SSJ5         */
00137      0,                         /* SN2          */
00138      0,                         /* TOKEN        */
00139      0,                         /* VHOST        */
00140      0,                         /* SSJ3         */
00141      0,                         /* NICK2        */
00142      0,                         /* UMODE2       */
00143      0,                         /* VL           */
00144      0,                         /* TLKEXT       */
00145      0,                         /* DODKEY       */
00146      0,                         /* DOZIP        */
00147      0, 0, 0}
00148 };
00149 
00150 /*******************************************************************/
00151 
00152 void charybdis_set_umode(User * user, int ac, char **av)
00153 {
00154     int add = 1;                /* 1 if adding modes, 0 if deleting */
00155     char *modes = av[0];
00156 
00157     ac--;
00158 
00159     if (debug)
00160         alog("debug: Changing mode for %s to %s", user->nick, modes);
00161 
00162     while (*modes) {
00163 
00164         /* This looks better, much better than "add ? (do_add) : (do_remove)".
00165          * At least this is readable without paying much attention :) -GD
00166          */
00167         if (add)
00168             user->mode |= umodes[(int) *modes];
00169         else
00170             user->mode &= ~umodes[(int) *modes];
00171 
00172         switch (*modes++) {
00173         case '+':
00174             add = 1;
00175             break;
00176         case '-':
00177             add = 0;
00178             break;
00179         case 'o':
00180             if (add) {
00181                 opcnt++;
00182 
00183                 if (WallOper)
00184                     anope_cmd_global(s_OperServ,
00185                                      "\2%s\2 is now an IRC operator.",
00186                                      user->nick);
00187                 display_news(user, NEWS_OPER);
00188 
00189             } else {
00190                 opcnt--;
00191             }
00192             break;
00193         }
00194     }
00195 }
00196 
00197 unsigned long umodes[128] = {
00198     0, 0, 0,                    /* Unused */
00199     0, 0, 0,                    /* Unused */
00200     0, 0, 0,                    /* Unused, Unused, Horzontal Tab */
00201     0, 0, 0,                    /* Line Feed, Unused, Unused */
00202     0, 0, 0,                    /* Carriage Return, Unused, Unused */
00203     0, 0, 0,                    /* Unused */
00204     0, 0, 0,                    /* Unused */
00205     0, 0, 0,                    /* Unused */
00206     0, 0, 0,                    /* Unused */
00207     0, 0, 0,                    /* Unused */
00208     0, 0, 0,                    /* Unused, Unused, Space */
00209     0, 0, 0,                    /* ! " #  */
00210     0, 0, 0,                    /* $ % &  */
00211     0, 0, 0,                    /* ! ( )  */
00212     0, 0, 0,                    /* * + ,  */
00213     0, 0, 0,                    /* - . /  */
00214     0, 0,                       /* 0 1 */
00215     0, 0,                       /* 2 3 */
00216     0, 0,                       /* 4 5 */
00217     0, 0,                       /* 6 7 */
00218     0, 0,                       /* 8 9 */
00219     0, 0,                       /* : ; */
00220     0, 0, 0,                    /* < = > */
00221     0, 0,                       /* ? @ */
00222     0, 0, 0,                    /* A B C */
00223     0, 0, 0,                    /* D E F */
00224     0, 0, 0,                    /* G H I */
00225     0, 0, 0,                    /* J K L */
00226     0, 0, 0,                    /* M N O */
00227     0, UMODE_Q, UMODE_R,        /* P Q R */
00228     UMODE_S, 0, 0,              /* S T U */
00229     0, 0, 0,                    /* V W X */
00230     0,                          /* Y */
00231     0,                          /* Z */
00232     0, 0, 0,                    /* [ \ ] */
00233     0, 0, 0,                    /* ^ _ ` */
00234     UMODE_a, 0, 0,              /* a b c */
00235     0, 0, 0,                    /* d e f */
00236     UMODE_g, 0, UMODE_i,        /* g h i */
00237     0, 0, UMODE_l,              /* j k l */
00238     0, 0, UMODE_o,              /* m n o */
00239     0, 0, 0,                    /* p q r */
00240     UMODE_s, 0, 0,              /* s t u */
00241     0, UMODE_w, 0,              /* v w x */
00242     0,                          /* y */
00243     UMODE_z,                    /* z */
00244     0, 0, 0,                    /* { | } */
00245     0, 0                        /* ~ � */
00246 };
00247 
00248 
00249 char myCsmodes[128] = {
00250     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00251     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00252 
00253     0,
00254     0,
00255     0, 0, 0,
00256     0,
00257     0, 0, 0, 0,
00258     0,
00259 
00260     'v', 0, 0, 0, 0,
00261     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00262 
00263     'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00264     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00265 
00266     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00267     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00268 };
00269 
00270 CMMode myCmmodes[128] = {
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},
00289     {NULL}, {NULL}, {NULL},
00290     {NULL}, {NULL}, {NULL},
00291     {NULL}, {NULL}, {NULL},
00292     {NULL}, {NULL}, {NULL},
00293     {NULL}, {NULL}, {NULL},     /* BCD */
00294     {NULL}, {NULL}, {NULL},     /* EFG */
00295     {NULL},                     /* H */
00296     {add_invite, del_invite},
00297     {NULL},                     /* J */
00298     {NULL}, {NULL}, {NULL},     /* KLM */
00299     {NULL}, {NULL}, {NULL},     /* NOP */
00300     {NULL}, {NULL}, {NULL},     /* QRS */
00301     {NULL}, {NULL}, {NULL},     /* TUV */
00302     {NULL}, {NULL}, {NULL},     /* WXY */
00303     {NULL},                     /* Z */
00304     {NULL}, {NULL},             /* (char 91 - 92) */
00305     {NULL}, {NULL}, {NULL},     /* (char 93 - 95) */
00306     {NULL},                     /* ` (char 96) */
00307     {NULL},                     /* a (char 97) */
00308     {add_ban, del_ban},
00309     {NULL},
00310     {NULL},
00311     {add_exception, del_exception},
00312     {NULL},
00313     {NULL},
00314     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00315     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00316     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}
00317 };
00318 
00319 
00320 CBMode myCbmodes[128] = {
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}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00325     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00326     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00327     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00328     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00329     {0},
00330     {0},                        /* A */
00331     {0},                        /* B */
00332     {0},                        /* C */
00333     {0},                        /* D */
00334     {0},                        /* E */
00335     {CMODE_F, 0, NULL, NULL},   /* F */
00336     {0},                        /* G */
00337     {0},                        /* H */
00338     {0},                        /* I */
00339     {0},                        /* J */
00340     {0},                        /* K */
00341     {CMODE_L, CBM_NO_USER_MLOCK, NULL, NULL},   /* L */
00342     {0},                        /* M */
00343     {0},                        /* N */
00344     {0},                        /* O */
00345     {CMODE_P, CBM_NO_USER_MLOCK, NULL, NULL},   /* P */
00346     {CMODE_Q, 0, NULL, NULL},   /* Q */
00347     {0},                        /* R */
00348     {0},                        /* S */
00349     {0},                        /* T */
00350     {0},                        /* U */
00351     {0},                        /* V */
00352     {0},                        /* W */
00353     {0},                        /* X */
00354     {0},                        /* Y */
00355     {0},                        /* Z */
00356     {0}, {0}, {0}, {0}, {0}, {0},
00357     {0},
00358     {0},                        /* b */
00359     {CMODE_c, 0, NULL, NULL},   /* c */
00360     {0},                        /* d */
00361     {0},                        /* e */
00362     {CMODE_f, 0, set_redirect, cs_set_redirect},  /* f */
00363     {CMODE_g, 0, NULL, NULL},   /* g */
00364     {0},                        /* h */
00365     {CMODE_i, 0, NULL, NULL},
00366     {CMODE_j, 0, set_flood, cs_set_flood},       /* j */
00367     {CMODE_k, 0, chan_set_key, cs_set_key},
00368     {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit},
00369     {CMODE_m, 0, NULL, NULL},
00370     {CMODE_n, 0, NULL, NULL},
00371     {0},                        /* o */
00372     {CMODE_p, 0, NULL, NULL},
00373     {0},                        /* q */
00374     {CMODE_r, 0, NULL, NULL},
00375     {CMODE_s, 0, NULL, NULL},
00376     {CMODE_t, 0, NULL, NULL},
00377     {0},
00378     {0},                        /* v */
00379     {0},                        /* w */
00380     {0},                        /* x */
00381     {0},                        /* y */
00382     {CMODE_z, 0, NULL, NULL},   /* z */
00383     {0}, {0}, {0}, {0}
00384 };
00385 
00386 CBModeInfo myCbmodeinfos[] = {
00387     {'c', CMODE_c, 0, NULL, NULL},
00388     {'f', CMODE_f, CBM_MINUS_NO_ARG, get_redirect, cs_get_redirect},
00389     {'g', CMODE_g, 0, NULL, NULL},
00390     {'i', CMODE_i, 0, NULL, NULL},
00391     {'j', CMODE_j, CBM_MINUS_NO_ARG, get_flood, cs_get_flood},
00392     {'k', CMODE_k, 0, get_key, cs_get_key},
00393     {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit},
00394     {'m', CMODE_m, 0, NULL, NULL},
00395     {'n', CMODE_n, 0, NULL, NULL},
00396     {'p', CMODE_p, 0, NULL, NULL},
00397     {'r', CMODE_r, 0, NULL, NULL},
00398     {'s', CMODE_s, 0, NULL, NULL},
00399     {'t', CMODE_t, 0, NULL, NULL},
00400     {'z', CMODE_z, 0, NULL, NULL},
00401     {'F', CMODE_F, 0, NULL, NULL},
00402     {'L', CMODE_L, 0, NULL, NULL},
00403     {'P', CMODE_P, 0, NULL, NULL},
00404     {'Q', CMODE_Q, 0, NULL, NULL},
00405     {0}
00406 };
00407 
00408 
00409 CUMode myCumodes[128] = {
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}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00421     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00422     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00423     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00424 
00425     {0},
00426 
00427     {0},                        /* a */
00428     {0},                        /* b */
00429     {0},                        /* c */
00430     {0},                        /* d */
00431     {0},                        /* e */
00432     {0},                        /* f */
00433     {0},                        /* g */
00434     {0},
00435     {0},                        /* i */
00436     {0},                        /* j */
00437     {0},                        /* k */
00438     {0},                        /* l */
00439     {0},                        /* m */
00440     {0},                        /* n */
00441     {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op},
00442     {0},                        /* p */
00443     {0},                        /* q */
00444     {0},                        /* r */
00445     {0},                        /* s */
00446     {0},                        /* t */
00447     {0},                        /* u */
00448     {CUS_VOICE, 0, NULL},
00449     {0},                        /* w */
00450     {0},                        /* x */
00451     {0},                        /* y */
00452     {0},                        /* z */
00453     {0}, {0}, {0}, {0}, {0}
00454 };
00455 
00456 
00457 
00458 void charybdis_cmd_notice(char *source, char *dest, char *buf)
00459 {
00460     Uid *ud;
00461     User *u;
00462 
00463     if (!buf) {
00464         return;
00465     }
00466 
00467     if (NSDefFlags & NI_MSG) {
00468         charybdis_cmd_privmsg2(source, dest, buf);
00469     } else {
00470         ud = find_uid(source);
00471         u = finduser(dest);
00472         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source),
00473                  "NOTICE %s :%s", (UseTS6 ? (u ? u->uid : dest) : dest),
00474                  buf);
00475     }
00476 }
00477 
00478 void charybdis_cmd_notice2(char *source, char *dest, char *msg)
00479 {
00480     Uid *ud;
00481     User *u;
00482 
00483     ud = find_uid(source);
00484     u = finduser(dest);
00485     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "NOTICE %s :%s",
00486              (UseTS6 ? (u ? u->uid : dest) : dest), msg);
00487 }
00488 
00489 void charybdis_cmd_privmsg(char *source, char *dest, char *buf)
00490 {
00491     Uid *ud, *ud2;
00492 
00493     if (!buf) {
00494         return;
00495     }
00496     ud = find_uid(source);
00497     ud2 = find_uid(dest);
00498 
00499     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "PRIVMSG %s :%s",
00500              (UseTS6 ? (ud2 ? ud2->uid : dest) : dest), buf);
00501 }
00502 
00503 void charybdis_cmd_privmsg2(char *source, char *dest, char *msg)
00504 {
00505     Uid *ud, *ud2;
00506 
00507     ud = find_uid(source);
00508     ud2 = find_uid(dest);
00509 
00510     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "PRIVMSG %s :%s",
00511              (UseTS6 ? (ud2 ? ud2->uid : dest) : dest), msg);
00512 }
00513 
00514 void charybdis_cmd_serv_notice(char *source, char *dest, char *msg)
00515 {
00516     send_cmd(source, "NOTICE $$%s :%s", dest, msg);
00517 }
00518 
00519 void charybdis_cmd_serv_privmsg(char *source, char *dest, char *msg)
00520 {
00521     send_cmd(source, "PRIVMSG $$%s :%s", dest, msg);
00522 }
00523 
00524 
00525 void charybdis_cmd_global(char *source, char *buf)
00526 {
00527     Uid *u;
00528 
00529     if (!buf) {
00530         return;
00531     }
00532 
00533     if (source) {
00534         u = find_uid(source);
00535         if (u) {
00536             send_cmd((UseTS6 ? u->uid : source), "OPERWALL :%s", buf);
00537         } else {
00538             send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", buf);
00539         }
00540     } else {
00541         send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", buf);
00542     }
00543 }
00544 
00545 /* GLOBOPS - to handle old WALLOPS */
00546 void charybdis_cmd_global_legacy(char *source, char *fmt)
00547 {
00548     Uid *u;
00549 
00550     if (source) {
00551         u = find_uid(source);
00552         if (u) {
00553             send_cmd((UseTS6 ? u->uid : source), "OPERWALL :%s", fmt);
00554         } else {
00555             send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", fmt);
00556         }
00557     } else {
00558         send_cmd((UseTS6 ? TS6SID : ServerName), "WALLOPS :%s", fmt);
00559     }
00560 
00561     send_cmd(source ? source : ServerName, "OPERWALL :%s", fmt);
00562 }
00563 
00564 int anope_event_sjoin(char *source, int ac, char **av)
00565 {
00566     do_sjoin(source, ac, av);
00567     return MOD_CONT;
00568 }
00569 
00570 /*
00571    Non TS6
00572 
00573    av[0] = nick
00574    av[1] = hop
00575    av[2] = ts
00576    av[3] = modes
00577    av[4] = user
00578    av[5] = host
00579    av[6] = server
00580    av[7] = info
00581 
00582    TS6
00583    av[0] = nick
00584    av[1] = hop
00585    av[2] = ts
00586    av[3] = modes
00587    av[4] = user
00588    av[5] = host
00589    av[6] = IP
00590    av[7] = UID
00591    av[8] = info
00592 
00593 */
00594 int anope_event_nick(char *source, int ac, char **av)
00595 {
00596     Server *s;
00597     User *user;
00598 
00599     if (UseTS6 && ac == 9) {
00600         s = findserver_uid(servlist, source);
00601         /* Source is always the server */
00602         *source = '\0';
00603         user = do_nick(source, av[0], av[4], av[5], s->name, av[8],
00604                        strtoul(av[2], NULL, 10), 0, 0, NULL, av[7]);
00605         if (user) {
00606             anope_set_umode(user, 1, &av[3]);
00607         }
00608     } else {
00609         if (ac != 2) {
00610             user = do_nick(source, av[0], av[4], av[5], av[6], av[7],
00611                            strtoul(av[2], NULL, 10), 0, 0, NULL, NULL);
00612             if (user)
00613                 anope_set_umode(user, 1, &av[3]);
00614         } else {
00615             do_nick(source, av[0], NULL, NULL, NULL, NULL,
00616                     strtoul(av[1], NULL, 10), 0, 0, NULL, NULL);
00617         }
00618     }
00619     return MOD_CONT;
00620 }
00621 
00622 /*
00623    TS6
00624    av[0] = nick
00625    av[1] = hop
00626    av[2] = ts
00627    av[3] = modes
00628    av[4] = user
00629    av[5] = vhost
00630    av[6] = IP
00631    av[7] = UID
00632    ac[8] = host or *
00633    ac[9] = services login
00634    av[10] = info
00635 
00636 */
00637 int anope_event_euid(char *source, int ac, char **av)
00638 {
00639     Server *s;
00640     User *user;
00641     time_t ts;
00642 
00643     if (UseTS6 && ac == 11) {
00644         s = findserver_uid(servlist, source);
00645         /* Source is always the server */
00646         *source = '\0';
00647         ts = strtoul(av[2], NULL, 10);
00648         user = do_nick(source, av[0], av[4], !strcmp(av[8], "*") ? av[5] : av[8], s->name, av[10],
00649                        ts, !stricmp(av[0], av[9]) ? ts : 0, 0, av[5], av[7]);
00650         if (user) {
00651             anope_set_umode(user, 1, &av[3]);
00652         }
00653     }
00654     return MOD_CONT;
00655 }
00656 
00657 int anope_event_topic(char *source, int ac, char **av)
00658 {
00659     User *u;
00660 
00661     if (ac == 4) {
00662         do_topic(source, ac, av);
00663     } else {
00664         Channel *c = findchan(av[0]);
00665         time_t topic_time = time(NULL);
00666 
00667         if (!c) {
00668             if (debug) {
00669                 alog("debug: TOPIC %s for nonexistent channel %s",
00670                      merge_args(ac - 1, av + 1), av[0]);
00671             }
00672             return MOD_CONT;
00673         }
00674 
00675         if (check_topiclock(c, topic_time))
00676             return MOD_CONT;
00677 
00678         if (c->topic) {
00679             free(c->topic);
00680             c->topic = NULL;
00681         }
00682         if (ac > 1 && *av[1])
00683             c->topic = sstrdup(av[1]);
00684 
00685         if (UseTS6) {
00686             u = find_byuid(source);
00687             if (u) {
00688                 strscpy(c->topic_setter, u->nick, sizeof(c->topic_setter));
00689             } else {
00690                 strscpy(c->topic_setter, source, sizeof(c->topic_setter));
00691             }
00692         } else {
00693             strscpy(c->topic_setter, source, sizeof(c->topic_setter));
00694         }
00695         c->topic_time = topic_time;
00696 
00697         record_topic(av[0]);
00698                 
00699                 if (ac > 1 && *av[1])
00700                     send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[1]);
00701                 else
00702                     send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
00703     }
00704     return MOD_CONT;
00705 }
00706 
00707 int anope_event_tburst(char *source, int ac, char **av)
00708 {
00709     char *setter;
00710     Channel *c;
00711     time_t topic_time;
00712 
00713     if (ac != 4) {
00714         return MOD_CONT;
00715     }
00716 
00717     setter = myStrGetToken(av[2], '!', 0);
00718 
00719     c = findchan(av[0]);
00720     topic_time = strtol(av[1], NULL, 10);
00721 
00722     if (!c) {
00723         if (debug) {
00724             alog("debug: TOPIC %s for nonexistent channel %s",
00725                  merge_args(ac - 1, av + 1), av[0]);
00726         }
00727         if (setter)
00728             free(setter);
00729         return MOD_CONT;
00730     }
00731 
00732     if (check_topiclock(c, topic_time)) {
00733         if (setter)
00734             free(setter);
00735         return MOD_CONT;
00736     }
00737 
00738     if (c->topic) {
00739         free(c->topic);
00740         c->topic = NULL;
00741     }
00742     if (ac > 1 && *av[3])
00743         c->topic = sstrdup(av[3]);
00744 
00745     strscpy(c->topic_setter, setter, sizeof(c->topic_setter));
00746     c->topic_time = topic_time;
00747 
00748     record_topic(av[0]);
00749 
00750         if (ac > 1 && *av[3])
00751             send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[3]);
00752         else
00753             send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
00754 
00755     if (setter)
00756         free(setter);
00757 
00758     return MOD_CONT;
00759 }
00760 
00761 int anope_event_436(char *source, int ac, char **av)
00762 {
00763     if (ac < 1)
00764         return MOD_CONT;
00765 
00766     m_nickcoll(av[0]);
00767     return MOD_CONT;
00768 }
00769 
00770 
00771 /* *INDENT-OFF* */
00772 void moduleAddIRCDMsgs(void) 
00773 {
00774     Message *m;
00775     
00776     updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+","-");
00777 
00778     if (UseTS6) {
00779         TS6SID = sstrdup(Numeric);
00780     }
00781 
00782     m = createMessage("401",       anope_event_null); addCoreMessage(IRCD,m);
00783     m = createMessage("402",       anope_event_null); addCoreMessage(IRCD,m);
00784     m = createMessage("436",       anope_event_436); addCoreMessage(IRCD,m);
00785     m = createMessage("AWAY",      anope_event_away); addCoreMessage(IRCD,m);
00786     m = createMessage("INVITE",    anope_event_invite); addCoreMessage(IRCD,m);
00787     m = createMessage("JOIN",      anope_event_join); addCoreMessage(IRCD,m);
00788     m = createMessage("KICK",      anope_event_kick); addCoreMessage(IRCD,m);
00789     m = createMessage("KILL",      anope_event_kill); addCoreMessage(IRCD,m);
00790     m = createMessage("MODE",      anope_event_mode); addCoreMessage(IRCD,m);
00791     m = createMessage("TMODE",     anope_event_tmode); addCoreMessage(IRCD,m);
00792     m = createMessage("MOTD",      anope_event_motd); addCoreMessage(IRCD,m);
00793     m = createMessage("NICK",      anope_event_nick); addCoreMessage(IRCD,m);
00794     m = createMessage("BMASK",     anope_event_bmask); addCoreMessage(IRCD,m);
00795     m = createMessage("UID",       anope_event_nick); addCoreMessage(IRCD,m);
00796     m = createMessage("NOTICE",    anope_event_notice); addCoreMessage(IRCD,m);
00797     m = createMessage("PART",      anope_event_part); addCoreMessage(IRCD,m);
00798     m = createMessage("PASS",      anope_event_pass); addCoreMessage(IRCD,m);
00799     m = createMessage("PING",      anope_event_ping); addCoreMessage(IRCD,m);
00800     m = createMessage("PRIVMSG",   anope_event_privmsg); addCoreMessage(IRCD,m);
00801     m = createMessage("QUIT",      anope_event_quit); addCoreMessage(IRCD,m);
00802     m = createMessage("SERVER",    anope_event_server); addCoreMessage(IRCD,m);
00803     m = createMessage("SQUIT",     anope_event_squit); addCoreMessage(IRCD,m);
00804     m = createMessage("TOPIC",     anope_event_topic); addCoreMessage(IRCD,m);
00805     m = createMessage("TB",        anope_event_tburst); addCoreMessage(IRCD,m);
00806     m = createMessage("USER",      anope_event_null); addCoreMessage(IRCD,m);
00807     m = createMessage("WALLOPS",   anope_event_null); addCoreMessage(IRCD,m);
00808     m = createMessage("WHOIS",     anope_event_whois); addCoreMessage(IRCD,m);
00809     m = createMessage("SVSMODE",   anope_event_null); addCoreMessage(IRCD,m);
00810     m = createMessage("SVSNICK",   anope_event_null); addCoreMessage(IRCD,m);
00811     m = createMessage("CAPAB",     anope_event_capab); addCoreMessage(IRCD,m);
00812     m = createMessage("SJOIN",     anope_event_sjoin); addCoreMessage(IRCD,m);
00813     m = createMessage("SVINFO",    anope_event_svinfo); addCoreMessage(IRCD,m);
00814     m = createMessage("ADMIN",     anope_event_admin); addCoreMessage(IRCD,m);
00815     m = createMessage("ERROR",     anope_event_error); addCoreMessage(IRCD,m);
00816     m = createMessage("421",       anope_event_null); addCoreMessage(IRCD,m);
00817     m = createMessage("ENCAP",     anope_event_null); addCoreMessage(IRCD,m);    
00818     m = createMessage("SID",       anope_event_sid); addCoreMessage(IRCD,m);
00819     m = createMessage("EUID",      anope_event_euid); addCoreMessage(IRCD,m);
00820 }
00821 
00822 /* *INDENT-ON* */
00823 
00824 
00825 void charybdis_cmd_sqline(char *mask, char *reason)
00826 {
00827     Uid *ud;
00828 
00829     ud = find_uid(s_OperServ);
00830     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00831              "RESV * %s :%s", mask, reason);
00832 }
00833 
00834 void charybdis_cmd_unsgline(char *mask)
00835 {
00836     Uid *ud;
00837 
00838     ud = find_uid(s_OperServ);
00839     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00840              "UNXLINE * %s", mask);
00841 }
00842 
00843 void charybdis_cmd_unszline(char *mask)
00844 {
00845     /* not supported */
00846 }
00847 
00848 void charybdis_cmd_szline(char *mask, char *reason, char *whom)
00849 {
00850     /* not supported */
00851 }
00852 
00853 void charybdis_cmd_svsnoop(char *server, int set)
00854 {
00855     /* does not support */
00856 }
00857 
00858 void charybdis_cmd_svsadmin(char *server, int set)
00859 {
00860     charybdis_cmd_svsnoop(server, set);
00861 }
00862 
00863 void charybdis_cmd_sgline(char *mask, char *reason)
00864 {
00865     Uid *ud;
00866 
00867     ud = find_uid(s_OperServ);
00868     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00869              "XLINE * %s 0 :%s", mask, reason);
00870 }
00871 
00872 void charybdis_cmd_remove_akill(char *user, char *host)
00873 {
00874     Uid *ud;
00875 
00876     if (!user || !*user || !host || !*host)
00877         return;
00878 
00879     ud = find_uid(s_OperServ);
00880     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00881              "UNKLINE * %s %s", user, host);
00882 }
00883 
00884 void charybdis_cmd_topic(char *whosets, char *chan, char *whosetit,
00885                       char *topic, time_t when)
00886 {
00887     Uid *ud;
00888 
00889     ud = find_uid(whosets);
00890     send_cmd((UseTS6 ? (ud ? ud->uid : whosets) : whosets), "TOPIC %s :%s",
00891              chan, topic);
00892 }
00893 
00894 void charybdis_cmd_vhost_off(User * u)
00895 {
00896     send_cmd((UseTS6 ? TS6SID : ServerName), "ENCAP * CHGHOST %s :%s",
00897              u->nick, u->host);
00898 }
00899 
00900 void charybdis_cmd_vhost_on(char *nick, char *vIdent, char *vhost)
00901 {
00902     send_cmd((UseTS6 ? TS6SID : ServerName), "ENCAP * CHGHOST %s :%s",
00903              nick, vhost);
00904 }
00905 
00906 void charybdis_cmd_unsqline(char *user)
00907 {
00908     Uid *ud;
00909 
00910     ud = find_uid(s_OperServ);
00911     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00912              "UNRESV * %s", user);
00913 }
00914 
00915 void charybdis_cmd_join(char *user, char *channel, time_t chantime)
00916 {
00917     Uid *ud;
00918 
00919     ud = find_uid(user);
00920     send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) chantime,
00921              channel, (UseTS6 ? (ud ? ud->uid : user) : user));
00922 }
00923 
00924 /*
00925 oper:           the nick of the oper performing the kline
00926 target.server:  the server(s) this kline is destined for
00927 duration:       the duration if a tkline, 0 if permanent.
00928 user:           the 'user' portion of the kline
00929 host:           the 'host' portion of the kline
00930 reason:         the reason for the kline.
00931 */
00932 
00933 void charybdis_cmd_akill(char *user, char *host, char *who, time_t when,
00934                       time_t expires, char *reason)
00935 {
00936     Uid *ud;
00937 
00938     ud = find_uid(s_OperServ);
00939 
00940     send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
00941              "KLINE * %ld %s %s :%s",
00942              (long int) (expires - (long) time(NULL)), user, host, reason);
00943 }
00944 
00945 void charybdis_cmd_svskill(char *source, char *user, char *buf)
00946 {
00947     Uid *ud, *ud2;
00948 
00949     if (!buf) {
00950         return;
00951     }
00952 
00953     if (!source || !user) {
00954         return;
00955     }
00956 
00957     ud = find_uid(source);
00958     ud2 = find_uid(user);
00959     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "KILL %s :%s",
00960              (UseTS6 ? (ud2 ? ud2->uid : user) : user), buf);
00961 }
00962 
00963 void charybdis_cmd_svsmode(User * u, int ac, char **av)
00964 {
00965     send_cmd((UseTS6 ? TS6SID : ServerName), "SVSMODE %s %s", u->nick,
00966              av[0]);
00967 }
00968 
00969 /*
00970  * SVINFO
00971  *      parv[0] = sender prefix
00972  *      parv[1] = TS_CURRENT for the server
00973  *      parv[2] = TS_MIN for the server
00974  *      parv[3] = server is standalone or connected to non-TS only
00975  *      parv[4] = server's idea of UTC time
00976  */
00977 void charybdis_cmd_svinfo()
00978 {
00979     send_cmd(NULL, "SVINFO 6 3 0 :%ld", (long int) time(NULL));
00980 }
00981 
00982 void charybdis_cmd_svsinfo()
00983 {
00984 
00985 }
00986 
00987 /* CAPAB */
00988 /*
00989   QS       - Can handle quit storm removal
00990   EX       - Can do channel +e exemptions 
00991   CHW      - Can do channel wall @#
00992   LL       - Can do lazy links 
00993   IE       - Can do invite exceptions 
00994   EOB      - Can do EOB message
00995   KLN      - Can do KLINE message 
00996   GLN      - Can do GLINE message 
00997   HUB      - This server is a HUB 
00998   UID      - Can do UIDs
00999   ZIP      - Can do ZIPlinks
01000   ENC      - Can do ENCrypted links 
01001   KNOCK    - supports KNOCK 
01002   TBURST   - supports TBURST
01003   PARA     - supports invite broadcasting for +p
01004   ENCAP    - supports message encapsulation
01005   SERVICES - supports services-oriented TS6 extensions
01006   EUID     - supports EUID and non-ENCAP CHGHOST
01007 */
01008 void charybdis_cmd_capab()
01009 {
01010     send_cmd(NULL,
01011              "CAPAB :QS EX CHW IE KLN GLN KNOCK TB UNKLN CLUSTER ENCAP SERVICES EUID");
01012 }
01013 
01014 /* PASS */
01015 void charybdis_cmd_pass(char *pass)
01016 {
01017     if (UseTS6) {
01018         send_cmd(NULL, "PASS %s TS 6 :%s", pass, TS6SID);
01019     } else {
01020         send_cmd(NULL, "PASS %s :TS", pass);
01021     }
01022 }
01023 
01024 /* SERVER name hop descript */
01025 void charybdis_cmd_server(char *servname, int hop, char *descript)
01026 {
01027     send_cmd(NULL, "SERVER %s %d :%s", servname, hop, descript);
01028 }
01029 
01030 void charybdis_cmd_connect(int servernum)
01031 {
01032     /* Make myself known to myself in the serverlist */
01033     if (UseTS6) {
01034         me_server =
01035             new_server(NULL, ServerName, ServerDesc, SERVER_ISME, TS6SID);
01036     } else {
01037         me_server =
01038             new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL);
01039     }
01040     if (servernum == 1)
01041         charybdis_cmd_pass(RemotePassword);
01042     else if (servernum == 2)
01043         charybdis_cmd_pass(RemotePassword2);
01044     else if (servernum == 3)
01045         charybdis_cmd_pass(RemotePassword3);
01046 
01047     charybdis_cmd_capab();
01048     charybdis_cmd_server(ServerName, 1, ServerDesc);
01049     charybdis_cmd_svinfo();
01050 }
01051 
01052 void charybdis_cmd_bob()
01053 {
01054     /* Not used */
01055 }
01056 
01057 void charybdis_cmd_bot_nick(char *nick, char *user, char *host, char *real,
01058                          char *modes)
01059 {
01060     EnforceQlinedNick(nick, NULL);
01061     if (UseTS6) {
01062         char *uidbuf = ts6_uid_retrieve();
01063         send_cmd(TS6SID, "UID %s 1 %ld %s %s %s 0 %s :%s", nick,
01064                  (long int) time(NULL), modes, user, host, uidbuf,
01065                  real);
01066         new_uid(nick, uidbuf);
01067     } else {
01068         send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s :%s", nick,
01069                  (long int) time(NULL), modes, user, host, ServerName,
01070                  real);
01071     }
01072     charybdis_cmd_sqline(nick, "Reserved for services");
01073 }
01074 
01075 void charybdis_cmd_part(char *nick, char *chan, char *buf)
01076 {
01077     Uid *ud;
01078 
01079     ud = find_uid(nick);
01080 
01081     if (buf) {
01082         send_cmd((UseTS6 ? ud->uid : nick), "PART %s :%s", chan, buf);
01083     } else {
01084         send_cmd((UseTS6 ? ud->uid : nick), "PART %s", chan);
01085     }
01086 }
01087 
01088 int anope_event_ping(char *source, int ac, char **av)
01089 {
01090     if (ac < 1)
01091         return MOD_CONT;
01092     charybdis_cmd_pong(ac > 1 ? av[1] : ServerName, av[0]);
01093     return MOD_CONT;
01094 }
01095 
01096 int anope_event_away(char *source, int ac, char **av)
01097 {
01098     User *u = NULL;
01099 
01100     if (UseTS6) {
01101         u = find_byuid(source);
01102     }
01103 
01104     m_away((UseTS6 ? (u ? u->nick : source) : source),
01105            (ac ? av[0] : NULL));
01106     return MOD_CONT;
01107 }
01108 
01109 int anope_event_kill(char *source, int ac, char **av)
01110 {
01111     User *u = NULL;
01112     Uid *ud = NULL;
01113 
01114     if (ac != 2)
01115         return MOD_CONT;
01116 
01117     if (UseTS6) {
01118         u = find_byuid(av[0]);
01119         ud = find_nickuid(av[0]);
01120     }
01121 
01122     m_kill(u ? u->nick : (ud ? ud->nick : av[0]), av[1]);
01123     return MOD_CONT;
01124 }
01125 
01126 int anope_event_kick(char *source, int ac, char **av)
01127 {
01128     if (ac != 3)
01129         return MOD_CONT;
01130     do_kick(source, ac, av);
01131     return MOD_CONT;
01132 }
01133 
01134 void charybdis_cmd_eob()
01135 {
01136     /* doesn't support EOB */
01137 }
01138 
01139 int anope_event_join(char *source, int ac, char **av)
01140 {
01141     if (ac != 1) {
01142         /* ignore cmodes in JOIN as per TS6 v8 */
01143         do_sjoin(source, ac > 2 ? 2 : ac, av);
01144         return MOD_CONT;
01145     } else {
01146         do_join(source, ac, av);
01147     }
01148     return MOD_CONT;
01149 }
01150 
01151 int anope_event_motd(char *source, int ac, char **av)
01152 {
01153     if (!source) {
01154         return MOD_CONT;
01155     }
01156 
01157     m_motd(source);
01158     return MOD_CONT;
01159 }
01160 
01161 int anope_event_privmsg(char *source, int ac, char **av)
01162 {
01163     User *u;
01164     Uid *ud;
01165 
01166     if (ac != 2) {
01167         return MOD_CONT;
01168     }
01169 
01170     u = find_byuid(source);
01171     ud = find_nickuid(av[0]);
01172     m_privmsg((UseTS6 ? (u ? u->nick : source) : source),
01173               (UseTS6 ? (ud ? ud->nick : av[0]) : av[0]), av[1]);
01174     return MOD_CONT;
01175 }
01176 
01177 int anope_event_part(char *source, int ac, char **av)
01178 {
01179     User *u;
01180 
01181     if (ac < 1 || ac > 2) {
01182         return MOD_CONT;
01183     }
01184 
01185     u = find_byuid(source);
01186     do_part((UseTS6 ? (u ? u->nick : source) : source), ac, av);
01187 
01188     return MOD_CONT;
01189 }
01190 
01191 int anope_event_whois(char *source, int ac, char **av)
01192 {
01193     Uid *ud;
01194 
01195     if (source && ac >= 1) {
01196         ud = find_nickuid(av[0]);
01197         m_whois(source, (UseTS6 ? (ud ? ud->nick : av[0]) : av[0]));
01198     }
01199     return MOD_CONT;
01200 }
01201 
01202 /* EVENT: SERVER */
01203 int anope_event_server(char *source, int ac, char **av)
01204 {
01205     if (!stricmp(av[1], "1")) {
01206         uplink = sstrdup(av[0]);
01207         if (UseTS6 && TS6UPLINK) {
01208             do_server(source, av[0], av[1], av[2], TS6UPLINK);
01209         } else {
01210             do_server(source, av[0], av[1], av[2], NULL);
01211         }
01212     } else {
01213         do_server(source, av[0], av[1], av[2], NULL);
01214     }
01215     return MOD_CONT;
01216 }
01217 
01218 int anope_event_sid(char *source, int ac, char **av)
01219 {
01220     Server *s;
01221 
01222     /* :42X SID trystan.nomadirc.net 2 43X :ircd-charybdis test server */
01223 
01224     s = findserver_uid(servlist, source);
01225 
01226     do_server(s->name, av[0], av[1], av[3], av[2]);
01227     return MOD_CONT;
01228 }
01229 
01230 int anope_event_squit(char *source, int ac, char **av)
01231 {
01232     if (ac != 2)
01233         return MOD_CONT;
01234     do_squit(source, ac, av);
01235     return MOD_CONT;
01236 }
01237 
01238 int anope_event_quit(char *source, int ac, char **av)
01239 {
01240     User *u;
01241 
01242     if (ac != 1) {
01243         return MOD_CONT;
01244     }
01245 
01246     u = find_byuid(source);
01247 
01248     do_quit((UseTS6 ? (u ? u->nick : source) : source), ac, av);
01249     return MOD_CONT;
01250 }
01251 
01252 void charybdis_cmd_372(char *source, char *msg)
01253 {
01254     send_cmd((UseTS6 ? TS6SID : ServerName), "372 %s :- %s", source, msg);
01255 }
01256 
01257 void charybdis_cmd_372_error(char *source)
01258 {
01259     send_cmd((UseTS6 ? TS6SID : ServerName),
01260              "422 %s :- MOTD file not found!  Please "
01261              "contact your IRC administrator.", source);
01262 }
01263 
01264 void charybdis_cmd_375(char *source)
01265 {
01266     send_cmd((UseTS6 ? TS6SID : ServerName),
01267              "375 %s :- %s Message of the Day", source, ServerName);
01268 }
01269 
01270 void charybdis_cmd_376(char *source)
01271 {
01272     send_cmd((UseTS6 ? TS6SID : ServerName),
01273              "376 %s :End of /MOTD command.", source);
01274 }
01275 
01276 /* 391 */
01277 void charybdis_cmd_391(char *source, char *timestr)
01278 {
01279     if (!timestr) {
01280         return;
01281     }
01282     send_cmd(NULL, "391 :%s %s :%s", source, ServerName, timestr);
01283 }
01284 
01285 /* 250 */
01286 void charybdis_cmd_250(char *buf)
01287 {
01288     if (!buf) {
01289         return;
01290     }
01291 
01292     send_cmd(NULL, "250 %s", buf);
01293 }
01294 
01295 /* 307 */
01296 void charybdis_cmd_307(char *buf)
01297 {
01298     if (!buf) {
01299         return;
01300     }
01301 
01302     send_cmd((UseTS6 ? TS6SID : ServerName), "307 %s", buf);
01303 }
01304 
01305 /* 311 */
01306 void charybdis_cmd_311(char *buf)
01307 {
01308     if (!buf) {
01309         return;
01310     }
01311 
01312     send_cmd((UseTS6 ? TS6SID : ServerName), "311 %s", buf);
01313 }
01314 
01315 /* 312 */
01316 void charybdis_cmd_312(char *buf)
01317 {
01318     if (!buf) {
01319         return;
01320     }
01321 
01322     send_cmd((UseTS6 ? TS6SID : ServerName), "312 %s", buf);
01323 }
01324 
01325 /* 317 */
01326 void charybdis_cmd_317(char *buf)
01327 {
01328     if (!buf) {
01329         return;
01330     }
01331 
01332     send_cmd((UseTS6 ? TS6SID : ServerName), "317 %s", buf);
01333 }
01334 
01335 /* 219 */
01336 void charybdis_cmd_219(char *source, char *letter)
01337 {
01338     if (!source) {
01339         return;
01340     }
01341 
01342     if (letter) {
01343         send_cmd(NULL, "219 %s %c :End of /STATS report.", source,
01344                  *letter);
01345     } else {
01346         send_cmd(NULL, "219 %s l :End of /STATS report.", source);
01347     }
01348 }
01349 
01350 /* 401 */
01351 void charybdis_cmd_401(char *source, char *who)
01352 {
01353     if (!source || !who) {
01354         return;
01355     }
01356     send_cmd((UseTS6 ? TS6SID : ServerName), "401 %s %s :No such service.",
01357              source, who);
01358 }
01359 
01360 /* 318 */
01361 void charybdis_cmd_318(char *source, char *who)
01362 {
01363     if (!source || !who) {
01364         return;
01365     }
01366 
01367     send_cmd((UseTS6 ? TS6SID : ServerName),
01368              "318 %s %s :End of /WHOIS list.", source, who);
01369 }
01370 
01371 /* 242 */
01372 void charybdis_cmd_242(char *buf)
01373 {
01374     if (!buf) {
01375         return;
01376     }
01377 
01378     send_cmd(NULL, "242 %s", buf);
01379 }
01380 
01381 /* 243 */
01382 void charybdis_cmd_243(char *buf)
01383 {
01384     if (!buf) {
01385         return;
01386     }
01387 
01388     send_cmd(NULL, "243 %s", buf);
01389 }
01390 
01391 /* 211 */
01392 void charybdis_cmd_211(char *buf)
01393 {
01394     if (!buf) {
01395         return;
01396     }
01397 
01398     send_cmd(NULL, "211 %s", buf);
01399 }
01400 
01401 void charybdis_cmd_mode(char *source, char *dest, char *buf)
01402 {
01403     Uid *ud;
01404     if (!buf) {
01405         return;
01406     }
01407 
01408     if (source) {
01409         ud = find_uid(source);
01410         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "MODE %s %s",
01411                  dest, buf);
01412     } else {
01413         send_cmd(NULL, "MODE %s %s", dest, buf);
01414     }
01415 }
01416 
01417 void charybdis_cmd_tmode(char *source, char *dest, const char *fmt, ...)
01418 {
01419     va_list args;
01420     char buf[BUFSIZE];
01421     *buf = '\0';
01422 
01423     if (fmt) {
01424         va_start(args, fmt);
01425         vsnprintf(buf, BUFSIZE - 1, fmt, args);
01426         va_end(args);
01427     }
01428     if (!*buf) {
01429         return;
01430     }
01431 
01432     send_cmd(NULL, "MODE %s %s", dest, buf);
01433 }
01434 
01435 void charybdis_cmd_nick(char *nick, char *name, char *mode)
01436 {
01437     EnforceQlinedNick(nick, NULL);
01438     if (UseTS6) {
01439         char *uidbuf = ts6_uid_retrieve();
01440         send_cmd(TS6SID, "UID %s 1 %ld %s %s %s 0 %s :%s", nick,
01441                  (long int) time(NULL), mode, ServiceUser, ServiceHost,
01442                  uidbuf, name);
01443         new_uid(nick, uidbuf);
01444     } else {
01445         send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s :%s", nick,
01446                  (long int) time(NULL), mode, ServiceUser, ServiceHost,
01447                  ServerName, name);
01448     }
01449     charybdis_cmd_sqline(nick, "Reserved for services");
01450 }
01451 
01452 void charybdis_cmd_kick(char *source, char *chan, char *user, char *buf)
01453 {
01454     Uid *ud;
01455     User *u;
01456 
01457     ud = find_uid(source);
01458     u = finduser(user);
01459 
01460     if (buf) {
01461         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source),
01462                  "KICK %s %s :%s", chan,
01463                  (UseTS6 ? (u ? u->uid : user) : user), buf);
01464     } else {
01465         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "KICK %s %s",
01466                  chan, (UseTS6 ? (u ? u->uid : user) : user));
01467     }
01468 }
01469 
01470 void charybdis_cmd_notice_ops(char *source, char *dest, char *buf)
01471 {
01472     Uid *ud;
01473     ud = find_uid(source);
01474 
01475     if (!buf) {
01476         return;
01477     }
01478 
01479     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "NOTICE @%s :%s", dest, buf);
01480 }
01481 
01482 void charybdis_cmd_bot_chan_mode(char *nick, char *chan)
01483 {
01484     Uid *u;
01485 
01486     if (UseTS6) {
01487         u = find_uid(nick);
01488         charybdis_cmd_tmode(nick, chan, "%s %s", ircd->botchanumode,
01489                          (u ? u->uid : nick));
01490     } else {
01491         anope_cmd_mode(ServerName, chan, "%s %s", ircd->botchanumode, nick);
01492     }
01493 }
01494 
01495 /* QUIT */
01496 void charybdis_cmd_quit(char *source, char *buf)
01497 {
01498     Uid *ud;
01499     ud = find_uid(source);
01500 
01501     if (buf) {
01502         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "QUIT :%s",
01503                  buf);
01504     } else {
01505         send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "QUIT");
01506     }
01507 }
01508 
01509 /* PONG */
01510 void charybdis_cmd_pong(char *servname, char *who)
01511 {
01512     if (UseTS6) {
01513         /* deliberately no SID in the first parameter -- jilles */
01514         send_cmd(TS6SID, "PONG %s :%s", servname, who);
01515     } else {
01516         send_cmd(servname, "PONG %s :%s", servname, who);
01517     }
01518 }
01519 
01520 /* INVITE */
01521 void charybdis_cmd_invite(char *source, char *chan, char *nick)
01522 {
01523     Uid *ud;
01524     User *u;
01525 
01526     if (!source || !chan || !nick) {
01527         return;
01528     }
01529 
01530     ud = find_uid(source);
01531     u = finduser(nick);
01532 
01533     send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "INVITE %s %s",
01534              (UseTS6 ? (u ? u->uid : nick) : nick), chan);
01535 }
01536 
01537 /* SQUIT */
01538 void charybdis_cmd_squit(char *servname, char *message)
01539 {
01540     if (!servname || !message) {
01541         return;
01542     }
01543 
01544     send_cmd(NULL, "SQUIT %s :%s", servname, message);
01545 }
01546 
01547 int anope_event_mode(char *source, int ac, char **av)
01548 {
01549     User *u, *u2;
01550 
01551     if (ac < 2) {
01552         return MOD_CONT;
01553     }
01554 
01555     if (*av[0] == '#' || *av[0] == '&') {
01556         do_cmode(source, ac, av);
01557     } else {
01558         if (UseTS6) {
01559             u = find_byuid(source);
01560             u2 = find_byuid(av[0]);
01561             av[0] = u2->nick;
01562             do_umode(u->nick, ac, av);
01563         } else {
01564             do_umode(source, ac, av);
01565         }
01566     }
01567     return MOD_CONT;
01568 }
01569 
01570 int anope_event_tmode(char *source, int ac, char **av)
01571 {
01572     if (ac > 2 && (*av[1] == '#' || *av[1] == '&')) {
01573         do_cmode(source, ac, av);
01574     }
01575     return MOD_CONT;
01576 }
01577 
01578 void charybdis_cmd_351(char *source)
01579 {
01580     send_cmd((UseTS6 ? TS6SID : ServerName),
01581              "351 %s Anope-%s %s :%s - %s (%s) -- %s", source, version_number,
01582              ServerName, ircd->name, version_flags, EncModule, version_build);
01583 }
01584 
01585 /* Event: PROTOCTL */
01586 int anope_event_capab(char *source, int ac, char **av)
01587 {
01588     int argvsize = 8;
01589     int argc;
01590     char **argv;
01591     char *str;
01592 
01593     if (ac < 1)
01594         return MOD_CONT;
01595 
01596     /* We get the params as one arg, we should split it for capab_parse */
01597     argv = scalloc(argvsize, sizeof(char *));
01598     argc = 0;
01599     while ((str = myStrGetToken(av[0], ' ', argc))) {
01600         if (argc == argvsize) {
01601             argvsize += 8;
01602             argv = srealloc(argv, argvsize * sizeof(char *));
01603         }
01604         argv[argc] = str;
01605         argc++;
01606     }
01607 
01608     capab_parse(argc, argv);
01609 
01610     /* Free our built ac/av */
01611     for (argvsize = 0; argvsize < argc; argvsize++) {
01612         free(argv[argvsize]);
01613     }
01614     free(argv);
01615 
01616     return MOD_CONT;
01617 }
01618 
01619 /* SVSHOLD - set */
01620 void charybdis_cmd_svshold(char *nick)
01621 {
01622     send_cmd(NULL, "ENCAP * NICKDELAY 300 %s", nick);
01623 }
01624 
01625 /* SVSHOLD - release */
01626 void charybdis_cmd_release_svshold(char *nick)
01627 {
01628     send_cmd(NULL, "ENCAP * NICKDELAY 0 %s", nick);
01629 }
01630 
01631 /* SVSNICK */
01632 void charybdis_cmd_svsnick(char *nick, char *newnick, time_t when)
01633 {
01634     User *u;
01635 
01636     if (!nick || !newnick) {
01637         return;
01638     }
01639 
01640     u = finduser(nick);
01641     if (!u)
01642         return;
01643     send_cmd(NULL, "ENCAP %s RSFNC %s %s %ld %ld", u->server->name,
01644              u->nick, newnick, (long int)when, (long int)u->timestamp);
01645 }
01646 
01647 void charybdis_cmd_guest_nick(char *nick, char *user, char *host, char *real,
01648                            char *modes)
01649 {
01650     /* not supported  */
01651 }
01652 
01653 void charybdis_cmd_svso(char *source, char *nick, char *flag)
01654 {
01655     /* Not Supported by this IRCD */
01656 }
01657 
01658 void charybdis_cmd_unban(char *name, char *nick)
01659 {
01660     /* Not Supported by this IRCD */
01661 }
01662 
01663 /* SVSMODE channel modes */
01664 
01665 void charybdis_cmd_svsmode_chan(char *name, char *mode, char *nick)
01666 {
01667     /* Not Supported by this IRCD */
01668 }
01669 
01670 /* SVSMODE +d */
01671 /* sent if svid is something weird */
01672 void charybdis_cmd_svid_umode(char *nick, time_t ts)
01673 {
01674     /* not supported */
01675 }
01676 
01677 /* SVSMODE +d */
01678 /* nc_change was = 1, and there is no na->status */
01679 void charybdis_cmd_nc_change(User * u)
01680 {
01681     /* not supported */
01682 }
01683 
01684 /* SVSMODE +d */
01685 void charybdis_cmd_svid_umode2(User * u, char *ts)
01686 {
01687     /* not supported */
01688 }
01689 
01690 void charybdis_cmd_svid_umode3(User * u, char *ts)
01691 {
01692     /* not used */
01693 }
01694 
01695 /* NICK <newnick>  */
01696 void charybdis_cmd_chg_nick(char *oldnick, char *newnick)
01697 {
01698     Uid *ud;
01699 
01700     if (!oldnick || !newnick) {
01701         return;
01702     }
01703 
01704     ud = find_uid(oldnick);
01705     if (ud)
01706         strscpy(ud->nick, newnick, NICKMAX);
01707 
01708     send_cmd(oldnick, "NICK %s", newnick);
01709 }
01710 
01711 /*
01712  * SVINFO
01713  *      parv[0] = sender prefix
01714  *      parv[1] = TS_CURRENT for the server
01715  *      parv[2] = TS_MIN for the server
01716  *      parv[3] = server is standalone or connected to non-TS only
01717  *      parv[4] = server's idea of UTC time
01718  */
01719 int anope_event_svinfo(char *source, int ac, char **av)
01720 {
01721     /* currently not used but removes the message : unknown message from server */
01722     return MOD_CONT;
01723 }
01724 
01725 int anope_event_pass(char *source, int ac, char **av)
01726 {
01727     if (UseTS6) {
01728         TS6UPLINK = sstrdup(av[3]);
01729     }
01730     return MOD_CONT;
01731 }
01732 
01733 void charybdis_cmd_svsjoin(char *source, char *nick, char *chan, char *param)
01734 {
01735     /* Not Supported by this IRCD */
01736 }
01737 
01738 void charybdis_cmd_svspart(char *source, char *nick, char *chan)
01739 {
01740     /* Not Supported by this IRCD */
01741 }
01742 
01743 void charybdis_cmd_swhois(char *source, char *who, char *mask)
01744 {
01745     /* not supported */
01746 }
01747 
01748 int anope_event_notice(char *source, int ac, char **av)
01749 {
01750     return MOD_CONT;
01751 }
01752 
01753 int anope_event_admin(char *source, int ac, char **av)
01754 {
01755     return MOD_CONT;
01756 }
01757 
01758 int anope_event_invite(char *source, int ac, char **av)
01759 {
01760     return MOD_CONT;
01761 }
01762 
01763 int anope_event_bmask(char *source, int ac, char **av)
01764 {
01765     Channel *c;
01766     char *bans;
01767     char *b;
01768     int count, i;
01769 
01770     /* :42X BMASK 1106409026 #ircops b :*!*@*.aol.com */
01771     /*             0          1      2   3            */
01772     c = findchan(av[1]);
01773 
01774     if (c) {
01775         bans = sstrdup(av[3]);
01776         count = myNumToken(bans, ' ');
01777         for (i = 0; i <= count - 1; i++) {
01778             b = myStrGetToken(bans, ' ', i);
01779             if (!stricmp(av[2], "b")) {
01780                 add_ban(c, b);
01781             }
01782             if (!stricmp(av[2], "e")) {
01783                 add_exception(c, b);
01784             }
01785             if (!stricmp(av[2], "I")) {
01786                 add_invite(c, b);
01787             }
01788             if (b)
01789                 free(b);
01790         }
01791         free(bans);
01792     }
01793     return MOD_CONT;
01794 }
01795 
01796 int charybdis_flood_mode_check(char *value)
01797 {
01798     char *dp, *end;
01799 
01800     if (value && *value != ':'
01801         && (strtoul((*value == '*' ? value + 1 : value), &dp, 10) > 0)
01802         && (*dp == ':') && (*(++dp) != 0) && (strtoul(dp, &end, 10) > 0)
01803         && (*end == 0)) {
01804         return 1;
01805     } else {
01806         return 0;
01807     }
01808 
01809     return 0;
01810 }
01811 
01812 int anope_event_error(char *source, int ac, char **av)
01813 {
01814     if (ac >= 1) {
01815         if (debug) {
01816             alog("debug: %s", av[0]);
01817         }
01818     }
01819     return MOD_CONT;
01820 }
01821 
01822 void charybdis_cmd_jupe(char *jserver, char *who, char *reason)
01823 {
01824     char rbuf[256];
01825 
01826     snprintf(rbuf, sizeof(rbuf), "Juped by %s%s%s", who,
01827              reason ? ": " : "", reason ? reason : "");
01828 
01829     if (findserver(servlist, jserver))
01830         charybdis_cmd_squit(jserver, rbuf);
01831     charybdis_cmd_server(jserver, 2, rbuf);
01832     new_server(me_server, jserver, rbuf, SERVER_JUPED, NULL);
01833 }
01834 
01835 /* 
01836   1 = valid nick
01837   0 = nick is in valid
01838 */
01839 int charybdis_valid_nick(char *nick)
01840 {
01841     /* TS6 Save extension -Certus */
01842     if (isdigit(*nick))
01843         return 0;
01844     return 1;
01845 }
01846 
01847 /* 
01848   1 = valid chan
01849   0 = chan is invalid
01850 */
01851 int charybdis_valid_chan(char *chan)
01852 {
01853     /* no hard coded invalid chan */
01854     return 1;
01855 }
01856 
01857 
01858 void charybdis_cmd_ctcp(char *source, char *dest, char *buf)
01859 {
01860     char *s;
01861 
01862     if (!buf) {
01863         return;
01864     } else {
01865         s = normalizeBuffer(buf);
01866     }
01867 
01868     send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
01869     free(s);
01870 }
01871 
01872 int charybdis_send_account(int argc, char **argv)
01873 {
01874     send_cmd((UseTS6 ? TS6SID : ServerName), "ENCAP * SU %s :%s",
01875         argv[0], argv[0]);
01876 
01877     return MOD_CONT;
01878 }
01879 
01880 /* XXX: We need a hook on /ns logout before this is useful! --nenolod */
01881 /* We have one now! -GD */
01882 int charybdis_send_deaccount(int argc, char **argv)
01883 {
01884     send_cmd((UseTS6 ? TS6SID : ServerName), "ENCAP * SU %s",
01885         argv[0]);
01886 
01887     return MOD_CONT;
01888 }
01889 
01894 void moduleAddAnopeCmds()
01895 {
01896     pmodule_cmd_svsnoop(charybdis_cmd_svsnoop);
01897     pmodule_cmd_remove_akill(charybdis_cmd_remove_akill);
01898     pmodule_cmd_topic(charybdis_cmd_topic);
01899     pmodule_cmd_vhost_off(charybdis_cmd_vhost_off);
01900     pmodule_cmd_akill(charybdis_cmd_akill);
01901     pmodule_cmd_svskill(charybdis_cmd_svskill);
01902     pmodule_cmd_svsmode(charybdis_cmd_svsmode);
01903     pmodule_cmd_372(charybdis_cmd_372);
01904     pmodule_cmd_372_error(charybdis_cmd_372_error);
01905     pmodule_cmd_375(charybdis_cmd_375);
01906     pmodule_cmd_376(charybdis_cmd_376);
01907     pmodule_cmd_nick(charybdis_cmd_nick);
01908     pmodule_cmd_guest_nick(charybdis_cmd_guest_nick);
01909     pmodule_cmd_mode(charybdis_cmd_mode);
01910     pmodule_cmd_bot_nick(charybdis_cmd_bot_nick);
01911     pmodule_cmd_kick(charybdis_cmd_kick);
01912     pmodule_cmd_notice_ops(charybdis_cmd_notice_ops);
01913     pmodule_cmd_notice(charybdis_cmd_notice);
01914     pmodule_cmd_notice2(charybdis_cmd_notice2);
01915     pmodule_cmd_privmsg(charybdis_cmd_privmsg);
01916     pmodule_cmd_privmsg2(charybdis_cmd_privmsg2);
01917     pmodule_cmd_serv_notice(charybdis_cmd_serv_notice);
01918     pmodule_cmd_serv_privmsg(charybdis_cmd_serv_privmsg);
01919     pmodule_cmd_bot_chan_mode(charybdis_cmd_bot_chan_mode);
01920     pmodule_cmd_351(charybdis_cmd_351);
01921     pmodule_cmd_quit(charybdis_cmd_quit);
01922     pmodule_cmd_pong(charybdis_cmd_pong);
01923     pmodule_cmd_join(charybdis_cmd_join);
01924     pmodule_cmd_unsqline(charybdis_cmd_unsqline);
01925     pmodule_cmd_invite(charybdis_cmd_invite);
01926     pmodule_cmd_part(charybdis_cmd_part);
01927     pmodule_cmd_391(charybdis_cmd_391);
01928     pmodule_cmd_250(charybdis_cmd_250);
01929     pmodule_cmd_307(charybdis_cmd_307);
01930     pmodule_cmd_311(charybdis_cmd_311);
01931     pmodule_cmd_312(charybdis_cmd_312);
01932     pmodule_cmd_317(charybdis_cmd_317);
01933     pmodule_cmd_219(charybdis_cmd_219);
01934     pmodule_cmd_401(charybdis_cmd_401);
01935     pmodule_cmd_318(charybdis_cmd_318);
01936     pmodule_cmd_242(charybdis_cmd_242);
01937     pmodule_cmd_243(charybdis_cmd_243);
01938     pmodule_cmd_211(charybdis_cmd_211);
01939     pmodule_cmd_global(charybdis_cmd_global);
01940     pmodule_cmd_global_legacy(charybdis_cmd_global_legacy);
01941     pmodule_cmd_sqline(charybdis_cmd_sqline);
01942     pmodule_cmd_squit(charybdis_cmd_squit);
01943     pmodule_cmd_svso(charybdis_cmd_svso);
01944     pmodule_cmd_chg_nick(charybdis_cmd_chg_nick);
01945     pmodule_cmd_svsnick(charybdis_cmd_svsnick);
01946     pmodule_cmd_vhost_on(charybdis_cmd_vhost_on);
01947     pmodule_cmd_connect(charybdis_cmd_connect);
01948     pmodule_cmd_bob(charybdis_cmd_bob);
01949     pmodule_cmd_svshold(charybdis_cmd_svshold);
01950     pmodule_cmd_release_svshold(charybdis_cmd_release_svshold);
01951     pmodule_cmd_unsgline(charybdis_cmd_unsgline);
01952     pmodule_cmd_unszline(charybdis_cmd_unszline);
01953     pmodule_cmd_szline(charybdis_cmd_szline);
01954     pmodule_cmd_sgline(charybdis_cmd_sgline);
01955     pmodule_cmd_unban(charybdis_cmd_unban);
01956     pmodule_cmd_svsmode_chan(charybdis_cmd_svsmode_chan);
01957     pmodule_cmd_svid_umode(charybdis_cmd_svid_umode);
01958     pmodule_cmd_nc_change(charybdis_cmd_nc_change);
01959     pmodule_cmd_svid_umode2(charybdis_cmd_svid_umode2);
01960     pmodule_cmd_svid_umode3(charybdis_cmd_svid_umode3);
01961     pmodule_cmd_svsjoin(charybdis_cmd_svsjoin);
01962     pmodule_cmd_svspart(charybdis_cmd_svspart);
01963     pmodule_cmd_swhois(charybdis_cmd_swhois);
01964     pmodule_cmd_eob(charybdis_cmd_eob);
01965     pmodule_flood_mode_check(charybdis_flood_mode_check);
01966     pmodule_cmd_jupe(charybdis_cmd_jupe);
01967     pmodule_valid_nick(charybdis_valid_nick);
01968     pmodule_valid_chan(charybdis_valid_chan);
01969     pmodule_cmd_ctcp(charybdis_cmd_ctcp);
01970     pmodule_set_umode(charybdis_set_umode);
01971 }
01972 
01976 int AnopeInit(int argc, char **argv)
01977 {
01978     EvtHook *hk;
01979 
01980     moduleAddAuthor("Anope");
01981     moduleAddVersion(VERSION_STRING);
01982     moduleSetType(PROTOCOL);
01983 
01984     pmodule_ircd_version("Charybdis 1.0/1.1+");
01985     pmodule_ircd_cap(myIrcdcap);
01986     pmodule_ircd_var(myIrcd);
01987     pmodule_ircd_cbmodeinfos(myCbmodeinfos);
01988     pmodule_ircd_cumodes(myCumodes);
01989     pmodule_ircd_flood_mode_char_set("");
01990     pmodule_ircd_flood_mode_char_remove("");
01991     pmodule_ircd_cbmodes(myCbmodes);
01992     pmodule_ircd_cmmodes(myCmmodes);
01993     pmodule_ircd_csmodes(myCsmodes);
01994     pmodule_ircd_useTSMode(0);
01995 
01997     pmodule_invis_umode(UMODE_i);
01998     pmodule_oper_umode(UMODE_o);
01999     pmodule_invite_cmode(CMODE_i);
02000     pmodule_secret_cmode(CMODE_s);
02001     pmodule_private_cmode(CMODE_p);
02002     pmodule_key_mode(CMODE_k);
02003     pmodule_limit_mode(CMODE_l);
02004     pmodule_permchan_mode(0);
02005 
02006     moduleAddAnopeCmds();
02007     moduleAddIRCDMsgs();
02008 
02009     hk = createEventHook(EVENT_NICK_IDENTIFY, charybdis_send_account);
02010     moduleAddEventHook(hk);
02011 
02012     hk = createEventHook(EVENT_NICK_REGISTERED, charybdis_send_account);
02013     moduleAddEventHook(hk);
02014 
02015     /* XXX: It'd be nice if we could have an event like this, but it's not there yet :( */
02016         /* It's there now! Trystan said so! -GD */
02017     hk = createEventHook(EVENT_NICK_LOGOUT, charybdis_send_deaccount);
02018     moduleAddEventHook(hk);
02019 
02020     return MOD_CONT;
02021 }
02022 
02023 /* Clean up allocated things in here */
02024 void AnopeFini(void)
02025 {
02026         if (UseTS6)
02027                 free(TS6SID);
02028 }
02029 
02030 /* EOF */