ratbox.c

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