shadowircd.c

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