ratbox.c

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