unreal32.c

Go to the documentation of this file.
00001 /* Unreal IRCD 3.2.x functions
00002  *
00003  * (C) 2003-2007 Anope Team
00004  * Contact us at info@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  *
00012  */
00013 
00014 /*************************************************************************/
00015 
00016 #include "services.h"
00017 #include "pseudo.h"
00018 #include "unreal32.h"
00019 
00020 IRCDVar myIrcd[] = {
00021     {"UnrealIRCd 3.2.x",        /* ircd name */
00022      "+oS",                     /* nickserv mode */
00023      "+oS",                     /* chanserv mode */
00024      "+oS",                     /* memoserv mode */
00025      "+oS",                     /* hostserv mode */
00026      "+ioS",                    /* operserv mode */
00027      "+oS",                     /* botserv mode  */
00028      "+oS",                     /* helpserv mode */
00029      "+iS",                     /* Dev/Null mode */
00030      "+ioS",                    /* Global mode   */
00031      "+oS",                     /* nickserv alias mode */
00032      "+oS",                     /* chanserv alias mode */
00033      "+oS",                     /* memoserv alias mode */
00034      "+ioS",                    /* hostserv alias mode */
00035      "+ioS",                    /* operserv alias mode */
00036      "+oS",                     /* botserv alias mode  */
00037      "+oS",                     /* helpserv alias mode */
00038      "+iS",                     /* Dev/Null alias mode */
00039      "+ioS",                    /* Global alias mode   */
00040      "+qS",                     /* Used by BotServ Bots */
00041      5,                         /* Chan Max Symbols     */
00042      "-cilmnpstuzACGHKMNOQRSTV",        /* Modes to Remove */
00043      "+ao",                     /* Channel Umode used by Botserv bots */
00044      1,                         /* SVSNICK */
00045      1,                         /* Vhost  */
00046      1,                         /* Has Owner */
00047      "+q",                      /* Mode to set for an owner */
00048      "-q",                      /* Mode to unset for an owner */
00049      "+a",                      /* Mode to set for channel admin */
00050      "-a",                      /* Mode to unset for channel admin */
00051      "+rd",                     /* Mode On Reg          */
00052      NULL,                      /* Mode on ID for Roots */
00053      NULL,                      /* Mode on ID for Admins */
00054      NULL,                      /* Mode on ID for Opers */
00055      "-r+d",                    /* Mode on UnReg        */
00056      "-r+d",                    /* Mode on Nick Change  */
00057      1,                         /* Supports SGlines     */
00058      1,                         /* Supports SQlines     */
00059      1,                         /* Supports SZlines     */
00060      1,                         /* Supports Halfop +h   */
00061      3,                         /* Number of server args */
00062      0,                         /* Join 2 Set           */
00063      0,                         /* Join 2 Message       */
00064      1,                         /* Has exceptions +e    */
00065      1,                         /* TS Topic Forward     */
00066      0,                         /* TS Topci Backward    */
00067      UMODE_S,                   /* Protected Umode      */
00068      0,                         /* Has Admin            */
00069      0,                         /* Chan SQlines         */
00070      0,                         /* Quit on Kill         */
00071      1,                         /* SVSMODE unban        */
00072      1,                         /* Has Protect          */
00073      1,                         /* Reverse              */
00074      1,                         /* Chan Reg             */
00075      CMODE_r,                   /* Channel Mode         */
00076      1,                         /* vidents              */
00077      1,                         /* svshold              */
00078      1,                         /* time stamp on mode   */
00079      1,                         /* NICKIP               */
00080      1,                         /* O:LINE               */
00081      1,                         /* UMODE               */
00082      1,                         /* VHOST ON NICK        */
00083      1,                         /* Change RealName      */
00084      CMODE_K,                   /* No Knock             */
00085      CMODE_A,                   /* Admin Only           */
00086      DEFAULT_MLOCK,             /* Default MLOCK       */
00087      UMODE_x,                   /* Vhost Mode           */
00088      1,                         /* +f                   */
00089      1,                         /* +L                   */
00090      CMODE_f,                   /* +f Mode                          */
00091      CMODE_L,                   /* +L Mode                          */
00092      0,                         /* On nick change check if they could be identified */
00093      1,                         /* No Knock requires +i */
00094      NULL,                      /* CAPAB Chan Modes             */
00095      1,                         /* We support Unreal TOKENS */
00096      0,                         /* TOKENS are CASE Sensitive */
00097      1,                         /* TIME STAMPS are BASE64 */
00098      1,                         /* +I support */
00099      '&',                       /* SJOIN ban char */
00100      '\"',                      /* SJOIN except char */
00101      '\'',                      /* SJOIN invite char */
00102      1,                         /* Can remove User Channel Modes with SVSMODE */
00103      0,                         /* Sglines are not enforced until user reconnects */
00104      "x",                       /* vhost char */
00105      0,                         /* ts6 */
00106      1,                         /* support helper umode */
00107      0,                         /* p10 */
00108      NULL,                      /* character set */
00109      1,                         /* reports sync state */
00110      }
00111     ,
00112     {NULL}
00113 };
00114 
00115 IRCDCAPAB myIrcdcap[] = {
00116     {
00117      CAPAB_NOQUIT,              /* NOQUIT       */
00118      0,                         /* TSMODE       */
00119      0,                         /* UNCONNECT    */
00120      CAPAB_NICKIP,              /* NICKIP       */
00121      0,                         /* SJOIN        */
00122      CAPAB_ZIP,                 /* ZIP          */
00123      0,                         /* BURST        */
00124      0,                         /* TS5          */
00125      0,                         /* TS3          */
00126      0,                         /* DKEY         */
00127      0,                         /* PT4          */
00128      0,                         /* SCS          */
00129      0,                         /* QS           */
00130      0,                         /* UID          */
00131      0,                         /* KNOCK        */
00132      0,                         /* CLIENT       */
00133      0,                         /* IPV6         */
00134      0,                         /* SSJ5         */
00135      0,                         /* SN2          */
00136      CAPAB_TOKEN,               /* TOKEN        */
00137      0,                         /* VHOST        */
00138      CAPAB_SSJ3,                /* SSJ3         */
00139      CAPAB_NICK2,               /* NICK2        */
00140      CAPAB_UMODE2,              /* UMODE2       */
00141      CAPAB_VL,                  /* VL           */
00142      CAPAB_TLKEXT,              /* TLKEXT       */
00143      0,                         /* DODKEY       */
00144      0,                         /* DOZIP        */
00145      CAPAB_CHANMODE,            /* CHANMODE             */
00146      CAPAB_SJB64,
00147      CAPAB_NICKCHARS,
00148      }
00149 };
00150 
00151 
00152 unsigned long umodes[128] = {
00153     0, 0, 0,                    /* Unused */
00154     0, 0, 0,                    /* Unused */
00155     0, 0, 0,                    /* Unused, Unused, Horzontal Tab */
00156     0, 0, 0,                    /* Line Feed, Unused, Unused */
00157     0, 0, 0,                    /* Carriage Return, Unused, Unused */
00158     0, 0, 0,                    /* Unused */
00159     0, 0, 0,                    /* Unused */
00160     0, 0, 0,                    /* Unused */
00161     0, 0, 0,                    /* Unused */
00162     0, 0, 0,                    /* Unused */
00163     0, 0, 0,                    /* Unused, Unused, Space */
00164     0, 0, 0,                    /* ! " #  */
00165     0, 0, 0,                    /* $ % &  */
00166     0, 0, 0,                    /* ! ( )  */
00167     0, 0, 0,                    /* * + ,  */
00168     0, 0, 0,                    /* - . /  */
00169     0, 0,                       /* 0 1 */
00170     0, 0,                       /* 2 3 */
00171     0, 0,                       /* 4 5 */
00172     0, 0,                       /* 6 7 */
00173     0, 0,                       /* 8 9 */
00174     0, 0,                       /* : ; */
00175     0, 0, 0,                    /* < = > */
00176     0, 0,                       /* ? @ */
00177     UMODE_A, UMODE_B, UMODE_C,  /* A B C */
00178     0, 0, 0,                    /* D E F */
00179     UMODE_G, UMODE_H, 0,        /* G H I */
00180     0, 0, 0,                    /* J K L */
00181     0, UMODE_N, UMODE_O,        /* M N O */
00182     0, 0, UMODE_R,              /* P Q R */
00183     UMODE_S, UMODE_T, 0,        /* S T U */
00184     UMODE_V, UMODE_W, 0,        /* V W X */
00185     0,                          /* Y */
00186     0,                          /* Z */
00187     0, 0, 0,                    /* [ \ ] */
00188     0, 0, 0,                    /* ^ _ ` */
00189     UMODE_a, 0, 0,              /* a b c */
00190     UMODE_d, 0, 0,              /* d e f */
00191     UMODE_g, UMODE_h, UMODE_i,  /* g h i */
00192     0, 0, 0,                    /* j k l */
00193     0, 0, UMODE_o,              /* m n o */
00194     UMODE_p, UMODE_q, UMODE_r,  /* p q r */
00195     UMODE_s, UMODE_t, 0,        /* s t u */
00196     UMODE_v, UMODE_w, UMODE_x,  /* v w x */
00197     0,                          /* y */
00198     UMODE_z,                    /* z */
00199     0, 0, 0,                    /* { | } */
00200     0, 0                        /* ~ ‚ */
00201 };
00202 
00203 char myCsmodes[128] = {
00204     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00205     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00206 
00207     0,
00208     0,
00209     0, 0, 0,
00210     'h',                        /* (37) % Channel halfops */
00211     'b',                        /* (38) & bans */
00212     0, 0, 0,
00213     'q',
00214 
00215     'v', 0, 0, 0, 0,
00216     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00217 
00218     'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00219     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00220 
00221     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00222     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'a', 0
00223 };
00224 
00225 CMMode myCmmodes[128] = {
00226     {NULL}, {NULL}, {NULL},
00227     {NULL}, {NULL}, {NULL},
00228     {NULL}, {NULL}, {NULL},
00229     {NULL}, {NULL}, {NULL},
00230     {NULL}, {NULL}, {NULL},
00231     {NULL}, {NULL}, {NULL},
00232     {NULL}, {NULL}, {NULL},
00233     {NULL}, {NULL}, {NULL},
00234     {NULL}, {NULL}, {NULL},
00235     {NULL}, {NULL}, {NULL},
00236     {NULL}, {NULL}, {NULL},
00237     {NULL}, {NULL}, {NULL},
00238     {NULL}, {NULL}, {NULL},
00239     {NULL}, {NULL}, {NULL},
00240     {NULL}, {NULL}, {NULL},
00241     {NULL}, {NULL}, {NULL},
00242     {NULL}, {NULL}, {NULL},
00243     {NULL}, {NULL}, {NULL},
00244     {NULL}, {NULL}, {NULL},
00245     {NULL}, {NULL}, {NULL},
00246     {NULL}, {NULL}, {NULL},
00247     {NULL}, {NULL}, {NULL},
00248     {NULL}, {NULL}, {NULL},     /* BCD */
00249     {NULL}, {NULL}, {NULL},     /* EFG */
00250     {NULL},                     /* H */
00251     {add_invite, del_invite},   /* I */
00252     {NULL},                     /* J */
00253     {NULL}, {NULL}, {NULL},     /* KLM */
00254     {NULL}, {NULL}, {NULL},     /* NOP */
00255     {NULL}, {NULL}, {NULL},     /* QRS */
00256     {NULL}, {NULL}, {NULL},     /* TUV */
00257     {NULL}, {NULL}, {NULL},     /* WXY */
00258     {NULL},                     /* Z */
00259     {NULL}, {NULL},             /* (char 91 - 92) */
00260     {NULL}, {NULL}, {NULL},     /* (char 93 - 95) */
00261     {NULL},                     /* ` (char 96) */
00262     {NULL},                     /* a (char 97) */
00263     {add_ban, del_ban},         /* b */
00264     {NULL}, {NULL},             /* cd */
00265     {add_exception, del_exception},
00266     {NULL}, {NULL},
00267     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00268     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
00269     {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}
00270 };
00271 
00272 CBMode myCbmodes[128] = {
00273     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00274     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00275     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00276     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00277     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00278     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00279     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00280     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00281     {0},
00282     {CMODE_A, CBM_NO_USER_MLOCK, NULL, NULL},
00283     {0},                        /* B */
00284     {CMODE_C, 0, NULL, NULL},   /* C */
00285     {0},                        /* D */
00286     {0},                        /* E */
00287     {0},                        /* F */
00288     {CMODE_G, 0, NULL, NULL},   /* G */
00289     {0},                        /* H */
00290     {0},                        /* I */
00291     {0},                        /* J */
00292     {CMODE_K, 0, NULL, NULL},   /* K */
00293     {CMODE_L, 0, set_redirect, cs_set_redirect},
00294     {CMODE_M, 0, NULL, NULL},   /* M */
00295     {CMODE_N, 0, NULL, NULL},   /* N */
00296     {CMODE_O, CBM_NO_USER_MLOCK, NULL, NULL},
00297     {0},                        /* P */
00298     {CMODE_Q, 0, NULL, NULL},   /* Q */
00299     {CMODE_R, 0, NULL, NULL},   /* R */
00300     {CMODE_S, 0, NULL, NULL},   /* S */
00301     {CMODE_T, 0, NULL, NULL},   /* T */
00302     {0},                        /* U */
00303     {CMODE_V, 0, NULL, NULL},   /* V */
00304     {0},                        /* W */
00305     {0},                        /* X */
00306     {0},                        /* Y */
00307     {0},                        /* Z */
00308     {0}, {0}, {0}, {0}, {0}, {0},
00309     {0},                        /* a */
00310     {0},                        /* b */
00311     {CMODE_c, 0, NULL, NULL},
00312     {0},                        /* d */
00313     {0},                        /* e */
00314     {CMODE_f, 0, set_flood, cs_set_flood},
00315     {0},                        /* g */
00316     {0},                        /* h */
00317     {CMODE_i, 0, NULL, NULL},
00318     {0},                        /* j */
00319     {CMODE_k, 0, chan_set_key, cs_set_key},
00320     {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit},
00321     {CMODE_m, 0, NULL, NULL},
00322     {CMODE_n, 0, NULL, NULL},
00323     {0},                        /* o */
00324     {CMODE_p, 0, NULL, NULL},
00325     {0},                        /* q */
00326     {CMODE_r, CBM_NO_MLOCK, NULL, NULL},
00327     {CMODE_s, 0, NULL, NULL},
00328     {CMODE_t, 0, NULL, NULL},
00329     {CMODE_u, 0, NULL, NULL},
00330     {0},                        /* v */
00331     {0},                        /* w */
00332     {0},                        /* x */
00333     {0},                        /* y */
00334     {CMODE_z, 0, NULL, NULL},
00335     {0}, {0}, {0}, {0}
00336 };
00337 
00338 CBModeInfo myCbmodeinfos[] = {
00339     {'c', CMODE_c, 0, NULL, NULL},
00340     {'f', CMODE_f, 0, get_flood, cs_get_flood},
00341     {'i', CMODE_i, 0, NULL, NULL},
00342     {'k', CMODE_k, 0, get_key, cs_get_key},
00343     {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit},
00344     {'m', CMODE_m, 0, NULL, NULL},
00345     {'n', CMODE_n, 0, NULL, NULL},
00346     {'p', CMODE_p, 0, NULL, NULL},
00347     {'r', CMODE_r, 0, NULL, NULL},
00348     {'s', CMODE_s, 0, NULL, NULL},
00349     {'t', CMODE_t, 0, NULL, NULL},
00350     {'u', CMODE_u, 0, NULL, NULL},
00351     {'z', CMODE_z, 0, NULL, NULL},
00352     {'A', CMODE_A, 0, NULL, NULL},
00353     {'C', CMODE_C, 0, NULL, NULL},
00354     {'G', CMODE_G, 0, NULL, NULL},
00355     {'K', CMODE_K, 0, NULL, NULL},
00356     {'L', CMODE_L, 0, get_redirect, cs_get_redirect},
00357     {'M', CMODE_M, 0, NULL, NULL},
00358     {'N', CMODE_N, 0, NULL, NULL},
00359     {'O', CMODE_O, 0, NULL, NULL},
00360     {'Q', CMODE_Q, 0, NULL, NULL},
00361     {'R', CMODE_R, 0, NULL, NULL},
00362     {'S', CMODE_S, 0, NULL, NULL},
00363     {'T', CMODE_T, 0, NULL, NULL},
00364     {'V', CMODE_V, 0, NULL, NULL},
00365     {0}
00366 };
00367 
00368 CUMode myCumodes[128] = {
00369     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00370     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00371     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00372     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00373 
00374     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00375     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00376     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00377     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00378 
00379     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00380     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00381     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00382     {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
00383 
00384     {0},
00385 
00386     {CUS_PROTECT, CUF_PROTECT_BOTSERV, check_valid_op},
00387     {0},                        /* b */
00388     {0},                        /* c */
00389     {0},                        /* d */
00390     {0},                        /* e */
00391     {0},                        /* f */
00392     {0},                        /* g */
00393     {CUS_HALFOP, 0, check_valid_op},
00394     {0},                        /* i */
00395     {0},                        /* j */
00396     {0},                        /* k */
00397     {0},                        /* l */
00398     {0},                        /* m */
00399     {0},                        /* n */
00400     {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op},
00401     {0},                        /* p */
00402     {CUS_OWNER, 0, check_valid_op},
00403     {0},                        /* r */
00404     {0},                        /* s */
00405     {0},                        /* t */
00406     {0},                        /* u */
00407     {CUS_VOICE, 0, NULL},
00408     {0},                        /* w */
00409     {0},                        /* x */
00410     {0},                        /* y */
00411     {0},                        /* z */
00412     {0}, {0}, {0}, {0}, {0}
00413 };
00414 
00415 
00416 void unreal_set_umode(User * user, int ac, char **av)
00417 {
00418     int add = 1;                /* 1 if adding modes, 0 if deleting */
00419     char *modes = av[0];
00420 
00421     ac--;
00422 
00423     if (!user || !modes) {
00424         /* Prevent NULLs from doing bad things */
00425         return;
00426     }
00427 
00428     if (debug)
00429         alog("debug: Changing mode for %s to %s", user->nick, modes);
00430 
00431     while (*modes) {
00432 
00433         /* This looks better, much better than "add ? (do_add) : (do_remove)".
00434          * At least this is readable without paying much attention :) -GD
00435          */
00436         if (add)
00437             user->mode |= umodes[(int) *modes];
00438         else
00439             user->mode &= ~umodes[(int) *modes];
00440 
00441         switch (*modes++) {
00442         case '+':
00443             add = 1;
00444             break;
00445         case '-':
00446             add = 0;
00447             break;
00448         case 'd':
00449             if (ac <= 0) {
00450                 break;
00451             }
00452             ac--;
00453             av++;
00454             if (av) {
00455                 user->svid = strtoul(*av, NULL, 0);
00456             }
00457             break;
00458         case 'o':
00459             if (add) {
00460                 opcnt++;
00461                 if (WallOper) {
00462                     anope_cmd_global(s_OperServ,
00463                                      "\2%s\2 is now an IRC operator.",
00464                                      user->nick);
00465                 }
00466                 display_news(user, NEWS_OPER);
00467             } else {
00468                 opcnt--;
00469             }
00470             break;
00471         case 'r':
00472             if (add && !nick_identified(user)) {
00473                 common_svsmode(user, "-r", NULL);
00474                 user->mode &= ~UMODE_r;
00475             }
00476             break;
00477         case 'x':
00478             update_host(user);
00479             break;
00480         }
00481     }
00482 }
00483 
00484 
00485 
00486 
00487 /* Event: PROTOCTL */
00488 int anope_event_capab(char *source, int ac, char **av)
00489 {
00490     capab_parse(ac, av);
00491     return MOD_CONT;
00492 }
00493 
00494 /* SVSNOOP */
00495 void unreal_cmd_svsnoop(char *server, int set)
00496 {
00497     send_cmd(NULL, "%s %s %s", send_token("SVSNOOP", "f"), server,
00498              (set ? "+" : "-"));
00499 }
00500 
00501 void unreal_cmd_svsadmin(char *server, int set)
00502 {
00503     unreal_cmd_svsnoop(server, set);
00504 }
00505 
00506 void unreal_cmd_remove_akill(char *user, char *host)
00507 {
00508     send_cmd(NULL, "%s - G %s %s %s", send_token("TKL", "BD"), user, host,
00509              s_OperServ);
00510 }
00511 
00512 void unreal_cmd_topic(char *whosets, char *chan, char *whosetit,
00513                       char *topic, time_t when)
00514 {
00515     send_cmd(whosets, "%s %s %s %lu :%s", send_token("TOPIC", ")"), chan,
00516              whosetit, (unsigned long int) when, topic);
00517 }
00518 
00519 void unreal_cmd_vhost_off(User * u)
00520 {
00521     if (UseSVS2MODE) {
00522         send_cmd(s_HostServ, "%s %s -xt", send_token("SVS2MODE", "v"),
00523                  u->nick);
00524     } else {
00525         send_cmd(s_HostServ, "%s %s -xt", send_token("SVSMODE", "n"),
00526                  u->nick);
00527     }
00528     notice_lang(s_HostServ, u, HOST_OFF_UNREAL, u->nick,
00529                 myIrcd->vhostchar);
00530 }
00531 
00532 void unreal_cmd_akill(char *user, char *host, char *who, time_t when,
00533                       time_t expires, char *reason)
00534 {
00535     send_cmd(NULL, "%s + G %s %s %s %ld %ld :%s", send_token("TKL", "BD"),
00536              user, host, who, (long int) time(NULL) + 86400 * 2,
00537              (long int) when, reason);
00538 }
00539 
00540 /*
00541 ** svskill
00542 **  parv[0] = servername
00543 **  parv[1] = client
00544 **  parv[2] = kill message
00545 */
00546 void unreal_cmd_svskill(char *source, char *user, char *buf)
00547 {
00548     if (!source || !user || !buf) {
00549         return;
00550     }
00551     send_cmd(source, "%s %s :%s", send_token("SVSKILL", "h"), user, buf);
00552 }
00553 
00554 /*
00555  * m_svsmode() added by taz
00556  * parv[0] - sender
00557  * parv[1] - username to change mode for
00558  * parv[2] - modes to change
00559  * parv[3] - Service Stamp (if mode == d)
00560  */
00561 void unreal_cmd_svsmode(User * u, int ac, char **av)
00562 {
00563     if (ac >= 1) {
00564         if (!u || !av[0]) {
00565             return;
00566         }
00567         if (UseSVS2MODE) {
00568             send_cmd(ServerName, "%s %s %s%s%s",
00569                      send_token("SVS2MODE", "v"), u->nick, av[0],
00570                      (ac == 2 ? " " : ""), (ac == 2 ? av[1] : ""));
00571         } else {
00572             send_cmd(ServerName, "%s %s %s%s%s",
00573                      send_token("SVSMODE", "n"), u->nick, av[0],
00574                      (ac == 2 ? " " : ""), (ac == 2 ? av[1] : ""));
00575         }
00576     }
00577 }
00578 
00579 /* 372 */
00580 void unreal_cmd_372(char *source, char *msg)
00581 {
00582     send_cmd(ServerName, "372 %s :- %s", source, msg);
00583 }
00584 
00585 void unreal_cmd_372_error(char *source)
00586 {
00587     send_cmd(ServerName, "422 %s :- MOTD file not found!  Please "
00588              "contact your IRC administrator.", source);
00589 }
00590 
00591 void unreal_cmd_375(char *source)
00592 {
00593     send_cmd(ServerName, "375 %s :- %s Message of the Day",
00594              source, ServerName);
00595 }
00596 
00597 void unreal_cmd_376(char *source)
00598 {
00599     send_cmd(ServerName, "376 %s :End of /MOTD command.", source);
00600 }
00601 
00602 void unreal_cmd_nick(char *nick, char *name, char *modes)
00603 {
00604     EnforceQlinedNick(nick, NULL);
00605     send_cmd(NULL, "%s %s 1 %ld %s %s %s 0 %s %s%s :%s",
00606              send_token("NICK", "&"), nick, (long int) time(NULL),
00607              ServiceUser, ServiceHost, ServerName, modes, ServiceHost,
00608              (myIrcd->nickip ? " *" : " "), name);
00609     unreal_cmd_sqline(nick, "Reserved for services");
00610 }
00611 
00612 void unreal_cmd_guest_nick(char *nick, char *user, char *host, char *real,
00613                            char *modes)
00614 {
00615     send_cmd(NULL, "%s %s 1 %ld %s %s %s 0 %s %s%s :%s",
00616              send_token("NICK", "&"), nick, (long int) time(NULL), user,
00617              host, ServerName, modes, host, (myIrcd->nickip ? " *" : " "),
00618              real);
00619 }
00620 
00621 void unreal_cmd_mode(char *source, char *dest, char *buf)
00622 {
00623     if (!buf) {
00624         return;
00625     }
00626 
00627     send_cmd(source, "%s %s %s", send_token("MODE", "G"), dest, buf);
00628 }
00629 
00630 void unreal_cmd_bot_nick(char *nick, char *user, char *host, char *real,
00631                          char *modes)
00632 {
00633     EnforceQlinedNick(nick, s_BotServ);
00634     send_cmd(NULL, "%s %s 1 %ld %s %s %s 0 %s %s%s :%s",
00635              send_token("NICK", "&"), nick, (long int) time(NULL), user,
00636              host, ServerName, modes, host, (myIrcd->nickip ? " *" : " "),
00637              real);
00638     unreal_cmd_sqline(nick, "Reserved for services");
00639 }
00640 
00641 void unreal_cmd_kick(char *source, char *chan, char *user, char *buf)
00642 {
00643     if (buf) {
00644         send_cmd(source, "%s %s %s :%s", send_token("KICK", "H"), chan,
00645                  user, buf);
00646     } else {
00647         send_cmd(source, "%s %s %s", send_token("KICK", "H"), chan, user);
00648     }
00649 }
00650 
00651 void unreal_cmd_notice_ops(char *source, char *dest, char *buf)
00652 {
00653     if (!buf) {
00654         return;
00655     }
00656 
00657     send_cmd(NULL, "%s @%s :%s", send_token("NOTICE", "B"), dest, buf);
00658 }
00659 
00660 
00661 void unreal_cmd_notice(char *source, char *dest, char *buf)
00662 {
00663     if (!buf) {
00664         return;
00665     }
00666 
00667     if (NSDefFlags & NI_MSG) {
00668         unreal_cmd_privmsg2(source, dest, buf);
00669     } else {
00670         send_cmd(source, "%s %s :%s", send_token("NOTICE", "B"), dest,
00671                  buf);
00672     }
00673 }
00674 
00675 void unreal_cmd_notice2(char *source, char *dest, char *msg)
00676 {
00677     send_cmd(source, "%s %s :%s", send_token("NOTICE", "B"), dest, msg);
00678 }
00679 
00680 void unreal_cmd_privmsg(char *source, char *dest, char *buf)
00681 {
00682     if (!buf) {
00683         return;
00684     }
00685 
00686     send_cmd(source, "%s %s :%s", send_token("PRIVMSG", "!"), dest, buf);
00687 }
00688 
00689 void unreal_cmd_privmsg2(char *source, char *dest, char *msg)
00690 {
00691     send_cmd(source, "%s %s :%s", send_token("PRIVMSG", "!"), dest, msg);
00692 }
00693 
00694 void unreal_cmd_serv_notice(char *source, char *dest, char *msg)
00695 {
00696     send_cmd(source, "%s $%s :%s", send_token("NOTICE", "B"), dest, msg);
00697 }
00698 
00699 void unreal_cmd_serv_privmsg(char *source, char *dest, char *msg)
00700 {
00701     send_cmd(source, "%s $%s :%s", send_token("PRIVMSG", "!"), dest, msg);
00702 }
00703 
00704 void unreal_cmd_bot_chan_mode(char *nick, char *chan)
00705 {
00706     anope_cmd_mode(nick, chan, "%s %s %s", myIrcd->botchanumode, nick,
00707                    nick);
00708 }
00709 
00710 void unreal_cmd_351(char *source)
00711 {
00712     send_cmd(ServerName, "351 %s Anope-%s %s :%s - %s (%s) -- %s",
00713              source, version_number, ServerName, myIrcd->name,
00714              version_flags, EncModule, version_build);
00715 }
00716 
00717 /* QUIT */
00718 void unreal_cmd_quit(char *source, char *buf)
00719 {
00720     if (buf) {
00721         send_cmd(source, "%s :%s", send_token("QUIT", ","), buf);
00722     } else {
00723         send_cmd(source, "%s", send_token("QUIT", ","));
00724     }
00725 }
00726 
00727 /* PROTOCTL */
00728 /*
00729    NICKv2 = Nick Version 2
00730    VHP    = Sends hidden host 
00731    UMODE2 = sends UMODE2 on user modes
00732    NICKIP = Sends IP on NICK
00733    TOKEN  = Use tokens to talk
00734    SJ3    = Supports SJOIN
00735    NOQUIT = No Quit
00736    TKLEXT = Extended TKL we don't use it but best to have it
00737    SJB64  = Base64 encoded time stamps
00738    VL     = Version Info
00739    NS     = Numeric Server
00740 
00741 */
00742 void unreal_cmd_capab()
00743 {
00744     if (UseTokens) {
00745         if (Numeric) {
00746             send_cmd(NULL,
00747                      "PROTOCTL NICKv2 VHP UMODE2 NICKIP TOKEN SJOIN SJOIN2 SJ3 NOQUIT TKLEXT SJB64 VL");
00748         } else {
00749             send_cmd(NULL,
00750                      "PROTOCTL NICKv2 VHP UMODE2 NICKIP TOKEN SJOIN SJOIN2 SJ3 NOQUIT TKLEXT SJB64");
00751         }
00752     } else {
00753         if (Numeric) {
00754             send_cmd(NULL,
00755                      "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT SJB64 VL");
00756         } else {
00757             send_cmd(NULL,
00758                      "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT SJB64");
00759         }
00760     }
00761 }
00762 
00763 /* PASS */
00764 void unreal_cmd_pass(char *pass)
00765 {
00766     send_cmd(NULL, "PASS :%s", pass);
00767 }
00768 
00769 /* SERVER name hop descript */
00770 /* Unreal 3.2 actually sends some info about itself in the descript area */
00771 void unreal_cmd_server(char *servname, int hop, char *descript)
00772 {
00773     if (Numeric) {
00774         send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", servname, hop, Numeric,
00775                  descript);
00776     } else {
00777         send_cmd(NULL, "SERVER %s %d :%s", servname, hop, descript);
00778     }
00779 }
00780 
00781 /* PONG */
00782 void unreal_cmd_pong(char *servname, char *who)
00783 {
00784     send_cmd(servname, "%s %s", send_token("PONG", "9"), who);
00785 }
00786 
00787 /* JOIN */
00788 void unreal_cmd_join(char *user, char *channel, time_t chantime)
00789 {
00790     send_cmd(ServerName, "%s !%s %s :%s",
00791              send_token("SJOIN", "~"), base64enc((long int) chantime),
00792              channel, user);
00793     /* send_cmd(user, "%s %s", send_token("JOIN", "C"), channel); */
00794 }
00795 
00796 /* unsqline
00797 **  parv[0] = sender
00798 **  parv[1] = nickmask
00799 */
00800 void unreal_cmd_unsqline(char *user)
00801 {
00802     if (!user) {
00803         return;
00804     }
00805     send_cmd(NULL, "%s %s", send_token("UNSQLINE", "d"), user);
00806 }
00807 
00808 /* CHGHOST */
00809 void unreal_cmd_chghost(char *nick, char *vhost)
00810 {
00811     if (!nick || !vhost) {
00812         return;
00813     }
00814     send_cmd(ServerName, "%s %s %s", send_token("CHGHOST", "AL"), nick,
00815              vhost);
00816 }
00817 
00818 /* CHGIDENT */
00819 void unreal_cmd_chgident(char *nick, char *vIdent)
00820 {
00821     if (!nick || !vIdent) {
00822         return;
00823     }
00824     send_cmd(ServerName, "%s %s %s", send_token("CHGIDENT", "AZ"), nick,
00825              vIdent);
00826 }
00827 
00828 /* INVITE */
00829 void unreal_cmd_invite(char *source, char *chan, char *nick)
00830 {
00831     if (!source || !chan || !nick) {
00832         return;
00833     }
00834 
00835     send_cmd(source, "%s %s %s", send_token("INVITE", "*"), nick, chan);
00836 }
00837 
00838 /* PART */
00839 void unreal_cmd_part(char *nick, char *chan, char *buf)
00840 {
00841     if (!nick || !chan) {
00842         return;
00843     }
00844 
00845     if (buf) {
00846         send_cmd(nick, "%s %s :%s", send_token("PART", "D"), chan, buf);
00847     } else {
00848         send_cmd(nick, "%s %s", send_token("PART", "D"), chan);
00849     }
00850 }
00851 
00852 /* 391    RPL_TIME ":%s 391 %s %s :%s" */
00853 void unreal_cmd_391(char *source, char *timestr)
00854 {
00855     if (!timestr) {
00856         return;
00857     }
00858     send_cmd(ServerName, "391 %s %s :%s", source, ServerName, timestr);
00859 }
00860 
00861 /* 250 */
00862 void unreal_cmd_250(char *buf)
00863 {
00864     if (!buf) {
00865         return;
00866     }
00867 
00868     send_cmd(NULL, "250 %s", buf);
00869 }
00870 
00871 /* 307 */
00872 void unreal_cmd_307(char *buf)
00873 {
00874     if (!buf) {
00875         return;
00876     }
00877 
00878     send_cmd(ServerName, "307 %s", buf);
00879 }
00880 
00881 /* 311 */
00882 void unreal_cmd_311(char *buf)
00883 {
00884     if (!buf) {
00885         return;
00886     }
00887 
00888     send_cmd(ServerName, "311 %s", buf);
00889 }
00890 
00891 /* 312 */
00892 void unreal_cmd_312(char *buf)
00893 {
00894     if (!buf) {
00895         return;
00896     }
00897 
00898     send_cmd(ServerName, "312 %s", buf);
00899 }
00900 
00901 /* 317 */
00902 void unreal_cmd_317(char *buf)
00903 {
00904     if (!buf) {
00905         return;
00906     }
00907 
00908     send_cmd(ServerName, "317 %s", buf);
00909 }
00910 
00911 /* 219 */
00912 void unreal_cmd_219(char *source, char *letter)
00913 {
00914     if (!source) {
00915         return;
00916     }
00917 
00918     if (letter) {
00919         send_cmd(NULL, "219 %s %c :End of /STATS report.", source,
00920                  *letter);
00921     } else {
00922         send_cmd(NULL, "219 %s l :End of /STATS report.", source);
00923     }
00924 }
00925 
00926 /* 401 */
00927 void unreal_cmd_401(char *source, char *who)
00928 {
00929     if (!source || !who) {
00930         return;
00931     }
00932     send_cmd(ServerName, "401 %s %s :No such service.", source, who);
00933 }
00934 
00935 /* 318 */
00936 void unreal_cmd_318(char *source, char *who)
00937 {
00938     if (!source || !who) {
00939         return;
00940     }
00941 
00942     send_cmd(ServerName, "318 %s %s :End of /WHOIS list.", source, who);
00943 }
00944 
00945 /* 242 */
00946 void unreal_cmd_242(char *buf)
00947 {
00948     if (!buf) {
00949         return;
00950     }
00951 
00952     send_cmd(NULL, "242 %s", buf);
00953 }
00954 
00955 /* 243 */
00956 void unreal_cmd_243(char *buf)
00957 {
00958     if (!buf) {
00959         return;
00960     }
00961 
00962     send_cmd(NULL, "243 %s", buf);
00963 }
00964 
00965 /* 211 */
00966 void unreal_cmd_211(char *buf)
00967 {
00968     if (!buf) {
00969         return;
00970     }
00971 
00972     send_cmd(NULL, "211 %s", buf);
00973 }
00974 
00975 /* GLOBOPS */
00976 void unreal_cmd_global(char *source, char *buf)
00977 {
00978     if (!buf) {
00979         return;
00980     }
00981 
00982     send_cmd(source ? source : ServerName, "%s :%s",
00983              send_token("GLOBOPS", "]"), buf);
00984 }
00985 
00986 /* GLOBOPS - to handle old WALLOPS */
00987 void unreal_cmd_global_legacy(char *source, char *fmt)
00988 {
00989     send_cmd(source ? source : ServerName, "%s :%s",
00990              send_token("GLOBOPS", "]"), fmt);
00991 }
00992 
00993 /* SQLINE */
00994 /*
00995 **  parv[0] = sender
00996 **  parv[1] = nickmask
00997 **  parv[2] = reason
00998 ** 
00999 ** - Unreal will translate this to TKL for us
01000 **
01001 */
01002 void unreal_cmd_sqline(char *mask, char *reason)
01003 {
01004     if (!mask || !reason) {
01005         return;
01006     }
01007 
01008     send_cmd(NULL, "%s %s :%s", send_token("SQLINE", "c"), mask, reason);
01009 }
01010 
01011 /* SQUIT */
01012 void unreal_cmd_squit(char *servname, char *message)
01013 {
01014     if (!servname || !message) {
01015         return;
01016     }
01017 
01018     send_cmd(NULL, "%s %s :%s", send_token("SQUIT", "-"), servname,
01019              message);
01020 }
01021 
01022 /*
01023 ** svso
01024 **      parv[0] = sender prefix
01025 **      parv[1] = nick
01026 **      parv[2] = options
01027 */
01028 void unreal_cmd_svso(char *source, char *nick, char *flag)
01029 {
01030     if (!source || !nick || !flag) {
01031         return;
01032     }
01033 
01034     send_cmd(source, "%s %s %s", send_token("SVSO", "BB"), nick, flag);
01035 }
01036 
01037 /* NICK <newnick>  */
01038 void unreal_cmd_chg_nick(char *oldnick, char *newnick)
01039 {
01040     if (!oldnick || !newnick) {
01041         return;
01042     }
01043 
01044     send_cmd(oldnick, "%s %s %ld", send_token("NICK", "&"), newnick,
01045              (long int) time(NULL));
01046 }
01047 
01048 /* SVSNICK */
01049 /*
01050 **      parv[0] = sender
01051 **      parv[1] = old nickname
01052 **      parv[2] = new nickname
01053 **      parv[3] = timestamp
01054 */
01055 void unreal_cmd_svsnick(char *source, char *guest, time_t when)
01056 {
01057     if (!source || !guest) {
01058         return;
01059     }
01060     send_cmd(NULL, "%s %s %s :%ld", send_token("SVSNICK", "e"), source,
01061              guest, (long int) when);
01062 }
01063 
01064 /* Functions that use serval cmd functions */
01065 
01066 void unreal_cmd_vhost_on(char *nick, char *vIdent, char *vhost)
01067 {
01068     if (!nick) {
01069         return;
01070     }
01071     if (vIdent) {
01072         unreal_cmd_chgident(nick, vIdent);
01073     }
01074     unreal_cmd_chghost(nick, vhost);
01075 }
01076 
01077 void unreal_cmd_connect(int servernum)
01078 {
01079     if (Numeric) {
01080         me_server =
01081             new_server(NULL, ServerName, ServerDesc, SERVER_ISME, Numeric);
01082     } else {
01083         me_server =
01084             new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL);
01085     }
01086 
01087     unreal_cmd_capab();
01088     if (servernum == 1) {
01089         unreal_cmd_pass(RemotePassword);
01090     }
01091     if (servernum == 2) {
01092         unreal_cmd_pass(RemotePassword2);
01093     }
01094     if (servernum == 3) {
01095         unreal_cmd_pass(RemotePassword3);
01096     }
01097     unreal_cmd_server(