plexus2.c

Go to the documentation of this file.
00001 /* PlexusIRCD 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 #include "services.h"
00013 #include "pseudo.h"
00014 #include "plexus2.h"
00015 
00016 IRCDVar myIrcd[] = {
00017   {"PleXusIRCd 2.0+",       /* ircd name */
00018    "+oiSR",         /* nickserv mode */
00019    "+oiSR",         /* chanserv mode */
00020    "+oiSR",         /* memoserv mode */
00021    "+oiSR",         /* hostserv mode */
00022    "+oaiSR",            /* operserv mode */
00023    "+oiSR",         /* botserv mode  */
00024    "+oiSR",         /* helpserv mode */
00025    "+oiSR",         /* Dev/Null mode */
00026    "+oiSR",         /* Global mode   */
00027    "+oiSR",         /* nickserv alias mode */
00028    "+oiSR",         /* chanserv alias mode */
00029    "+oiSR",         /* memoserv alias mode */
00030    "+oiSR",         /* hostserv alias mode */
00031    "+oaiSR",            /* operserv alias mode */
00032    "+oiSR",         /* botserv alias mode  */
00033    "+oiSR",         /* helpserv alias mode */
00034    "+oiSR",         /* Dev/Null alias mode */
00035    "+oiSR",         /* Global alias mode   */
00036    "+iSR",          /* Used by BotServ Bots */
00037    3,               /* Chan Max Symbols     */
00038    "-acilmnpstMNORZ",       /* Modes to Remove */
00039    "+o",            /* Channel Umode used by Botserv bots */
00040    1,               /* SVSNICK */
00041    1,               /* Vhost  */
00042    0,               /* Has Owner */
00043    NULL,            /* Mode to set for an owner */
00044    NULL,            /* Mode to unset for an owner */
00045    NULL,            /* Mode to set for chan admin */
00046    NULL,            /* Mode to unset for chan admin */
00047    "+R",            /* Mode On Reg          */
00048      NULL,                      /* Mode on ID for Roots */
00049      NULL,                      /* Mode on ID for Admins */
00050      NULL,                      /* Mode on ID for Opers */
00051    "-R",            /* Mode on UnReg        */
00052    "-R",            /* Mode on Nick Change  */
00053    1,               /* Supports SGlines     */
00054    1,               /* Supports SQlines     */
00055    0,               /* Supports SZlines     */
00056    1,               /* Supports Halfop +h   */
00057    3,               /* Number of server args */
00058    0,               /* Join 2 Set           */
00059    0,               /* Join 2 Message       */
00060    1,               /* Has exceptions +e    */
00061    0,               /* TS Topic Forward     */
00062    0,               /* TS Topci Backward    */
00063    0,               /* Protected Umode      */
00064    0,               /* Has Admin            */
00065    1,               /* Chan SQlines         */
00066    0,               /* Quit on Kill         */
00067    0,               /* SVSMODE unban        */
00068    0,               /* Has Protect          */
00069    0,               /* Reverse              */
00070    0,               /* Chan Reg             */
00071    0,               /* Channel Mode         */
00072    0,               /* vidents              */
00073    0,               /* svshold              */
00074    1,               /* time stamp on mode   */
00075    0,               /* NICKIP               */
00076    0,               /* O:LINE               */
00077    1,               /* UMODE                */
00078    1,               /* VHOST ON NICK        */
00079    0,               /* Change RealName      */
00080    CMODE_p,         /* No Knock             */
00081    0,               /* Admin Only           */
00082    DEFAULT_MLOCK,       /* Default MLOCK        */
00083    UMODE_h,         /* Vhost Mode           */
00084    0,               /* +f                   */
00085    0,               /* +L                   */
00086    0,               /* +f Mode                          */
00087    0,               /* +L Mode                              */
00088    0,               /* On nick change check if they could be identified */
00089    0,               /* No Knock requires +i */
00090    NULL,            /* CAPAB Chan Modes             */
00091    0,               /* We support TOKENS */
00092    1,               /* TOKENS are CASE inSensitive */
00093    0,               /* TIME STAMPS are BASE64 */
00094    1,               /* +I support */
00095    0,               /* SJOIN ban char */
00096    0,               /* SJOIN except char */
00097    0,               /* SJOIN invite char */
00098    0,               /* Can remove User Channel Modes with SVSMODE */
00099    0,               /* Sglines are not enforced until user reconnects */
00100    "h",             /* vhost char */
00101    0,               /* ts6 */
00102    0,               /* support helper umode */
00103    0,               /* p10 */
00104    NULL,            /* character set */
00105    1,               /* reports sync state */
00106    }
00107   ,
00108   {NULL}
00109 };
00110 
00111 IRCDCAPAB myIrcdcap[] = {
00112   {
00113    0,               /* NOQUIT       */
00114    0,               /* TSMODE       */
00115    0,               /* UNCONNECT    */
00116    0,               /* NICKIP       */
00117    0,               /* SJOIN        */
00118    CAPAB_ZIP,           /* ZIP          */
00119    0,               /* BURST        */
00120    CAPAB_TS5,           /* TS5          */
00121    0,               /* TS3          */
00122    0,               /* DKEY         */
00123    0,               /* PT4          */
00124    0,               /* SCS          */
00125    CAPAB_QS,            /* QS           */
00126    CAPAB_UID,           /* UID          */
00127    CAPAB_KNOCK,         /* KNOCK        */
00128    0,               /* CLIENT       */
00129    0,               /* IPV6         */
00130    0,               /* SSJ5         */
00131    0,               /* SN2          */
00132    0,               /* TOKEN        */
00133    0,               /* VHOST        */
00134    0,               /* SSJ3         */
00135    0,               /* NICK2        */
00136    0,               /* UMODE2       */
00137    0,               /* VL           */
00138    0,               /* TLKEXT       */
00139    0,               /* DODKEY       */
00140    0,               /* DOZIP        */
00141    0, 0, 0}
00142 };
00143 
00144 
00145 
00146 void
00147 plexus_set_umode (User * user, int ac, char **av)
00148 {
00149   int add = 1;          /* 1 if adding modes, 0 if deleting */
00150   char *modes = av[0];
00151 
00152   ac--;
00153 
00154   if (debug)
00155     alog ("debug: Changing mode for %s to %s", user->nick, modes);
00156 
00157   while (*modes)
00158     {
00159 
00160       /* This looks better, much better than "add ? (do_add) : (do_remove)".
00161        * At least this is readable without paying much attention :) -GD
00162        */
00163       if (add)
00164     user->mode |= umodes[(int) *modes];
00165       else
00166     user->mode &= ~umodes[(int) *modes];
00167 
00168       switch (*modes++)
00169     {
00170     case '+':
00171       add = 1;
00172       break;
00173     case '-':
00174       add = 0;
00175       break;
00176     case 'h':
00177       update_host (user);
00178       break;
00179     case 'o':
00180       if (add)
00181         {
00182           opcnt++;
00183 
00184           if (WallOper)
00185         anope_cmd_global (s_OperServ,
00186                   "\2%s\2 is now an IRC operator.",
00187                   user->nick);
00188           display_news (user, NEWS_OPER);
00189 
00190         }
00191       else
00192         {
00193           opcnt--;
00194         }
00195       break;
00196     case 'R':
00197       if (add && !nick_identified (user))
00198         {
00199           common_svsmode (user, "-R", NULL);
00200           user->mode &= ~UMODE_R;
00201         }
00202       break;
00203 
00204     }
00205     }
00206 }
00207 
00208 /*  
00209  * Local valid_op, and valid_halfop overrides.
00210  * These are nessecary due to the way hybrid-based ircds handle halfops.
00211  * hybrid-based ircds treat a -o as a -h as well. So if a user is set -o,
00212  * the ircd will also set them -h if they have that mode. This breaks
00213  * is_valid_op, as it always sends a -o. Breaking up the routines corrects this problem. - ThaPrince
00214  */
00215 
00216 int
00217 plexus_check_valid_halfop (User * user, Channel * chan, int servermode)
00218 {
00219   if (!chan || !chan->ci)
00220     return 1;
00221 
00222   /* They will be kicked; no need to deop, no need to update our internal struct too */
00223   if (chan->ci->flags & CI_VERBOTEN)
00224     return 0;
00225 
00226   if (servermode && !check_access (user, chan->ci, CA_AUTOHALFOP))
00227     {
00228       notice_lang (s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ);
00229       anope_cmd_mode (whosends (chan->ci), chan->name, "-h %s", user->nick);
00230       return 0;
00231     }
00232 
00233   if (check_access (user, chan->ci, CA_AUTODEOP))
00234     {
00235       anope_cmd_mode (whosends (chan->ci), chan->name, "-h %s", user->nick);
00236       return 0;
00237     }
00238 
00239   return 1;
00240 }
00241 
00242 int
00243 plexus_check_valid_op (User * user, Channel * chan, int servermode)
00244 {
00245   if (!chan || !chan->ci)
00246     return 1;
00247 
00248   /* They will be kicked; no need to deop, no need to update our internal struct too */
00249   if (chan->ci->flags & CI_VERBOTEN)
00250     return 0;
00251 
00252   if (servermode && !check_access (user, chan->ci, CA_AUTOOP))
00253     {
00254       notice_lang (s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ);
00255       if (check_access (user, chan->ci, CA_AUTOHALFOP))
00256     {
00257       anope_cmd_mode (whosends (chan->ci), chan->name,
00258               "-o+h %s %s", user->nick, user->nick);
00259     }
00260       else
00261     {
00262       anope_cmd_mode (whosends (chan->ci), chan->name, "-o %s",
00263               user->nick);
00264     }
00265       return 0;
00266     }
00267 
00268   if (check_access (user, chan->ci, CA_AUTODEOP))
00269     {
00270       anope_cmd_mode (whosends (chan->ci), chan->name, "-o %s", user->nick);
00271       return 0;
00272     }
00273 
00274   return 1;
00275 }
00276 
00277 unsigned long umodes[128] = {
00278   0, 0, 0,          /* Unused */
00279   0, 0, 0,          /* Unused */
00280   0, 0, 0,          /* Unused, Unused, Horzontal Tab */
00281   0, 0, 0,          /* Line Feed, Unused, Unused */
00282   0, 0, 0,          /* Carriage Return, Unused, Unused */
00283   0, 0, 0,          /* Unused */
00284   0, 0, 0,          /* Unused */
00285   0, 0, 0,          /* Unused */
00286   0, 0, 0,          /* Unused */
00287   0, 0, 0,          /* Unused */
00288   0, 0, 0,          /* Unused, Unused, Space */
00289   0, 0, 0,          /* ! " #  */
00290   0, 0, 0,          /* $ % &  */
00291   0, 0, 0,          /* ! ( )  */
00292   0, 0, 0,          /* * + ,  */
00293   0, 0, 0,          /* - . /  */
00294   0, 0,             /* 0 1 */
00295   0, 0,             /* 2 3 */
00296   0, 0,             /* 4 5 */
00297   0, 0,             /* 6 7 */
00298   0, 0,             /* 8 9 */
00299   0, 0,             /* : ; */
00300   0, 0, 0,          /* < = > */
00301   0, 0,             /* ? @ */
00302   0, 0, 0,          /* A B C */
00303   0, 0, 0,          /* D E F */
00304   0, 0, 0,          /* G H I */
00305   0, 0, 0,          /* J K L */
00306   0, 0, 0,          /* M N O */
00307   0, 0, UMODE_R,        /* P Q R */
00308   UMODE_S, 0, 0,        /* S T U */
00309   0, 0, 0,          /* V W X */
00310   0,                /* Y */
00311   0,                /* Z */
00312   0, 0, 0,          /* [ \ ] */
00313   0, 0, 0,          /* ^ _ ` */
00314   UMODE_a, UMODE_b, 0,      /* a b c */
00315   UMODE_d, 0, 0,        /* d e f */
00316   0, UMODE_h, UMODE_i,      /* g h i */
00317   0, 0, UMODE_l,        /* j k l */
00318   UMODE_g, UMODE_n, UMODE_o,    /* m n o */
00319   0, 0, 0,          /* p q r */
00320   0, 0, UMODE_u,        /* s t u */
00321   0, UMODE_w, UMODE_x,      /* v w x */
00322   0,                /* y */
00323   0,                /* z */
00324   0, 0, 0,          /* { | } */
00325   0, 0              /* ~ ‚ */
00326 };
00327 
00328 
00329 char myCsmodes[128] = {
00330   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00331   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00332 
00333   0,
00334   0,
00335   0, 0, 0,
00336   'h',
00337   0, 0, 0, 0,
00338   0,
00339 
00340   'v', 0, 0, 0, 0,
00341   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00342 
00343   'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00344   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00345 
00346   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00347   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00348 };
00349 
00350 CMMode myCmmodes[128] = {
00351   {NULL}, {NULL}, {NULL},
00352   {NULL}, {NULL}, {NULL},
00353   {NULL}, {NULL}, {NULL},
00354   {NULL}, {NULL}, {NULL},
00355   {NULL}, {NULL}, {NULL},
00356   {NULL}, {NULL}, {NULL},
00357   {NULL}, {NULL}, {NULL},
00358   {NULL}, {NULL}, {NULL},
00359   {NULL}, {NULL}, {NULL},
00360   {NULL}, {NULL}, {NULL},
00361   {NULL}, {NULL}, {NULL},
00362   {NULL}, {NULL}, {NULL},
00363   {NULL}, {NULL}, {NULL},
00364   {NULL}, {NULL}, {NULL},
00365   {NULL}, {NULL}, {NULL},
00366   {NULL}, {NULL}, {NULL},
00367   {NULL}, {NULL}, {NULL},
00368   {NULL}, {NULL}, {NULL},
00369   {NULL}, {NULL}, {NULL},
00370   {NULL}, {NULL}, {NULL},
00371   {NULL}, {NULL}, {NULL},
00372   {NULL}, {NULL}, {NULL},
00373   {NULL}, {NULL}, {NULL},   /* BCD */
00374   {NULL}, {NULL}, {NULL},   /* EFG */
00375   {NULL},           /* H */
00376   {add_invite, del_invite},
00377   {NULL},           /* J */
00378   {NULL}, {NULL}, {NULL},   /* KLM */
00379   {NULL}, {NULL}, {NULL},   /* NOP */
00380   {NULL}, {NULL}, {NULL},   /* QRS */
00381   {NULL}, {NULL}, {NULL},   /* TUV */
00382   {NULL}, {NULL}, {NULL},   /* WXY */
00383   {NULL},           /* Z */
00384   {NULL}, {NULL},       /* (char 91 - 92) */
00385   {NULL}, {NULL}, {NULL},   /* (char 93 - 95) */
00386   {NULL},           /* ` (char 96) */
00387   {NULL},           /* a (char 97) */
00388   {add_ban, del_ban},
00389   {NULL},
00390   {NULL},
00391   {add_exception, del_exception},
00392   {NULL},
00393   {NULL},
00394   {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00395   {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00396   {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}
00397 };
00398 
00399 
00400 CBMode myCbmodes[128] = {
00401   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00402   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00403   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
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   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00409   {0},
00410   {0},              /* A */
00411   {0},              /* B */
00412   {0},              /* C */
00413   {0},              /* D */
00414   {0},              /* E */
00415   {0},              /* F */
00416   {0},              /* G */
00417   {0},              /* H */
00418   {0},              /* I */
00419   {0},              /* J */
00420   {0},              /* K */
00421   {0},              /* L */
00422   {CMODE_M, 0, NULL, NULL}, /* M */
00423   {CMODE_N, 0, NULL, NULL}, /* N */
00424   {CMODE_O, CBM_NO_USER_MLOCK, NULL, NULL}, /* O */
00425   {0},              /* P */
00426   {0},              /* Q */
00427   {CMODE_R, 0, NULL, NULL}, /* R */
00428   {0},              /* S */
00429   {0},              /* T */
00430   {0},              /* U */
00431   {0},              /* V */
00432   {0},              /* W */
00433   {0},              /* X */
00434   {0},              /* Y */
00435   {CMODE_Z, 0, NULL, NULL}, /* Z */
00436   {0}, {0}, {0}, {0}, {0}, {0},
00437   {CMODE_a, 0, NULL, NULL},
00438   {0},              /* b */
00439   {CMODE_c, 0, NULL, NULL}, /* c */
00440   {0},              /* d */
00441   {0},              /* e */
00442   {0},              /* f */
00443   {0},              /* g */
00444   {0},              /* h */
00445   {CMODE_i, 0, NULL, NULL},
00446   {0},              /* j */
00447   {CMODE_k, 0, chan_set_key, cs_set_key},
00448   {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit},
00449   {CMODE_m, 0, NULL, NULL},
00450   {CMODE_n, 0, NULL, NULL},
00451   {0},              /* o */
00452   {CMODE_p, 0, NULL, NULL},
00453   {0},              /* q */
00454   {0},
00455   {CMODE_s, 0, NULL, NULL},
00456   {CMODE_t, 0, NULL, NULL},
00457   {0},
00458   {0},              /* v */
00459   {0},              /* w */
00460   {0},              /* x */
00461   {0},              /* y */
00462   {0},              /* z */
00463   {0}, {0}, {0}, {0}
00464 };
00465 
00466 CBModeInfo myCbmodeinfos[] = {
00467   {'a', CMODE_a, 0, NULL, NULL},
00468   {'i', CMODE_i, 0, NULL, NULL},
00469   {'k', CMODE_k, 0, get_key, cs_get_key},
00470   {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit},
00471   {'m', CMODE_m, 0, NULL, NULL},
00472   {'n', CMODE_n, 0, NULL, NULL},
00473   {'p', CMODE_p, 0, NULL, NULL},
00474   {'s', CMODE_s, 0, NULL, NULL},
00475   {'t', CMODE_t, 0, NULL, NULL},
00476   {'M', CMODE_M, 0, NULL, NULL},
00477   {'N', CMODE_N, 0, NULL, NULL},
00478   {'O', CMODE_O, 0, NULL, NULL},
00479   {'R', CMODE_R, 0, NULL, NULL},
00480   {'Z', CMODE_Z, 0, NULL, NULL},
00481   {0}
00482 };
00483 
00484 
00485 CUMode myCumodes[128] = {
00486   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00487   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00488   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00489   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00490 
00491   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00492   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00493   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00494   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00495 
00496   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00497   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00498   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00499   {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00500 
00501   {0},
00502 
00503   {0},              /* a */
00504   {0},              /* b */
00505   {0},              /* c */
00506   {0},              /* d */
00507   {0},              /* e */
00508   {0},              /* f */
00509   {0},              /* g */
00510   {CUS_HALFOP, 0, plexus_check_valid_halfop},
00511   {0},              /* i */
00512   {0},              /* j */
00513   {0},              /* k */
00514   {0},              /* l */
00515   {0},              /* m */
00516   {0},              /* n */
00517   {CUS_OP, CUF_PROTECT_BOTSERV, plexus_check_valid_op},
00518   {0},              /* p */
00519   {0},              /* q */
00520   {0},              /* r */
00521   {0},              /* s */
00522   {0},              /* t */
00523   {0},              /* u */
00524   {CUS_VOICE, 0, NULL},
00525   {0},              /* w */
00526   {0},              /* x */
00527   {0},              /* y */
00528   {0},              /* z */
00529   {0}, {0}, {0}, {0}, {0}
00530 };
00531 
00532 
00533 
00534 void
00535 plexus_cmd_notice (char *source, char *dest, char *buf)
00536 {
00537   if (!buf)
00538     {
00539       return;
00540     }
00541 
00542   if (NSDefFlags & NI_MSG)
00543     {
00544       plexus_cmd_privmsg2 (source, dest, buf);
00545     }
00546   else
00547     {
00548       send_cmd (source, "NOTICE %s :%s", dest, buf);
00549     }
00550 }
00551 
00552 void
00553 plexus_cmd_notice2 (char *source, char *dest, char *msg)
00554 {
00555   send_cmd (source, "NOTICE %s :%s", dest, msg);
00556 }
00557 
00558 void
00559 plexus_cmd_privmsg (char *source, char *dest, char *buf)
00560 {
00561   if (!buf)
00562     {
00563       return;
00564     }
00565 
00566   send_cmd (source, "PRIVMSG %s :%s", dest, buf);
00567 }
00568 
00569 void
00570 plexus_cmd_privmsg2 (char *source, char *dest, char *msg)
00571 {
00572   send_cmd (source, "PRIVMSG %s :%s", dest, msg);
00573 }
00574 
00575 void
00576 plexus_cmd_serv_notice (char *source, char *dest, char *msg)
00577 {
00578   send_cmd (source, "NOTICE $$%s :%s", dest, msg);
00579 }
00580 
00581 void
00582 plexus_cmd_serv_privmsg (char *source, char *dest, char *msg)
00583 {
00584   send_cmd (source, "PRIVMSG $$%s :%s", dest, msg);
00585 }
00586 
00587 
00588 void
00589 plexus_cmd_global (char *source, char *buf)
00590 {
00591   if (!buf)
00592     {
00593       return;
00594     }
00595 
00596   send_cmd (source ? source : ServerName, "OPERWALL :%s", buf);
00597 }
00598 
00599 /* GLOBOPS - to handle old WALLOPS */
00600 void
00601 plexus_cmd_global_legacy (char *source, char *fmt)
00602 {
00603   send_cmd (source ? source : ServerName, "OPERWALL :%s", fmt);
00604 }
00605 
00606 int
00607 anope_event_sjoin (char *source, int ac, char **av)
00608 {
00609   do_sjoin (source, ac, av);
00610   return MOD_CONT;
00611 }
00612 
00613 int
00614 anope_event_nick (char *source, int ac, char **av)
00615 {
00616   if (ac != 2)
00617     {
00618       User *user = do_nick (source, av[0], av[4], av[5], av[7], av[9],
00619                 strtoul (av[2], NULL, 10),
00620                 strtoul (av[8], NULL, 0), 0, av[6], NULL);
00621       if (user)
00622     anope_set_umode (user, 1, &av[3]);
00623     }
00624   else
00625     {
00626       do_nick (source, av[0], NULL, NULL, NULL, NULL,
00627            strtoul (av[1], NULL, 10), 0, 0, NULL, NULL);
00628     }
00629   return MOD_CONT;
00630 }
00631 
00632 int
00633 anope_event_topic (char *source, int ac, char **av)
00634 {
00635   if (ac == 4)
00636     {
00637       do_topic (source, ac, av);
00638     }
00639   else
00640     {
00641       Channel *c = findchan (av[0]);
00642       time_t topic_time = time (NULL);
00643 
00644       if (!c)
00645     {
00646       if (debug)
00647         {
00648           alog ("debug: TOPIC %s for nonexistent channel %s",
00649             merge_args (ac - 1, av + 1), av[0]);
00650         }
00651       return MOD_CONT;
00652     }
00653 
00654       if (check_topiclock (c, topic_time))
00655     return MOD_CONT;
00656 
00657       if (c->topic)
00658     {
00659       free (c->topic);
00660       c->topic = NULL;
00661     }
00662       if (ac > 1 && *av[1])
00663     c->topic = sstrdup (av[1]);
00664 
00665       strscpy (c->topic_setter, source, sizeof (c->topic_setter));
00666       c->topic_time = topic_time;
00667 
00668       record_topic (av[0]);
00669       
00670       if (ac > 1 && *av[1])
00671           send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[1]);
00672       else
00673           send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
00674               
00675     }
00676   return MOD_CONT;
00677 }
00678 
00679 int
00680 anope_event_tburst (char *source, int ac, char **av)
00681 {
00682   if (ac != 5)
00683     return MOD_CONT;
00684 
00685   av[0] = av[1];
00686   av[1] = av[3];
00687   av[3] = av[4];
00688   do_topic (source, 4, av);
00689   return MOD_CONT;
00690 }
00691 
00692 int
00693 anope_event_436 (char *source, int ac, char **av)
00694 {
00695   if (ac < 1)
00696     return MOD_CONT;
00697 
00698   m_nickcoll (av[0]);
00699   return MOD_CONT;
00700 }
00701 
00702 
00703 void
00704 moduleAddIRCDMsgs (void)
00705 {
00706   Message *m;
00707 
00708   updateProtectDetails ("PROTECT", "PROTECTME", "protect", "deprotect",
00709             "AUTOPROTECT", "+", "-");
00710 
00711   m = createMessage ("401", anope_event_null);
00712   addCoreMessage (IRCD, m);
00713   m = createMessage ("402", anope_event_null);
00714   addCoreMessage (IRCD, m);
00715   m = createMessage ("436", anope_event_436);
00716   addCoreMessage (IRCD, m);
00717   m = createMessage ("AWAY", anope_event_away);
00718   addCoreMessage (IRCD, m);
00719   m = createMessage ("INVITE", anope_event_invite);
00720   addCoreMessage (IRCD, m);
00721   m = createMessage ("JOIN", anope_event_join);
00722   addCoreMessage (IRCD, m);
00723   m = createMessage ("KICK", anope_event_kick);
00724   addCoreMessage (IRCD, m);
00725   m = createMessage ("KILL", anope_event_kill);
00726   addCoreMessage (IRCD, m);
00727   m = createMessage ("MODE", anope_event_mode);
00728   addCoreMessage (IRCD, m);
00729   m = createMessage ("MOTD", anope_event_motd);
00730   addCoreMessage (IRCD, m);
00731   m = createMessage ("NICK", anope_event_nick);
00732   addCoreMessage (IRCD, m);
00733   m = createMessage ("NOTICE", anope_event_notice);
00734   addCoreMessage (IRCD, m);
00735   m = createMessage ("PART", anope_event_part);
00736   addCoreMessage (IRCD, m);
00737   m = createMessage ("PASS", anope_event_pass);
00738   addCoreMessage (IRCD, m);
00739   m = createMessage ("PING", anope_event_ping);
00740   addCoreMessage (IRCD, m);
00741   m = createMessage ("PRIVMSG", anope_event_privmsg);
00742   addCoreMessage (IRCD, m);
00743   m = createMessage ("QUIT", anope_event_quit);
00744   addCoreMessage (IRCD, m);
00745   m = createMessage ("SERVER", anope_event_server);
00746   addCoreMessage (IRCD, m);
00747   m = createMessage ("SQUIT", anope_event_squit);
00748   addCoreMessage (IRCD, m);
00749   m = createMessage ("TOPIC", anope_event_topic);
00750   addCoreMessage (IRCD, m);
00751   m = createMessage ("TBURST", anope_event_tburst);
00752   addCoreMessage (IRCD, m);
00753   m = createMessage ("USER", anope_event_null);
00754   addCoreMessage (IRCD, m);
00755   m = createMessage ("WALLOPS", anope_event_null);
00756   addCoreMessage (IRCD, m);
00757   m = createMessage ("WHOIS", anope_event_whois);
00758   addCoreMessage (IRCD, m);
00759   m = createMessage ("SVSMODE", anope_event_mode);
00760   addCoreMessage (IRCD, m);
00761   m = createMessage ("SVSNICK", anope_event_null);
00762   addCoreMessage (IRCD, m);
00763   m = createMessage ("CAPAB", anope_event_capab);
00764   addCoreMessage (IRCD, m);
00765   m = createMessage ("SJOIN", anope_event_sjoin);
00766   addCoreMessage (IRCD, m);
00767   m = createMessage ("SVINFO", anope_event_svinfo);
00768   addCoreMessage (IRCD, m);
00769   m = createMessage ("EOB", anope_event_eob);
00770   addCoreMessage (IRCD, m);
00771   m = createMessage ("ADMIN", anope_event_admin);
00772   addCoreMessage (IRCD, m);
00773   m = createMessage ("ERROR", anope_event_error);
00774   addCoreMessage (IRCD, m);
00775   m = createMessage ("SETHOST", anope_event_sethost);
00776   addCoreMessage (IRCD, m);
00777 }
00778 
00779 void
00780 plexus_cmd_sqline (char *mask, char *reason)
00781 {
00782   send_cmd (s_OperServ, "RESV * %s :%s", mask, reason);
00783 }
00784 
00785 void
00786 plexus_cmd_unsgline (char *mask)
00787 {
00788   send_cmd (s_OperServ, "UNXLINE * %s", mask);
00789 }
00790 
00791 void
00792 plexus_cmd_unszline (char *mask)
00793 {
00794   /* Does not support */
00795 }
00796 
00797 void
00798 plexus_cmd_szline (char *mask, char *reason, char *whom)
00799 {
00800   /* Does not support */
00801 }
00802 
00803 void
00804 plexus_cmd_svsnoop (char *server, int set)
00805 {
00806   /* does not support */
00807 }
00808 
00809 void
00810 plexus_cmd_svsadmin (char *server, int set)
00811 {
00812   plexus_cmd_svsnoop (server, set);
00813 }
00814 
00815 void
00816 plexus_cmd_sgline (char *mask, char *reason)
00817 {
00818   send_cmd (s_OperServ, "XLINE * %s :%s", mask, reason);
00819 }
00820 
00821 void
00822 plexus_cmd_remove_akill (char *user, char *host)
00823 {
00824   send_cmd (s_OperServ, "UNKLINE * %s %s", user, host);
00825 }
00826 
00827 void
00828 plexus_cmd_topic (char *whosets, char *chan, char *whosetit,
00829           char *topic, time_t when)
00830 {
00831   send_cmd (whosets, "SVSTOPIC %s %s %lu :%s", chan, whosetit,
00832         (unsigned long int) when, topic);
00833 }
00834 
00835 void
00836 plexus_cmd_vhost_off (User * u)
00837 {
00838   send_cmd (ServerName, "SVSMODE %s -h", u->nick);
00839 }
00840 
00841 void
00842 plexus_cmd_vhost_on (char *nick, char *vIdent, char *vhost)
00843 {
00844   User *u;
00845 
00846   if (!nick)
00847   {
00848     return;
00849   }
00850 
00851   u = finduser (nick);
00852 
00853   if (u)
00854   {
00855     send_cmd (ServerName, "SVSHOST %s %s", nick, vhost);
00856     u->mode |= UMODE_h;
00857   }
00858 }
00859 
00860 void
00861 plexus_cmd_unsqline (char *user)
00862 {
00863   send_cmd (s_OperServ, "UNRESV * %s", user);
00864 }
00865 
00866 void
00867 plexus_cmd_join (char *user, char *channel, time_t chantime)
00868 {
00869   send_cmd (ServerName, "SJOIN %ld %s + :%s", (long int) chantime, channel,
00870         user);
00871 }
00872 
00873 /*
00874 oper:       the nick of the oper performing the kline
00875 target.server:  the server(s) this kline is destined for
00876 duration:   the duration if a tkline, 0 if permanent.
00877 user:       the 'user' portion of the kline
00878 host:       the 'host' portion of the kline
00879 reason:     the reason for the kline.
00880 */
00881 
00882 void
00883 plexus_cmd_akill (char *user, char *host, char *who, time_t when,
00884           time_t expires, char *reason)
00885 {
00886   send_cmd (s_OperServ, "KLINE * %ld %s %s :%s",
00887         (long int) (expires - (long) time (NULL)), user, host, reason);
00888 }
00889 
00890 void
00891 plexus_cmd_svskill (char *source, char *user, char *buf)
00892 {
00893   if (!buf)
00894     {
00895       return;
00896     }
00897 
00898   if (!source || !user)
00899     {
00900       return;
00901     }
00902 
00903   send_cmd (source, "KILL %s :%s", user, buf);
00904 }
00905 
00906 void
00907 plexus_cmd_svsmode (User * u, int ac, char **av)
00908 {
00909   send_cmd (ServerName, "SVSMODE %s %s", u->nick, av[0]);
00910 
00911   if ((ac == 2) && isdigit (*av[1]))
00912     send_cmd (ServerName, "SVSID %s %s", u->nick, av[1]);
00913 }
00914 
00915 /*
00916  * SVINFO
00917  *      parv[0] = sender prefix
00918  *      parv[1] = TS_CURRENT for the server
00919  *      parv[2] = TS_MIN for the server
00920  *      parv[3] = server is standalone or connected to non-TS only
00921  *      parv[4] = server's idea of UTC time
00922  */
00923 void
00924 plexus_cmd_svinfo ()
00925 {
00926   send_cmd (NULL, "SVINFO 5 5 0 :%ld", (long int) time (NULL));
00927 }
00928 
00929 /* CAPAB */
00930 /*
00931   QS     - Can handle quit storm removal
00932   EX     - Can do channel +e exemptions 
00933   CHW    - Can do channel wall @#
00934   LL     - Can do lazy links 
00935   IE     - Can do invite exceptions 
00936   EOB    - Can do EOB message
00937   KLN    - Can do KLINE message 
00938   GLN    - Can do GLINE message 
00939   HOPS   - can do half ops (+h)
00940   HUB    - This server is a HUB 
00941   AOPS   - Can do anon ops (+a) 
00942   UID    - Can do UIDs
00943   ZIP    - Can do ZIPlinks
00944   ENC    - Can do ENCrypted links 
00945   KNOCK  -  supports KNOCK 
00946   TBURST - supports TBURST
00947   PARA   - supports invite broadcasting for +p
00948   ENCAP  - ?
00949 */
00950 void
00951 plexus_cmd_capab ()
00952 {
00953   send_cmd (NULL,
00954         "CAPAB :QS EX CHW IE EOB KLN GLN HOPS HUB KNOCK TBURST PARA");
00955 }
00956 
00957 /* PASS */
00958 void
00959 plexus_cmd_pass (char *pass)
00960 {
00961   send_cmd (NULL, "PASS %s :TS", pass);
00962 }
00963 
00964 /* SERVER name hop descript */
00965 void
00966 plexus_cmd_server (char *servname, int hop, char *descript)
00967 {
00968   send_cmd (NULL, "SERVER %s %d :%s", servname, hop, descript);
00969 }
00970 
00971 void
00972 plexus_cmd_connect (int servernum)
00973 {
00974   me_server = new_server (NULL, ServerName, ServerDesc, SERVER_ISME, NULL);
00975 
00976   if (servernum == 1)
00977     plexus_cmd_pass (RemotePassword);
00978   else if (servernum == 2)
00979     plexus_cmd_pass (RemotePassword2);
00980   else if (servernum == 3)
00981     plexus_cmd_pass (RemotePassword3);
00982 
00983   plexus_cmd_capab ();
00984   plexus_cmd_server (ServerName, 1, ServerDesc);
00985   plexus_cmd_svinfo ();
00986 }
00987 
00988 void
00989 plexus_cmd_svsinfo ()
00990 {
00991   /* not used */
00992 }
00993 
00994 
00995 
00996 void
00997 plexus_cmd_bot_nick (char *nick, char *user, char *host, char *real,
00998              char *modes)
00999 {
01000   EnforceQlinedNick (nick, NULL);
01001   send_cmd (ServerName, "NICK %s 1 %ld %s %s %s %s %s 0 :%s", nick,
01002         (long int) time (NULL), modes, user, host, "*", ServerName, real);
01003   plexus_cmd_sqline (nick, "Reserved for services");
01004 
01005 }
01006 
01007 void
01008 plexus_cmd_part (char *nick, char *chan, char *buf)
01009 {
01010   if (buf)
01011     {
01012       send_cmd (nick, "PART %s :%s", chan, buf);
01013     }
01014   else
01015     {
01016       send_cmd (nick, "PART %s", chan);
01017     }
01018 }
01019 
01020 int
01021 anope_event_sethost (char *source, int ac, char **av)
01022 {
01023   User *u;
01024 
01025   if (ac != 2)
01026     return MOD_CONT;
01027 
01028   u = finduser (av[0]);
01029   if (!u)
01030     {
01031       if (debug)
01032     {
01033       alog ("debug: SETHOST for nonexistent user %s", source);
01034     }
01035       return MOD_CONT;
01036     }
01037 
01038   change_user_host (u, av[1]);
01039   return MOD_CONT;
01040 }
01041 
01042 int
01043 anope_event_ping (char *source, int ac, char **av)
01044 {
01045   if (ac < 1)
01046     return MOD_CONT;
01047   plexus_cmd_pong (ac > 1 ? av[1] : ServerName, av[0]);
01048   return MOD_CONT;
01049 }
01050 
01051 int
01052 anope_event_away (char *source, int ac, char **av)
01053 {
01054   if (!source)
01055     {
01056       return MOD_CONT;
01057     }
01058   m_away (source, (ac ? av[0] : NULL));
01059   return MOD_CONT;
01060 }
01061 
01062 int
01063 anope_event_kill (char *source, int ac, char **av)
01064 {
01065   if (ac != 2)
01066     return MOD_CONT;
01067 
01068   m_kill (av[0], av[1]);
01069   return MOD_CONT;
01070 }
01071 
01072 int
01073 anope_event_kick (char *source, int ac, char **av)
01074 {
01075   if (ac != 3)
01076     return MOD_CONT;
01077   do_kick (source, ac, av);
01078   return MOD_CONT;
01079 }
01080 
01081 int
01082 anope_event_eob (char *source, int ac, char **av)
01083 {
01084   Server *s;
01085   s = findserver (servlist, source);
01086   /* If we found a server with the given source, that one just
01087    * finished bursting. If there was no source, then our uplink
01088    * server finished bursting. -GD
01089    */
01090   if (!s && serv_uplink)
01091     s = serv_uplink;
01092   finish_sync (s, 1);
01093 
01094   return MOD_CONT;
01095 }
01096 
01097 void
01098 plexus_cmd_eob ()
01099 {
01100   send_cmd (ServerName, "EOB");
01101 }
01102 
01103 
01104 int
01105 anope_event_join (char *source, int ac, char **av)
01106 {
01107   if (ac != 1)
01108     return MOD_CONT;
01109   do_join (source, ac, av);
01110   return MOD_CONT;
01111 }
01112 
01113 int
01114 anope_event_motd (char *source, int ac, char **av)
01115 {
01116   if (!source)
01117     {
01118       return MOD_CONT;
01119     }
01120 
01121   m_motd (source);
01122   return MOD_CONT;
01123 }
01124 
01125 int
01126 anope_event_privmsg (char *source, int ac, char **av)
01127 {
01128   if (ac != 2)
01129     return MOD_CONT;
01130   m_privmsg (source, av[0], av[1]);
01131   return MOD_CONT;
01132 }
01133 
01134 int
01135 anope_event_part (char *source, int ac, char **av)
01136 {
01137   if (ac < 1 || ac > 2)
01138     return MOD_CONT;
01139   do_part (source, ac, av);
01140   return MOD_CONT;
01141 }
01142 
01143 int
01144 anope_event_whois (char *source, int ac, char **av)
01145 {
01146   if (source && ac >= 1)
01147     {
01148       m_whois (source, av[0]);
01149     }
01150   return MOD_CONT;
01151 }
01152 
01153 /* EVENT: SERVER */
01154 int
01155 anope_event_server (char *source, int ac, char **av)
01156 {
01157   if (!stricmp (av[1], "1"))
01158     {
01159       uplink = sstrdup (av[0]);
01160     }
01161   do_server (source, av[0], av[1], av[2], NULL);
01162   return MOD_CONT;
01163 }
01164 
01165 int
01166 anope_event_squit (char *source, int ac, char **av)
01167 {
01168   if (ac != 2)
01169     return MOD_CONT;
01170   do_squit (source, ac, av);
01171   return MOD_CONT;
01172 }
01173 
01174 int
01175 anope_event_quit (char *source, int ac, char **av)
01176 {
01177   if (ac != 1)
01178     return MOD_CONT;
01179   do_quit (source, ac, av);
01180   return MOD_CONT;
01181 }
01182 
<