summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bahamut.c6
-rw-r--r--src/base64.c14
-rw-r--r--src/botserv.c18
-rw-r--r--src/channels.c123
-rw-r--r--src/config.c68
-rw-r--r--src/datafiles.c155
-rw-r--r--src/dreamforge.c9
-rw-r--r--src/hostserv.c36
-rw-r--r--src/hybrid.c9
-rw-r--r--src/init.c15
-rw-r--r--src/main.c21
-rw-r--r--src/messages.c10
-rw-r--r--src/misc.c6
-rw-r--r--src/plexus.c9
-rw-r--r--src/ptlink.c9
-rw-r--r--src/rageircd.c9
-rw-r--r--src/ratbox.c1880
-rw-r--r--src/servers.c50
-rw-r--r--src/ultimate2.c9
-rw-r--r--src/ultimate3.c9
-rw-r--r--src/unreal31.c9
-rw-r--r--src/unreal32.c2
-rw-r--r--src/users.c105
-rw-r--r--src/viagra.c6
24 files changed, 2475 insertions, 112 deletions
diff --git a/src/bahamut.c b/src/bahamut.c
index 7cf512aa6..755c89ced 100644
--- a/src/bahamut.c
+++ b/src/bahamut.c
@@ -105,6 +105,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
NULL, /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
}
,
{NULL}
@@ -902,8 +904,6 @@ void anope_cmd_capab()
/* EVENT : SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
}
@@ -1668,7 +1668,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
/* this avoids "undefined symbol" messages of those whom try to load mods that
diff --git a/src/base64.c b/src/base64.c
index df14f09b0..80f1f7a2c 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -106,8 +106,8 @@ static const char Pad64 = '=';
int b64_encode(char *src, size_t srclength, char *target, size_t targsize)
{
size_t datalength = 0;
- u_char input[3];
- u_char output[4];
+ unsigned char input[3];
+ unsigned char output[4];
size_t i;
while (2 < srclength) {
@@ -280,10 +280,10 @@ int b64_decode(char *src, char *target, size_t targsize)
return (tarindex);
}
-char *encode_ip(u_char * ip)
+char *encode_ip(unsigned char *ip)
{
static char buf[25];
- u_char *cp;
+ unsigned char *cp;
struct in_addr ia; /* For IPv4 */
char *s_ip; /* Signed ip string */
@@ -295,7 +295,7 @@ char *encode_ip(u_char * ip)
} else {
s_ip = str_signed(ip);
ia.s_addr = inet_addr(s_ip);
- cp = (u_char *) ia.s_addr;
+ cp = (unsigned char *) ia.s_addr;
b64_encode((char *) &cp, sizeof(struct in_addr), buf, 25);
}
return buf;
@@ -378,14 +378,14 @@ static char *int_to_base64(long val)
static long base64_to_int(char *b64)
{
- int v = base64_to_int6_map[(u_char) * b64++];
+ int v = base64_to_int6_map[(unsigned char) *b64++];
if (!b64)
return 0;
while (*b64) {
v <<= 6;
- v += base64_to_int6_map[(u_char) * b64++];
+ v += base64_to_int6_map[(unsigned char) *b64++];
}
return v;
diff --git a/src/botserv.c b/src/botserv.c
index 438b5b6cd..066378743 100644
--- a/src/botserv.c
+++ b/src/botserv.c
@@ -818,13 +818,27 @@ static int delbot(BotInfo * bi)
BotInfo *findbot(char *nick)
{
BotInfo *bi;
+ Uid *ud;
+
+ /* to keep make strict happy */
+ ud = NULL;
if (!nick || !*nick)
return NULL;
- for (bi = botlists[tolower(*nick)]; bi; bi = bi->next)
- if (!stricmp(nick, bi->nick))
+ for (bi = botlists[tolower(*nick)]; bi; bi = bi->next) {
+ if (UseTS6 && ircd->ts6) {
+ ud = find_nickuid(nick);
+ }
+ if (!stricmp(nick, bi->nick)) {
return bi;
+ }
+ if (ud && UseTS6 && ircd->ts6) {
+ if (!stricmp(ud->nick, bi->nick)) {
+ return bi;
+ }
+ }
+ }
return NULL;
}
diff --git a/src/channels.c b/src/channels.c
index 240f308a0..48e4ec691 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -180,7 +180,6 @@ void chan_set_modes(const char *source, Channel * chan, int ac, char **av,
CBMode *cbm;
CMMode *cmm;
CUMode *cum;
- int botcheck = 0;
unsigned char botmode;
BotInfo *bi;
@@ -326,7 +325,7 @@ void chan_set_user_status(Channel * chan, User * user, int16 status)
{
struct u_chanlist *uc;
- if (HelpChannel
+ if (HelpChannel && ircd->supporthelper
&& (status == CUS_OP || status == (CUS_PROTECT | CUS_OP)
|| status == (CUS_OWNER | CUS_OP))
&& !stricmp(chan->name, HelpChannel)) {
@@ -524,7 +523,11 @@ void do_join(const char *source, int ac, char **av)
char *s, *t;
struct u_chanlist *c, *nextc;
- user = finduser(source);
+ if (UseTS6 && ircd->ts6) {
+ user = find_byuid(source);
+ } else {
+ user = finduser(source);
+ }
if (!user) {
alog("user: JOIN from nonexistent user %s: %s", source,
merge_args(ac, av));
@@ -600,14 +603,26 @@ void do_kick(const char *source, int ac, char **av)
continue;
}
- user = finduser(s);
+ if (UseTS6 && ircd->ts6) {
+ user = find_byuid(s);
+ if (!user) {
+ user = finduser(s);
+ }
+ } else {
+ user = finduser(s);
+ }
if (!user) {
alog("user: KICK for nonexistent user %s on %s: %s", s, av[0],
merge_args(ac - 2, av + 2));
continue;
}
- if (debug)
- alog("debug: kicking %s from %s", s, av[0]);
+ if (debug) {
+ if (UseTS6 && ircd->ts6) {
+ alog("debug: kicking %s from %s", user->nick, av[0]);
+ } else {
+ alog("debug: kicking %s from %s", s, av[0]);
+ }
+ }
for (c = user->chans; c && stricmp(av[0], c->chan->name) != 0;
c = c->next);
if (c) {
@@ -711,8 +726,6 @@ void do_sjoin(const char *source, int ac, char **av)
Channel *c;
User *user;
char *s, *end, cubuf[7], *end2, *cumodes[6];
-
-
int is_sqlined = 0;
int ts = 0;
@@ -778,7 +791,12 @@ void do_sjoin(const char *source, int ac, char **av)
*end2++ = csmodes[(int) *s++];
*end2 = 0;
- user = finduser(s);
+
+ if (UseTS6 && ircd->ts6) {
+ user = find_byuid(s);
+ } else {
+ user = finduser(s);
+ }
if (!user) {
alog("user: SJOIN for nonexistent user %s on %s", s,
av[1]);
@@ -822,7 +840,7 @@ void do_sjoin(const char *source, int ac, char **av)
}
/* Unreal just had to be different */
- } else if (ac == 3) {
+ } else if (ac == 3 && !ircd->ts6) {
c = findchan(av[1]);
if (ircd->chansqline) {
if (!c)
@@ -847,6 +865,7 @@ void do_sjoin(const char *source, int ac, char **av)
*end2 = 0;
user = finduser(s);
+
if (!user) {
alog("user: SJOIN for nonexistent user %s on %s", s,
av[1]);
@@ -885,8 +904,80 @@ void do_sjoin(const char *source, int ac, char **av)
if (c) {
c->creation_time = ts;
}
+ } else if (ac == 3 && ircd->ts6) {
+ c = findchan(av[1]);
+ if (ircd->chansqline) {
+ if (!c)
+ is_sqlined = check_chan_sqline(av[1]);
+ }
+
+ cubuf[0] = '+';
+ cumodes[0] = cubuf;
+
+ /* We make all the users join */
+ s = sstrdup(source); /* Users are always the last element */
+
+ while (*s) {
+ end = strchr(s, ' ');
+ if (end)
+ *end = 0;
+
+ end2 = cubuf + 1;
+
+ while (csmodes[(int) *s] != 0)
+ *end2++ = csmodes[(int) *s++];
+ *end2 = 0;
+
+ if (UseTS6 && ircd->ts6) {
+ user = find_byuid(s);
+ } else {
+ user = finduser(s);
+ }
+ if (!user) {
+ alog("user: SJOIN for nonexistent user %s on %s", s,
+ av[1]);
+ return;
+ }
+
+ if (is_sqlined && !is_oper(user)) {
+ anope_cmd_kick(s_OperServ, av[1], s, "Q-Lined");
+ } else {
+ if (!check_kick(user, av[1])) {
+ /* Make the user join; if the channel does not exist it
+ * will be created there. This ensures that the channel
+ * is not created to be immediately destroyed, and
+ * that the locked key or topic is not shown to anyone
+ * who joins the channel when empty.
+ */
+ c = join_user_update(user, c, av[1]);
+
+ /* We update user mode on the channel */
+ if (end2 - cubuf > 1) {
+ int i;
+
+ for (i = 1; i < end2 - cubuf; i++)
+ cumodes[i] = user->nick;
+ chan_set_modes(source, c, 1 + (end2 - cubuf - 1),
+ cumodes, 1);
+ }
+ }
+ }
+
+ if (!end)
+ break;
+ s = end + 1;
+ }
+
+ if (c) {
+ c->creation_time = ts;
+ }
+ free(s);
} else if (ac == 2) {
- user = finduser(source);
+ if (UseTS6 && ircd->ts6) {
+ user = find_byuid(source);
+ } else {
+ user = finduser(source);
+ }
if (!user) {
alog("user: SJOIN for nonexistent user %s on %s", source,
av[1]);
@@ -945,6 +1036,16 @@ void do_cmode(const char *source, int ac, char **av)
}
}
+ /* :42XAAAAAO TMODE 1106409026 #ircops +b *!*@*.aol.com */
+
+ if (UseTS6 && ircd->ts6) {
+ alog("chan %s : mode %s : extra %s", av[1], av[2], av[3]);
+ av[0] = sstrdup(av[1]);
+ av[1] = sstrdup(av[2]);
+ av[2] = sstrdup(av[3]);
+ alog("chan %s : mode %s : extra %s", av[0], av[1], av[2]);
+ }
+
chan = findchan(av[0]);
if (!chan) {
ci = cs_findchan(av[0]);
diff --git a/src/config.c b/src/config.c
index 11a772832..bfb3afc5f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -332,6 +332,8 @@ char *UlineServers;
char **Ulines;
int NumUlines;
+int UseTS6;
+
/*************************************************************************/
/* Deprecated directive (dep_) and value checking (chk_) functions: */
@@ -633,6 +635,7 @@ Directive directives[] = {
{"UseSVSHOLD", {{PARAM_SET, PARAM_RELOAD, &UseSVSHOLD}}},
{"UseSVS2MODE", {{PARAM_SET, PARAM_RELOAD, &UseSVS2MODE}}},
{"UseTokens", {{PARAM_SET, 0, &UseTokens}}},
+ {"UseTS6", {{PARAM_SET, 0, &UseTS6}}},
{"UnRestrictSAdmin", {{PARAM_SET, PARAM_RELOAD, &UnRestrictSAdmin}}},
{"WallAkillExpire", {{PARAM_SET, PARAM_RELOAD, &WallAkillExpire}}},
{"WallBadOS", {{PARAM_SET, PARAM_RELOAD, &WallBadOS}}},
@@ -985,6 +988,56 @@ int read_config(int reload)
CHEK2(s_GlobalNoticer, GlobalName);
CHEK2(PIDFilename, PIDFile);
}
+
+ if (s_ChanServAlias) {
+ if (!stricmp(s_ChanServ, s_ChanServAlias)) {
+ printf
+ ("\n*** ChanServ and ChanServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
+
+ if (s_NickServAlias) {
+ if (!stricmp(s_NickServ, s_NickServAlias)) {
+ printf
+ ("\n*** NickServ and NickServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
+
+ if (s_OperServAlias) {
+ if (!stricmp(s_OperServ, s_OperServAlias)) {
+ printf
+ ("\n*** OperServ and OperServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
+
+ if (s_MemoServAlias) {
+ if (!stricmp(s_MemoServ, s_MemoServAlias)) {
+ printf
+ ("\n*** MemoServ and MemoServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
+
+ if (s_HelpServAlias) {
+ if (!stricmp(s_HelpServ, s_HelpServAlias)) {
+ printf
+ ("\n*** HelpServ and HelpServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
+
+ if (s_GlobalNoticerAlias) {
+ if (!stricmp(s_GlobalNoticer, s_GlobalNoticerAlias)) {
+ printf
+ ("\n*** GlobalNoticer and GlobalNoticer Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
+
+
CHEK2(MOTDFilename, MOTDFile);
if (!reload) {
CHEK2(NickDBName, NickServDB);
@@ -1287,11 +1340,26 @@ int read_config(int reload)
CHECK(BSBadWordsMax);
CHECK(BSMinUsers);
CHECK(BSKeepData);
+ if (s_BotServAlias) {
+ if (!stricmp(s_BotServ, s_BotServAlias)) {
+ printf
+ ("\n*** BotServ and BotServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
}
if (s_HostServ) {
CHEK2(s_HostServ, HostServName);
CHEK2(HostDBName, HostServDB);
+
+ if (s_HostServAlias) {
+ if (!stricmp(s_HostServ, s_HostServAlias)) {
+ printf
+ ("\n*** HostServ and HostServ Alias are the same, this will cause errors\n");
+ retval = 0;
+ }
+ }
}
if (UseMail) {
diff --git a/src/datafiles.c b/src/datafiles.c
index 94d66a0b0..e2300a6ea 100644
--- a/src/datafiles.c
+++ b/src/datafiles.c
@@ -19,13 +19,14 @@
static int curday = 0;
/*************************************************************************/
-/*************************************************************************/
-/* Return the version number on the file. Return 0 if there is no version
+/**
+ * Return the version number on the file. Return 0 if there is no version
* number or the number doesn't make sense (i.e. less than 1 or greater
* than FILE_VERSION).
+ * @param f dbFile Struct Member
+ * @return int 0 if failure, 1 > is the version number
*/
-
int get_file_version(dbFILE * f)
{
FILE *fp = f->fp;
@@ -53,10 +54,11 @@ int get_file_version(dbFILE * f)
/*************************************************************************/
-/* Write the current version number to the file. Return 0 on error, 1 on
- * success.
+/**
+ * Write the current version number to the file.
+ * @param f dbFile Struct Member
+ * @return 0 on error, 1 on success.
*/
-
int write_file_version(dbFILE * f, uint32 version)
{
FILE *fp = f->fp;
@@ -73,8 +75,13 @@ int write_file_version(dbFILE * f, uint32 version)
}
/*************************************************************************/
-/*************************************************************************/
+/**
+ * Open the database for reading
+ * @param service If error whom to return the error as
+ * @param filename File to open as the database
+ * @return dbFile struct
+ */
static dbFILE *open_db_read(const char *service, const char *filename)
{
dbFILE *f;
@@ -107,6 +114,13 @@ static dbFILE *open_db_read(const char *service, const char *filename)
/*************************************************************************/
+/**
+ * Open the database for writting
+ * @param service If error whom to return the error as
+ * @param filename File to open as the database
+ * @param version Database Version
+ * @return dbFile struct
+ */
static dbFILE *open_db_write(const char *service, const char *filename,
uint32 version)
{
@@ -198,15 +212,20 @@ static dbFILE *open_db_write(const char *service, const char *filename,
/*************************************************************************/
-/* Open a database file for reading (*mode == 'r') or writing (*mode == 'w').
+/**
+ * Open a database file for reading (*mode == 'r') or writing (*mode == 'w').
* Return the stream pointer, or NULL on error. When opening for write, it
* is an error for rename() to return an error (when backing up the original
* file) other than ENOENT, if NO_BACKUP_OKAY is not defined; it is an error
* if the version number cannot be written to the file; and it is a fatal
* error if opening the file for write fails and the backup was successfully
* made but cannot be restored.
+ * @param service If error whom to return the error as
+ * @param filename File to open as the database
+ * @param mode Mode for writting or reading
+ * @param version Database Version
+ * @return dbFile struct
*/
-
dbFILE *open_db(const char *service, const char *filename,
const char *mode, uint32 version)
{
@@ -222,12 +241,14 @@ dbFILE *open_db(const char *service, const char *filename,
/*************************************************************************/
-/* Restore the database file to its condition before open_db(). This is
+/**
+ * Restore the database file to its condition before open_db(). This is
* identical to close_db() for files open for reading; however, for files
* open for writing, we first attempt to restore any backup file before
* closing files.
+ * @param dbFile struct
+ * @return void
*/
-
void restore_db(dbFILE * f)
{
int errno_save = errno;
@@ -273,10 +294,12 @@ void restore_db(dbFILE * f)
/*************************************************************************/
-/* Close a database file. If the file was opened for write, remove the
+/**
+ * Close a database file. If the file was opened for write, remove the
* backup we (may have) created earlier.
+ * @param dbFile struct
+ * @return void
*/
-
void close_db(dbFILE * f)
{
if (f->mode == 'w' && *f->backupname
@@ -290,9 +313,9 @@ void close_db(dbFILE * f)
}
/*************************************************************************/
-/*************************************************************************/
-/* Read and write 2- and 4-byte quantities, pointers, and strings. All
+/**
+ * Read and write 2- and 4-byte quantities, pointers, and strings. All
* multibyte values are stored in big-endian order (most significant byte
* first). A pointer is stored as a byte, either 0 if NULL or 1 if not,
* and read pointers are returned as either (void *)0 or (void *)1. A
@@ -301,10 +324,10 @@ void close_db(dbFILE * f)
* Written strings are truncated silently at 65534 bytes, and are always
* null-terminated.
*
- * All routines return -1 on error, 0 otherwise.
+ * @param ret 16bit integer to write
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
*/
-
-
int read_int16(uint16 * ret, dbFILE * f)
{
int c1, c2;
@@ -317,15 +340,33 @@ int read_int16(uint16 * ret, dbFILE * f)
return 0;
}
+/*************************************************************************/
+
+/**
+ * Write a 16bit integer
+ *
+ * @param ret 16bit integer to write
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int write_int16(uint16 val, dbFILE * f)
{
if (fputc((val >> 8) & 0xFF, f->fp) == EOF
- || fputc(val & 0xFF, f->fp) == EOF)
+ || fputc(val & 0xFF, f->fp) == EOF) {
return -1;
+ }
return 0;
}
+/*************************************************************************/
+/**
+ * Read a unsigned 32bit integer
+ *
+ * @param ret unsigned 32bit integer to read
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int read_int32(uint32 * ret, dbFILE * f)
{
int c1, c2, c3, c4;
@@ -340,6 +381,15 @@ int read_int32(uint32 * ret, dbFILE * f)
return 0;
}
+/*************************************************************************/
+
+/**
+ * Write a unsigned 32bit integer
+ *
+ * @param ret unsigned 32bit integer to write
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int write_int32(uint32 val, dbFILE * f)
{
if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
@@ -353,7 +403,15 @@ int write_int32(uint32 val, dbFILE * f)
return 0;
}
+/*************************************************************************/
+/**
+ * Read Pointer
+ *
+ * @param ret pointer to read
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int read_ptr(void **ret, dbFILE * f)
{
int c;
@@ -365,6 +423,15 @@ int read_ptr(void **ret, dbFILE * f)
return 0;
}
+/*************************************************************************/
+
+/**
+ * Write Pointer
+ *
+ * @param ret pointer to write
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int write_ptr(const void *ptr, dbFILE * f)
{
if (fputc(ptr ? 1 : 0, f->fp) == EOF)
@@ -372,7 +439,15 @@ int write_ptr(const void *ptr, dbFILE * f)
return 0;
}
+/*************************************************************************/
+/**
+ * Read String
+ *
+ * @param ret string
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int read_string(char **ret, dbFILE * f)
{
char *s;
@@ -393,6 +468,15 @@ int read_string(char **ret, dbFILE * f)
return 0;
}
+/*************************************************************************/
+
+/**
+ * Write String
+ *
+ * @param ret string
+ * @param dbFile struct
+ * @return -1 on error, 0 otherwise.
+ */
int write_string(const char *s, dbFILE * f)
{
uint32 len;
@@ -412,10 +496,14 @@ int write_string(const char *s, dbFILE * f)
}
/*************************************************************************/
-/*************************************************************************/
-
-/* Renames a database */
+/**
+ * Renames a database
+ *
+ * @param name Database to name
+ * @param ext Extention
+ * @return void
+ */
static void rename_database(char *name, char *ext)
{
@@ -431,8 +519,11 @@ static void rename_database(char *name, char *ext)
/*************************************************************************/
-/* Removes old databases */
-
+/**
+ * Removes old databases
+ *
+ * @return void
+ */
static void remove_backups(void)
{
@@ -465,16 +556,20 @@ static void remove_backups(void)
/*************************************************************************/
-/* Handles database backups. */
-
+/**
+ * Handles database backups.
+ *
+ * @return void
+ */
void backup_databases(void)
{
time_t t;
struct tm tm;
- if (!KeepBackups)
+ if (!KeepBackups) {
return;
+ }
time(&t);
tm = *localtime(&t);
@@ -497,11 +592,13 @@ void backup_databases(void)
if (!skeleton) {
rename_database(NickDBName, ext);
- if (s_BotServ)
+ if (s_BotServ) {
rename_database(BotDBName, ext);
+ }
rename_database(ChanDBName, ext);
- if (s_HostServ)
+ if (s_HostServ) {
rename_database(HostDBName, ext);
+ }
}
rename_database(OperDBName, ext);
diff --git a/src/dreamforge.c b/src/dreamforge.c
index b48b45a20..74209826f 100644
--- a/src/dreamforge.c
+++ b/src/dreamforge.c
@@ -103,6 +103,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
NULL, /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
}
,
{NULL}
@@ -1107,10 +1109,9 @@ void anope_cmd_kick(char *source, char *chan, char *user, const char *fmt,
/* EVENT: SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1401,7 +1402,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/hostserv.c b/src/hostserv.c
index 02e0c0c33..7a76dc668 100644
--- a/src/hostserv.c
+++ b/src/hostserv.c
@@ -81,15 +81,23 @@ void moduleAddHostServCmds(void)
/*************************************************************************/
-/*************************************************************************/
-/* HostServ initialization. */
+/**
+ * HostServ initialization.
+ * @return void
+ */
void hostserv_init(void)
{
moduleAddHostServCmds();
}
/*************************************************************************/
-/* Main HostServ routine. */
+
+/**
+ * Main HostServ routine.
+ * @param u User Struct
+ * @param buf Buffer holding the message
+ * @return void
+ */
void hostserv(User * u, char *buf)
{
char *cmd, *s;
@@ -115,8 +123,19 @@ void hostserv(User * u, char *buf)
}
/*************************************************************************/
-/* Start of Linked List routines */
+/* Start of Linked List routines */
/*************************************************************************/
+
+/**
+ * Create HostCore list member
+ * @param next HostCore next slot
+ * @param nick Nick to add
+ * @param vIdent Virtual Ident
+ * @param vHost Virtual Host
+ * @param creator Person whom set the vhost
+ * @param time Time the vhost was Set
+ * @return HostCore
+ */
HostCore *createHostCorelist(HostCore * next, char *nick, char *vIdent,
char *vHost, char *creator, int32 tmp_time)
{
@@ -158,12 +177,15 @@ HostCore *createHostCorelist(HostCore * next, char *nick, char *vIdent,
}
/*************************************************************************/
+
/**
* Returns either NULL for the head, or the location of the *PREVIOUS*
* record, this is where we need to insert etc..
- *
- * -rob
- **/
+ * @param head HostCore head
+ * @param nick Nick to find
+ * @param found If found
+ * @return HostCore
+ */
HostCore *findHostCore(HostCore * head, char *nick, boolean * found)
{
diff --git a/src/hybrid.c b/src/hybrid.c
index 646c4aa02..4301cc9e9 100644
--- a/src/hybrid.c
+++ b/src/hybrid.c
@@ -103,6 +103,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
NULL, /* vhost char */
+ 0, /* ts6 */
+ 0, /* support helper umode */
}
,
{NULL}
@@ -971,10 +973,9 @@ int anope_event_whois(char *source, int ac, char **av)
/* EVENT: SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1537,7 +1538,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
diff --git a/src/init.c b/src/init.c
index b0cad19db..d6a3fd0cb 100644
--- a/src/init.c
+++ b/src/init.c
@@ -508,7 +508,11 @@ int init(int ac, char **av)
#ifndef USE_THREADS
signal(SIGINT, sighandler);
#else
- signal(SIGINT, SIG_DFL);
+ if (nofork) {
+ signal(SIGINT, sighandler);
+ } else {
+ signal(SIGINT, SIG_DFL);
+ }
#endif
signal(SIGTERM, sighandler);
signal(SIGQUIT, sighandler);
@@ -656,8 +660,13 @@ int init(int ac, char **av)
}
#endif
/* Make myself known to myself in the serverlist */
- me_server =
- new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL);
+ if (UseTS6 && ircd->ts6) {
+ me_server =
+ new_server(NULL, ServerName, ServerDesc, SERVER_ISME, TS6SID);
+ } else {
+ me_server =
+ new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL);
+ }
/* Connect to the remote server */
servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort);
diff --git a/src/main.c b/src/main.c
index a44cda93c..e3eb8d05e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -253,6 +253,8 @@ void do_restart_services(void)
static void services_shutdown(void)
{
+ User *u, *next;
+
if (!quitmsg)
quitmsg = "Terminating, reason unknown";
alog("%s", quitmsg);
@@ -263,6 +265,12 @@ static void services_shutdown(void)
if (ircd->chanmodes) {
Anope_Free(ircd->chanmodes);
}
+ u = firstuser();
+ while (u) {
+ next = nextuser();
+ delete_user(u);
+ u = next;
+ }
}
disconn(servsock);
}
@@ -318,7 +326,18 @@ void sighandler(int signum)
quitmsg = "Shutting down on SIGTERM";
services_shutdown();
exit(0);
- } else if (signum == SIGINT || signum == SIGQUIT) {
+
+ } else if (signum == SIGINT) {
+ if (nofork) {
+ signal(SIGINT, SIG_IGN);
+ alog("Received SIGINT, exiting.");
+ expire_all();
+ save_databases();
+ quitmsg = "Shutting down on SIGINT";
+ services_shutdown();
+ exit(0);
+ }
+ } else if (signum == SIGQUIT) {
/* nothing -- terminate below */
} else if (!waiting) {
alog("PANIC! buffer = %s", inbuf);
diff --git a/src/messages.c b/src/messages.c
index 62b986267..dac9cc358 100644
--- a/src/messages.c
+++ b/src/messages.c
@@ -16,10 +16,8 @@
#include "messages.h"
#include "language.h"
-
int servernum;
-
/*************************************************************************/
int m_nickcoll(char *user)
@@ -120,7 +118,7 @@ int m_privmsg(char *source, char *receiver, char *msg)
ChannelInfo *ci;
User *u;
- if (!source || !*source) {
+ if (!source || !*source || !*receiver || !receiver || !msg) {
return MOD_CONT;
}
@@ -128,15 +126,11 @@ int m_privmsg(char *source, char *receiver, char *msg)
if (!u) {
alog("%s: user record for %s not found", msg, source);
- anope_cmd_notice(msg, source,
+ anope_cmd_notice(receiver, source,
getstring(NULL, USER_RECORD_NOT_FOUND));
return MOD_CONT;
}
- if (!*receiver || !receiver || !msg) {
- return MOD_CONT;
- }
-
if (*receiver == '#') {
if (s_BotServ && (ci = cs_findchan(receiver))) {
/* Some paranoia checks */
diff --git a/src/misc.c b/src/misc.c
index 1d011ece5..a238759b4 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -982,9 +982,9 @@ void add_entropy_userkeys(void)
* Get the random numbers 8 byte deep
* @return char
*/
-u_char getrandom8(void)
+unsigned char getrandom8(void)
{
- u_char si, sj;
+ unsigned char si, sj;
rs.i = (rs.i + 1);
si = rs.s[rs.i];
@@ -1112,7 +1112,7 @@ char *host_resolve(char *host)
* @return output string, same as input string.
*/
-char *str_signed(u_char *str)
+char *str_signed(unsigned char *str)
{
char *nstr;
diff --git a/src/plexus.c b/src/plexus.c
index 74f0bd49c..db0811631 100644
--- a/src/plexus.c
+++ b/src/plexus.c
@@ -103,6 +103,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
"h", /* vhost char */
+ 0, /* ts6 */
+ 0, /* support helper umode */
}
,
{NULL}
@@ -1052,10 +1054,9 @@ int anope_event_whois(char *source, int ac, char **av)
/* EVENT: SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1633,7 +1634,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/ptlink.c b/src/ptlink.c
index 1aa88596e..8025122ba 100644
--- a/src/ptlink.c
+++ b/src/ptlink.c
@@ -103,6 +103,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
NULL, /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
}
,
{NULL}
@@ -496,10 +498,9 @@ int anope_event_nick(char *source, int ac, char **av)
*/
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[3], NULL);
return MOD_CONT;
}
@@ -1727,7 +1728,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/rageircd.c b/src/rageircd.c
index f901a1b39..72ad08e08 100644
--- a/src/rageircd.c
+++ b/src/rageircd.c
@@ -104,6 +104,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
"x", /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
},
{NULL}
};
@@ -1344,10 +1346,9 @@ void anope_cmd_bot_chan_mode(char *nick, char *chan)
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1686,7 +1687,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/ratbox.c b/src/ratbox.c
new file mode 100644
index 000000000..746ed8adb
--- /dev/null
+++ b/src/ratbox.c
@@ -0,0 +1,1880 @@
+/* Ratbox IRCD functions
+ *
+ * (C) 2003 Anope Team
+ * Contact us at info@anope.org
+ *
+ * Please read COPYING and README for furhter details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+
+#include "services.h"
+#include "pseudo.h"
+
+#ifdef IRC_RATBOX
+
+const char version_protocol[] = "Ratbox IRCD 2.0+";
+
+/* Not all ircds use +f for their flood/join throttle system */
+const char flood_mode_char_set[] = ""; /* mode char for FLOOD mode on set */
+const char flood_mode_char_remove[] = ""; /* mode char for FLOOD mode on remove */
+int UseTSMODE = 0;
+
+int ts6nickcount = 0;
+
+IRCDVar ircd[] = {
+ {"Ratbox 2.0+", /* ircd name */
+ "+oi", /* nickserv mode */
+ "+oi", /* chanserv mode */
+ "+oi", /* memoserv mode */
+ "+oi", /* hostserv mode */
+ "+oai", /* operserv mode */
+ "+oi", /* botserv mode */
+ "+oi", /* helpserv mode */
+ "+oi", /* Dev/Null mode */
+ "+oi", /* Global mode */
+ "+oi", /* nickserv alias mode */
+ "+oi", /* chanserv alias mode */
+ "+oi", /* memoserv alias mode */
+ "+oi", /* hostserv alias mode */
+ "+oai", /* operserv alias mode */
+ "+oi", /* botserv alias mode */
+ "+oi", /* helpserv alias mode */
+ "+oi", /* Dev/Null alias mode */
+ "+oi", /* Global alias mode */
+ "+oi", /* Used by BotServ Bots */
+ 2, /* Chan Max Symbols */
+ "-acilmnpst", /* Modes to Remove */
+ "+o", /* Channel Umode used by Botserv bots */
+ 0, /* SVSNICK */
+ 0, /* Vhost */
+ 0, /* Has Owner */
+ NULL, /* Mode to set for an owner */
+ NULL, /* Mode to unset for an owner */
+ NULL, /* Mode On Reg */
+ NULL, /* Mode on UnReg */
+ NULL, /* Mode on Nick Change */
+ 0, /* Supports SGlines */
+ 1, /* Supports SQlines */
+ 0, /* Supports SZlines */
+ 0, /* Supports Halfop +h */
+ 3, /* Number of server args */
+ 1, /* Join 2 Set */
+ 1, /* Join 2 Message */
+ 1, /* Has exceptions +e */
+ 0, /* TS Topic Forward */
+ 0, /* TS Topci Backward */
+ 0, /* Protected Umode */
+ 0, /* Has Admin */
+ 1, /* Chan SQlines */
+ 0, /* Quit on Kill */
+ 0, /* SVSMODE unban */
+ 0, /* Has Protect */
+ 0, /* Reverse */
+ 0, /* Chan Reg */
+ 0, /* Channel Mode */
+ 0, /* vidents */
+ 0, /* svshold */
+ 0, /* time stamp on mode */
+ 0, /* NICKIP */
+ 0, /* UMODE */
+ 0, /* O:LINE */
+ 0, /* VHOST ON NICK */
+ 0, /* Change RealName */
+ 0, /* ChanServ extra */
+ CMODE_p, /* No Knock */
+ 0, /* Admin Only */
+ DEFAULT_MLOCK, /* Default MLOCK */
+ 0, /* Vhost Mode */
+ 0, /* +f */
+ 0, /* +L */
+ 0, /* +f Mode */
+ 0, /* +L Mode */
+ 0, /* On nick change check if they could be identified */
+ 0, /* No Knock requires +i */
+ NULL, /* CAPAB Chan Modes */
+ 0, /* We support TOKENS */
+ 1, /* TOKENS are CASE inSensitive */
+ 0, /* TIME STAMPS are BASE64 */
+ 1, /* +I support */
+ 0, /* SJOIN ban char */
+ 0, /* SJOIN except char */
+ 0, /* Can remove User Channel Modes with SVSMODE */
+ 0, /* Sglines are not enforced until user reconnects */
+ NULL, /* vhost char */
+ 1, /* ts6 */
+ 0, /* support helper umode */
+ }
+ ,
+ {NULL}
+};
+
+IRCDCAPAB ircdcap[] = {
+ {
+ 0, /* NOQUIT */
+ 0, /* TSMODE */
+ 0, /* UNCONNECT */
+ 0, /* NICKIP */
+ 0, /* SJOIN */
+ CAPAB_ZIP, /* ZIP */
+ 0, /* BURST */
+ CAPAB_TS5, /* TS5 */
+ 0, /* TS3 */
+ 0, /* DKEY */
+ 0, /* PT4 */
+ 0, /* SCS */
+ CAPAB_QS, /* QS */
+ CAPAB_UID, /* UID */
+ CAPAB_KNOCK, /* KNOCK */
+ 0, /* CLIENT */
+ 0, /* IPV6 */
+ 0, /* SSJ5 */
+ 0, /* SN2 */
+ 0, /* TOKEN */
+ 0, /* VHOST */
+ 0, /* SSJ3 */
+ 0, /* NICK2 */
+ 0, /* UMODE2 */
+ 0, /* VL */
+ 0, /* TLKEXT */
+ 0, /* DODKEY */
+ 0, /* DOZIP */
+ 0, 0}
+};
+
+static User *current;
+static int next_index;
+
+void anope_set_umode(User * user, int ac, char **av)
+{
+ int add = 1; /* 1 if adding modes, 0 if deleting */
+ char *modes = av[0];
+
+ ac--;
+
+ if (debug)
+ alog("debug: Changing mode for %s to %s", user->nick, modes);
+
+ while (*modes) {
+
+ add ? (user->mode |= umodes[(int) *modes]) : (user->mode &=
+ ~umodes[(int)
+ *modes]);
+
+ switch (*modes++) {
+ case '+':
+ add = 1;
+ break;
+ case '-':
+ add = 0;
+ break;
+ case 'o':
+ if (add) {
+ opcnt++;
+
+ if (WallOper)
+ anope_cmd_global(s_OperServ,
+ "\2%s\2 is now an IRC operator.",
+ user->nick);
+ display_news(user, NEWS_OPER);
+
+ } else {
+ opcnt--;
+ }
+ break;
+ }
+ }
+}
+
+unsigned long umodes[128] = {
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused, Unused, Horzontal Tab */
+ 0, 0, 0, /* Line Feed, Unused, Unused */
+ 0, 0, 0, /* Carriage Return, Unused, Unused */
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused */
+ 0, 0, 0, /* Unused, Unused, Space */
+ 0, 0, 0, /* ! " # */
+ 0, 0, 0, /* $ % & */
+ 0, 0, 0, /* ! ( ) */
+ 0, 0, 0, /* * + , */
+ 0, 0, 0, /* - . / */
+ 0, 0, /* 0 1 */
+ 0, 0, /* 2 3 */
+ 0, 0, /* 4 5 */
+ 0, 0, /* 6 7 */
+ 0, 0, /* 8 9 */
+ 0, 0, /* : ; */
+ 0, 0, 0, /* < = > */
+ 0, 0, /* ? @ */
+ 0, 0, 0, /* A B C */
+ 0, 0, 0, /* D E F */
+ 0, 0, 0, /* G H I */
+ 0, 0, 0, /* J K L */
+ 0, 0, 0, /* M N O */
+ 0, 0, 0, /* P Q R */
+ 0, 0, 0, /* S T U */
+ 0, 0, 0, /* V W X */
+ 0, /* Y */
+ 0, /* Z */
+ 0, 0, 0, /* [ \ ] */
+ 0, 0, 0, /* ^ _ ` */
+ UMODE_a, UMODE_b, 0, /* a b c */
+ UMODE_d, 0, 0, /* d e f */
+ 0, 0, UMODE_i, /* g h i */
+ 0, 0, UMODE_l, /* j k l */
+ UMODE_g, UMODE_n, UMODE_o, /* m n o */
+ 0, 0, 0, /* p q r */
+ 0, 0, UMODE_u, /* s t u */
+ 0, UMODE_w, UMODE_x, /* v w x */
+ 0, /* y */
+ 0, /* z */
+ 0, 0, 0, /* { | } */
+ 0, 0 /* ~ ‚ */
+};
+
+
+char csmodes[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0,
+ 0,
+ 0, 0, 0,
+ 0,
+ 0, 0, 0, 0,
+ 0,
+
+ 'v', 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 'o', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+CMMode cmmodes[128] = {
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL}, /* BCD */
+ {NULL}, {NULL}, {NULL}, /* EFG */
+ {NULL}, /* H */
+ {add_invite, del_invite},
+ {NULL}, /* J */
+ {NULL}, {NULL}, {NULL}, /* KLM */
+ {NULL}, {NULL}, {NULL}, /* NOP */
+ {NULL}, {NULL}, {NULL}, /* QRS */
+ {NULL}, {NULL}, {NULL}, /* TUV */
+ {NULL}, {NULL}, {NULL}, /* WXY */
+ {NULL}, /* Z */
+ {NULL}, {NULL}, /* (char 91 - 92) */
+ {NULL}, {NULL}, {NULL}, /* (char 93 - 95) */
+ {NULL}, /* ` (char 96) */
+ {NULL}, /* a (char 97) */
+ {add_ban, del_ban},
+ {NULL},
+ {NULL},
+ {add_exception, del_exception},
+ {NULL},
+ {NULL},
+ {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
+ {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}
+};
+
+
+CBMode cbmodes[128] = {
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0},
+ {0}, /* A */
+ {0}, /* B */
+ {0}, /* C */
+ {0}, /* D */
+ {0}, /* E */
+ {0}, /* F */
+ {0}, /* G */
+ {0}, /* H */
+ {0}, /* I */
+ {0}, /* J */
+ {0}, /* K */
+ {0}, /* L */
+ {0}, /* M */
+ {0}, /* N */
+ {0}, /* O */
+ {0}, /* P */
+ {0}, /* Q */
+ {0}, /* R */
+ {0}, /* S */
+ {0}, /* T */
+ {0}, /* U */
+ {0}, /* V */
+ {0}, /* W */
+ {0}, /* X */
+ {0}, /* Y */
+ {0}, /* Z */
+ {0}, {0}, {0}, {0}, {0}, {0},
+ {0},
+ {0}, /* b */
+ {0}, /* c */
+ {0}, /* d */
+ {0}, /* e */
+ {0}, /* f */
+ {0}, /* g */
+ {0}, /* h */
+ {CMODE_i, 0, NULL, NULL},
+ {0}, /* j */
+ {CMODE_k, 0, set_key, cs_set_key},
+ {CMODE_l, CBM_MINUS_NO_ARG, set_limit, cs_set_limit},
+ {CMODE_m, 0, NULL, NULL},
+ {CMODE_n, 0, NULL, NULL},
+ {0}, /* o */
+ {CMODE_p, 0, NULL, NULL},
+ {0}, /* q */
+ {0},
+ {CMODE_s, 0, NULL, NULL},
+ {CMODE_t, 0, NULL, NULL},
+ {0},
+ {0}, /* v */
+ {0}, /* w */
+ {0}, /* x */
+ {0}, /* y */
+ {0}, /* z */
+ {0}, {0}, {0}, {0}
+};
+
+CBModeInfo cbmodeinfos[] = {
+ {'i', CMODE_i, 0, NULL, NULL},
+ {'k', CMODE_k, 0, get_key, cs_get_key},
+ {'l', CMODE_l, CBM_MINUS_NO_ARG, get_limit, cs_get_limit},
+ {'m', CMODE_m, 0, NULL, NULL},
+ {'n', CMODE_n, 0, NULL, NULL},
+ {'p', CMODE_p, 0, NULL, NULL},
+ {'s', CMODE_s, 0, NULL, NULL},
+ {'t', CMODE_t, 0, NULL, NULL},
+ {0}
+};
+
+
+CUMode cumodes[128] = {
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+
+ {0},
+
+ {0}, /* a */
+ {0}, /* b */
+ {0}, /* c */
+ {0}, /* d */
+ {0}, /* e */
+ {0}, /* f */
+ {0}, /* g */
+ {0},
+ {0}, /* i */
+ {0}, /* j */
+ {0}, /* k */
+ {0}, /* l */
+ {0}, /* m */
+ {0}, /* n */
+ {CUS_OP, CUF_PROTECT_BOTSERV, check_valid_op},
+ {0}, /* p */
+ {0}, /* q */
+ {0}, /* r */
+ {0}, /* s */
+ {0}, /* t */
+ {0}, /* u */
+ {CUS_VOICE, 0, NULL},
+ {0}, /* w */
+ {0}, /* x */
+ {0}, /* y */
+ {0}, /* z */
+ {0}, {0}, {0}, {0}, {0}
+};
+
+
+
+void anope_cmd_notice(char *source, char *dest, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud;
+ User *u;
+
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ if (UsePrivmsg) {
+ anope_cmd_privmsg2(source, dest, buf);
+ } else {
+ ud = find_uid(source);
+ u = finduser(dest);
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source),
+ "NOTICE %s :%s", (UseTS6 ? (u ? u->uid : dest) : dest),
+ buf);
+ }
+}
+
+void anope_cmd_notice2(char *source, char *dest, char *msg)
+{
+ Uid *ud;
+ User *u;
+
+ ud = find_uid(source);
+ u = finduser(dest);
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "NOTICE %s :%s",
+ (UseTS6 ? (u ? u->uid : dest) : dest), msg);
+}
+
+void anope_cmd_privmsg(char *source, char *dest, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud, *ud2;
+
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+ ud = find_uid(source);
+ ud2 = find_uid(dest);
+
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "PRIVMSG %s :%s",
+ (UseTS6 ? (ud2 ? ud2->uid : dest) : dest), buf);
+}
+
+void anope_cmd_privmsg2(char *source, char *dest, char *msg)
+{
+ Uid *ud, *ud2;
+
+ ud = find_uid(source);
+ ud2 = find_uid(dest);
+
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "PRIVMSG %s :%s",
+ (UseTS6 ? (ud2 ? ud2->uid : dest) : dest), msg);
+}
+
+void anope_cmd_serv_notice(char *source, char *dest, char *msg)
+{
+ send_cmd(source, "NOTICE $$%s :%s", dest, msg);
+}
+
+void anope_cmd_serv_privmsg(char *source, char *dest, char *msg)
+{
+ send_cmd(source, "PRIVMSG $$%s :%s", dest, msg);
+}
+
+
+void anope_cmd_global(char *source, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *u;
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ if (source) {
+ u = find_uid(source);
+ if (u) {
+ send_cmd((UseTS6 ? u->uid : source), "OPERWALL :%s", buf);
+ } else {
+ send_cmd((UseTS6 ? TS6SID : ServerName), "OPERWALL :%s", buf);
+ }
+ } else {
+ send_cmd((UseTS6 ? TS6SID : ServerName), "OPERWALL :%s", buf);
+ }
+}
+
+/* GLOBOPS - to handle old WALLOPS */
+void anope_cmd_global_legacy(char *source, char *fmt)
+{
+ Uid *u;
+
+ if (source) {
+ u = find_uid(source);
+ if (u) {
+ send_cmd((UseTS6 ? u->uid : source), "OPERWALL :%s", fmt);
+ } else {
+ send_cmd((UseTS6 ? TS6SID : ServerName), "OPERWALL :%s", fmt);
+ }
+ } else {
+ send_cmd((UseTS6 ? TS6SID : ServerName), "OPERWALL :%s", fmt);
+ }
+
+ send_cmd(source ? source : ServerName, "OPERWALL :%s", fmt);
+}
+
+int anope_event_sjoin(char *source, int ac, char **av)
+{
+ do_sjoin(source, ac, av);
+ return MOD_CONT;
+}
+
+/*
+ Non TS6
+
+ av[0] = nick
+ av[1] = hop
+ av[2] = ts
+ av[3] = modes
+ av[4] = user
+ av[5] = host
+ av[6] = server
+ av[7] = info
+
+ TS6
+ av[0] = nick
+ av[1] = hop
+ av[2] = ts
+ av[3] = modes
+ av[4] = user
+ av[5] = host
+ av[6] = IP
+ av[7] = UID
+ av[8] = info
+
+*/
+int anope_event_nick(char *source, int ac, char **av)
+{
+ Server *s;
+ User *u;
+
+ if (UseTS6 && ac == 9) {
+ s = findserver_uid(servlist, source);
+ /* Source is always the server */
+ *source = '\0';
+ User *user = do_nick(source, av[0], av[4], av[5], s->name, av[8],
+ strtoul(av[2], NULL, 10),
+ 0, 0, "*", av[7]);
+ if (user) {
+ anope_set_umode(user, 1, &av[3]);
+ }
+ } else {
+ if (ac != 2) {
+ User *user = do_nick(source, av[0], av[4], av[5], av[6], av[7],
+ strtoul(av[2], NULL, 10),
+ 0, 0, "*", NULL);
+ if (user)
+ anope_set_umode(user, 1, &av[3]);
+ } else {
+ do_nick(source, av[0], NULL, NULL, NULL, NULL,
+ strtoul(av[1], NULL, 10), 0, 0, NULL, NULL);
+ }
+ return MOD_CONT;
+ }
+}
+
+int anope_event_topic(char *source, int ac, char **av)
+{
+ User *u;
+
+ if (ac == 4) {
+ do_topic(source, ac, av);
+ } else {
+ Channel *c = findchan(av[0]);
+ time_t topic_time = time(NULL);
+
+ if (!c) {
+ alog("channel: TOPIC %s for nonexistent channel %s",
+ merge_args(ac - 1, av + 1), av[0]);
+ return MOD_CONT;
+ }
+
+ if (check_topiclock(c, topic_time))
+ return MOD_CONT;
+
+ if (c->topic) {
+ free(c->topic);
+ c->topic = NULL;
+ }
+ if (ac > 1 && *av[1])
+ c->topic = sstrdup(av[1]);
+
+ if (UseTS6) {
+ u = find_byuid(source);
+ if (u) {
+ strscpy(c->topic_setter, u->nick, sizeof(c->topic_setter));
+ } else {
+ strscpy(c->topic_setter, source, sizeof(c->topic_setter));
+ }
+ } else {
+ strscpy(c->topic_setter, source, sizeof(c->topic_setter));
+ }
+ c->topic_time = topic_time;
+
+ record_topic(av[0]);
+ }
+ return MOD_CONT;
+}
+
+int anope_event_tburst(char *source, int ac, char **av)
+{
+ char *setter;
+
+ if (ac != 4) {
+ return MOD_CONT;
+ }
+
+ setter = myStrGetToken(av[2], '!', 0);
+
+ Channel *c = findchan(av[0]);
+ time_t topic_time = strtol(av[1], NULL, 10);
+
+ if (!c) {
+ alog("channel: TOPIC %s for nonexistent channel %s",
+ merge_args(ac - 1, av + 1), av[0]);
+ return MOD_CONT;
+ }
+
+ if (check_topiclock(c, topic_time))
+ return MOD_CONT;
+
+ if (c->topic) {
+ free(c->topic);
+ c->topic = NULL;
+ }
+ if (ac > 1 && *av[3])
+ c->topic = sstrdup(av[3]);
+
+ strscpy(c->topic_setter, setter, sizeof(c->topic_setter));
+ c->topic_time = topic_time;
+
+ record_topic(av[0]);
+ return MOD_CONT;
+}
+
+int anope_event_436(char *source, int ac, char **av)
+{
+ if (ac < 1)
+ return MOD_CONT;
+
+ m_nickcoll(av[0]);
+ return MOD_CONT;
+}
+
+
+/* *INDENT-OFF* */
+void moduleAddIRCDMsgs(void) {
+ Message *m;
+
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (UseTS6) {
+ snprintf(buf, BUFSIZE - 1, "%dX", Numeric);
+ TS6SID = sstrdup(buf);
+ UseTSMODE = 1; /* TMODE */
+ }
+
+ m = createMessage("401", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("402", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
+ m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
+ m = createMessage("INVITE", anope_event_invite); addCoreMessage(IRCD,m);
+ m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
+ m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
+ m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
+ m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
+ m = createMessage("TMODE", anope_event_tmode); addCoreMessage(IRCD,m);
+ m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
+ m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
+ m = createMessage("BMASK", anope_event_bmask); addCoreMessage(IRCD,m);
+ m = createMessage("UID", anope_event_nick); addCoreMessage(IRCD,m);
+ m = createMessage("NOTICE", anope_event_notice); addCoreMessage(IRCD,m);
+ m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
+ m = createMessage("PASS", anope_event_pass); addCoreMessage(IRCD,m);
+ m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
+ m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
+ m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
+ m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
+ m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
+ m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
+ m = createMessage("TB", anope_event_tburst); addCoreMessage(IRCD,m);
+ m = createMessage("USER", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("WALLOPS", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
+ m = createMessage("SVSMODE", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("SVSNICK", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m);
+ m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m);
+ m = createMessage("SVINFO", anope_event_svinfo); addCoreMessage(IRCD,m);
+ m = createMessage("ADMIN", anope_event_admin); addCoreMessage(IRCD,m);
+ m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m);
+ m = createMessage("421", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("ENCAP", anope_event_null); addCoreMessage(IRCD,m);
+ m = createMessage("SID", anope_event_sid); addCoreMessage(IRCD,m);
+}
+
+/* *INDENT-ON* */
+
+
+void anope_cmd_sqline(char *mask, char *reason)
+{
+ send_cmd(NULL, "RESV * %s :%s", mask, reason);
+}
+
+void anope_cmd_unsgline(char *mask)
+{
+ /* Does not support */
+}
+
+void anope_cmd_unszline(char *mask)
+{
+ /* Does not support */
+}
+
+void anope_cmd_szline(char *mask, char *reason, char *whom)
+{
+ /* Does not support */
+}
+
+void anope_cmd_svsnoop(char *server, int set)
+{
+ /* does not support */
+}
+
+void anope_cmd_svsadmin(char *server, int set)
+{
+ anope_cmd_svsnoop(server, set);
+}
+
+void anope_cmd_sgline(char *mask, char *reason)
+{
+ /* does not support */
+}
+
+void anope_cmd_remove_akill(char *user, char *host)
+{
+ Uid *ud;
+
+ ud = find_uid(s_OperServ);
+ send_cmd((UseTS6 ? (ud ? ud->uid : s_OperServ) : s_OperServ),
+ "UNKLINE * %s %s", user, host);
+}
+
+void anope_cmd_topic(char *whosets, char *chan, char *whosetit,
+ char *topic, time_t when)
+{
+ Uid *ud;
+
+ ud = find_uid(whosets);
+ send_cmd((UseTS6 ? (ud ? ud->uid : whosets) : whosets), "TOPIC %s :%s",
+ chan, topic);
+}
+
+void anope_cmd_vhost_off(User * u)
+{
+ /* not supported */
+}
+
+void anope_cmd_vhost_on(char *nick, char *vIdent, char *vhost)
+{
+ /* not supported */
+}
+
+void anope_cmd_unsqline(char *user)
+{
+ send_cmd(NULL, "UNRESV * %s", user);
+}
+
+void anope_cmd_join(char *user, char *channel, time_t chantime)
+{
+ Uid *ud;
+
+ if (UseTS6) {
+ ud = find_uid(user);
+ if (ud) {
+ send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL),
+ channel, ud->uid);
+ } else {
+ send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL),
+ channel, user);
+ }
+ } else {
+ send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL),
+ channel, user);
+ }
+}
+
+/*
+oper: the nick of the oper performing the kline
+target.server: the server(s) this kline is destined for
+duration: the duration if a tkline, 0 if permanent.
+user: the 'user' portion of the kline
+host: the 'host' portion of the kline
+reason: the reason for the kline.
+*/
+
+void anope_cmd_akill(char *user, char *host, char *who, time_t when,
+ time_t expires, char *reason)
+{
+ send_cmd(s_OperServ, "KLINE * %ld %s %s :%s",
+ (long int) (expires - (long) time(NULL)), user, host, reason);
+}
+
+void anope_cmd_svskill(char *source, char *user, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud, *ud2;
+
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ if (!source || !user) {
+ return;
+ }
+
+ if (UseTS6) {
+ ud = find_uid(source);
+ ud2 = find_uid(user);
+ if (ud && ud2) {
+ send_cmd(ud->uid, "KILL %s :%s", ud2->uid, buf);
+ } else {
+ send_cmd(source, "KILL %s :%s", user, buf);
+ }
+ } else {
+ send_cmd(source, "KILL %s :%s", user, buf);
+ }
+}
+
+void anope_cmd_svsmode(User * u, int ac, char **av)
+{
+ send_cmd((UseTS6 ? TS6SID : ServerName), "SVSMODE %s %s", u->nick,
+ av[0]);
+}
+
+void anope_cmd_connect(int servernum)
+{
+ if (servernum == 1)
+ anope_cmd_pass(RemotePassword);
+ else if (servernum == 2)
+ anope_cmd_pass(RemotePassword2);
+ else if (servernum == 3)
+ anope_cmd_pass(RemotePassword3);
+
+ anope_cmd_capab();
+ anope_cmd_server(ServerName, 1, ServerDesc);
+ anope_cmd_svinfo();
+}
+
+void anope_cmd_svsinfo()
+{
+ /* not used */
+}
+
+/*
+ * SVINFO
+ * parv[0] = sender prefix
+ * parv[1] = TS_CURRENT for the server
+ * parv[2] = TS_MIN for the server
+ * parv[3] = server is standalone or connected to non-TS only
+ * parv[4] = server's idea of UTC time
+ */
+void anope_cmd_svinfo()
+{
+ send_cmd(NULL, "SVINFO 6 3 0 :%ld", (long int) time(NULL));
+}
+
+/* CAPAB */
+/*
+ QS - Can handle quit storm removal
+ EX - Can do channel +e exemptions
+ CHW - Can do channel wall @#
+ LL - Can do lazy links
+ IE - Can do invite exceptions
+ EOB - Can do EOB message
+ KLN - Can do KLINE message
+ GLN - Can do GLINE message
+ HUB - This server is a HUB
+ UID - Can do UIDs
+ ZIP - Can do ZIPlinks
+ ENC - Can do ENCrypted links
+ KNOCK - supports KNOCK
+ TBURST - supports TBURST
+ PARA - supports invite broadcasting for +p
+ ENCAP - ?
+*/
+void anope_cmd_capab()
+{
+ send_cmd(NULL,
+ "CAPAB :QS EX CHW IE KLN GLN KNOCK TB UNKLN CLUSTER ENCAP");
+}
+
+/* PASS */
+void anope_cmd_pass(char *pass)
+{
+ if (UseTS6) {
+ send_cmd(NULL, "PASS %s TS 6 :%s", pass, TS6SID);
+ } else {
+ send_cmd(NULL, "PASS %s :TS", pass);
+ }
+}
+
+/* SERVER name hop descript */
+void anope_cmd_server(char *servname, int hop, char *descript)
+{
+ send_cmd(NULL, "SERVER %s %d :%s", servname, hop, descript);
+}
+
+void anope_cmd_bot_nick(char *nick, char *user, char *host, char *real,
+ char *modes)
+{
+ char nicknumbuf[10];
+ EnforceQlinedNick(nick, NULL);
+ if (UseTS6) {
+ snprintf(nicknumbuf, 10, "%dXAAAAA%c", Numeric,
+ (ts6nickcount + 'A'));
+ send_cmd(TS6SID, "UID %s 1 %ld %s %s %s 0 %s :%s", nick,
+ (long int) time(NULL), modes, user, host, nicknumbuf,
+ real);
+ new_uid(nick, nicknumbuf);
+ ts6nickcount++;
+ } else {
+ send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s :%s", nick,
+ (long int) time(NULL), modes, user, host, ServerName,
+ real);
+ }
+ anope_cmd_sqline(nick, "Reserved for services");
+}
+
+void anope_cmd_part(char *nick, char *chan, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud;
+
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+
+ ud = find_uid(nick);
+
+ if (buf) {
+ send_cmd((UseTS6 ? ud->uid : nick), "PART %s :%s", chan, buf);
+ } else {
+ send_cmd((UseTS6 ? ud->uid : nick), "PART %s", chan);
+ }
+}
+
+int anope_event_ping(char *source, int ac, char **av)
+{
+ if (ac < 1)
+ return MOD_CONT;
+ anope_cmd_pong(ac > 1 ? av[1] : ServerName, av[0]);
+ return MOD_CONT;
+}
+
+int anope_event_away(char *source, int ac, char **av)
+{
+ User *u;
+
+ if (ac) {
+ return MOD_CONT;
+ }
+
+ if (UseTS6) {
+ u = find_byuid(source);
+ }
+
+ m_away((UseTS6 ? u->nick : source), av[0]);
+ return MOD_CONT;
+}
+
+int anope_event_kill(char *source, int ac, char **av)
+{
+ if (ac != 2)
+ return MOD_CONT;
+
+ m_kill(av[0], av[1]);
+ return MOD_CONT;
+}
+
+int anope_event_kick(char *source, int ac, char **av)
+{
+ if (ac != 3)
+ return MOD_CONT;
+ do_kick(source, ac, av);
+ return MOD_CONT;
+}
+
+void anope_cmd_eob()
+{
+ /* doesn't support EOB */
+}
+
+int anope_event_join(char *source, int ac, char **av)
+{
+ if (ac != 1) {
+ do_sjoin(source, ac, av);
+ return MOD_CONT;
+ } else {
+ do_join(source, ac, av);
+ }
+ return MOD_CONT;
+}
+
+int anope_event_motd(char *source, int ac, char **av)
+{
+ if (!source) {
+ return MOD_CONT;
+ }
+
+ m_motd(source);
+ return MOD_CONT;
+}
+
+int anope_event_privmsg(char *source, int ac, char **av)
+{
+ User *u;
+ Uid *ud;
+
+ if (ac != 2) {
+ return MOD_CONT;
+ }
+
+ if (UseTS6) {
+ u = find_byuid(source);
+ ud = find_nickuid(av[0]);
+ if (u) {
+ m_privmsg(u->nick, (ud ? ud->nick : av[0]), av[1]);
+ } else {
+ m_privmsg(source, av[0], av[1]);
+ }
+ } else {
+ m_privmsg(source, av[0], av[1]);
+ }
+ return MOD_CONT;
+}
+
+int anope_event_part(char *source, int ac, char **av)
+{
+ User *u;
+
+ if (ac < 1 || ac > 2) {
+ return MOD_CONT;
+ }
+
+ u = find_byuid(source);
+ do_part((UseTS6 ? (u ? u->nick : source) : source), ac, av);
+
+ return MOD_CONT;
+}
+
+int anope_event_whois(char *source, int ac, char **av)
+{
+ Uid *ud;
+
+ if (source && ac >= 1) {
+ ud = find_nickuid(av[0]);
+ m_whois(source, (UseTS6 ? (ud ? ud->nick : av[0]) : av[0]));
+ }
+ return MOD_CONT;
+}
+
+/* EVENT: SERVER */
+int anope_event_server(char *source, int ac, char **av)
+{
+ if (!stricmp(av[1], "1")) {
+ uplink = sstrdup(av[0]);
+ if (UseTS6 && TS6UPLINK) {
+ do_server(source, av[0], av[1], av[2], TS6UPLINK);
+ } else {
+ do_server(source, av[0], av[1], av[2], NULL);
+ }
+ } else {
+ do_server(source, av[0], av[1], av[2], NULL);
+ }
+ return MOD_CONT;
+}
+
+int anope_event_sid(char *source, int ac, char **av)
+{
+ Server *s;
+
+ /* :42X SID trystan.nomadirc.net 2 43X :ircd-ratbox test server */
+
+ /* do_server(const char *source, char *servername, char *hops,
+ char *descript, char *numeric) */
+
+ s = findserver_uid(servlist, source);
+
+ do_server(s->name, av[0], av[1], av[3], av[2]);
+ return MOD_CONT;
+}
+
+int anope_event_squit(char *source, int ac, char **av)
+{
+ if (ac != 2)
+ return MOD_CONT;
+ do_squit(source, ac, av);
+ return MOD_CONT;
+}
+
+int anope_event_quit(char *source, int ac, char **av)
+{
+ User *u;
+
+ if (ac != 1) {
+ return MOD_CONT;
+ }
+
+ u = find_byuid(source);
+
+ if (UseTS6 && u) {
+ do_quit(u->nick, ac, av);
+ } else {
+ do_quit(source, ac, av);
+ }
+ return MOD_CONT;
+}
+
+void anope_cmd_372(char *source, char *msg)
+{
+ send_cmd((UseTS6 ? TS6SID : ServerName), "372 %s :- %s", source, msg);
+}
+
+void anope_cmd_372_error(char *source)
+{
+ send_cmd((UseTS6 ? TS6SID : ServerName),
+ "372 %s :- MOTD file not found! Please "
+ "contact your IRC administrator.", source);
+}
+
+void anope_cmd_375(char *source)
+{
+ send_cmd((UseTS6 ? TS6SID : ServerName),
+ "375 %s :- %s Message of the Day", source, ServerName);
+}
+
+void anope_cmd_376(char *source)
+{
+ send_cmd((UseTS6 ? TS6SID : ServerName),
+ "376 %s :End of /MOTD command.", source);
+}
+
+/* 391 */
+void anope_cmd_391(char *source, char *timestr)
+{
+ if (!timestr) {
+ return;
+ }
+ send_cmd(NULL, "391 :%s %s :%s", source, ServerName, timestr);
+}
+
+/* 250 */
+void anope_cmd_250(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd(NULL, "250 %s ", buf);
+}
+
+/* 307 */
+void anope_cmd_307(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd((UseTS6 ? TS6SID : ServerName), "307 %s ", buf);
+}
+
+/* 311 */
+void anope_cmd_311(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd((UseTS6 ? TS6SID : ServerName), "311 %s ", buf);
+}
+
+/* 312 */
+void anope_cmd_312(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd((UseTS6 ? TS6SID : ServerName), "312 %s ", buf);
+}
+
+/* 317 */
+void anope_cmd_317(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd((UseTS6 ? TS6SID : ServerName), "317 %s ", buf);
+}
+
+/* 219 */
+void anope_cmd_219(char *source, char *letter)
+{
+ if (!source) {
+ return;
+ }
+
+ if (letter) {
+ send_cmd(NULL, "219 %s %c :End of /STATS report.", source,
+ *letter);
+ } else {
+ send_cmd(NULL, "219 %s l :End of /STATS report.", source);
+ }
+}
+
+/* 401 */
+void anope_cmd_401(char *source, char *who)
+{
+ if (!source || !who) {
+ return;
+ }
+ send_cmd((UseTS6 ? TS6SID : ServerName), "401 %s %s :No such service.",
+ source, who);
+}
+
+/* 318 */
+void anope_cmd_318(char *source, char *who)
+{
+ if (!source || !who) {
+ return;
+ }
+
+ send_cmd((UseTS6 ? TS6SID : ServerName),
+ "318 %s %s :End of /WHOIS list.", source, who);
+}
+
+/* 242 */
+void anope_cmd_242(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd(NULL, "242 %s ", buf);
+}
+
+/* 243 */
+void anope_cmd_243(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd(NULL, "243 %s ", buf);
+}
+
+/* 211 */
+void anope_cmd_211(const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd(NULL, "211 %s ", buf);
+}
+
+void anope_cmd_mode(char *source, char *dest, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud;
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ if (source) {
+ ud = find_uid(source);
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "MODE %s %s",
+ dest, buf);
+ } else {
+ send_cmd(source, "MODE %s %s", dest, buf);
+ }
+}
+
+void anope_cmd_tmode(char *source, char *dest, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud;
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd(NULL, "MODE %s %s", dest, buf);
+}
+
+void anope_cmd_nick(char *nick, char *name, char *mode)
+{
+ char nicknumbuf[10];
+ EnforceQlinedNick(nick, NULL);
+ if (UseTS6) {
+ snprintf(nicknumbuf, 10, "%dXAAAAA%c", Numeric,
+ (ts6nickcount + 'A'));
+ send_cmd(TS6SID, "UID %s 1 %ld %s %s %s 0 %s :%s", nick,
+ (long int) time(NULL), mode, ServiceUser, ServiceHost,
+ nicknumbuf, name);
+ new_uid(nick, nicknumbuf);
+ ts6nickcount++;
+ } else {
+ send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s :%s", nick,
+ (long int) time(NULL), mode, ServiceUser, ServiceHost,
+ ServerName, name);
+ }
+ anope_cmd_sqline(nick, "Reserved for services");
+}
+
+void anope_cmd_kick(char *source, char *chan, char *user, const char *fmt,
+ ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud;
+ User *u;
+ *buf = '\0';
+
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+
+ ud = find_uid(source);
+ u = finduser(user);
+
+ if (buf) {
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source),
+ "KICK %s %s :%s", chan,
+ (UseTS6 ? (u ? u->uid : user) : user), buf);
+ } else {
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "KICK %s %s",
+ chan, (UseTS6 ? (u ? u->uid : user) : user));
+ }
+}
+
+void anope_cmd_notice_ops(char *source, char *dest, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ }
+
+ send_cmd(NULL, "NOTICE @%s :%s", dest, buf);
+}
+
+void anope_cmd_bot_chan_mode(char *nick, char *chan)
+{
+ Uid *u;
+
+ if (UseTS6) {
+ u = find_uid(nick);
+ anope_cmd_tmode(nick, chan, "%s %s", ircd->botchanumode,
+ (u ? u->uid : nick));
+ } else {
+ anope_cmd_mode(nick, chan, "%s %s", ircd->botchanumode, nick);
+ }
+}
+
+/* QUIT */
+void anope_cmd_quit(char *source, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ Uid *ud;
+
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+
+ ud = find_uid(source);
+
+ if (buf) {
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "QUIT :%s",
+ buf);
+ } else {
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "QUIT");
+ }
+}
+
+/* PONG */
+void anope_cmd_pong(char *servname, char *who)
+{
+ if (UseTS6) {
+ send_cmd(TS6SID, "PONG %s", who);
+ } else {
+ send_cmd(servname, "PONG %s", who);
+ }
+}
+
+/* INVITE */
+void anope_cmd_invite(char *source, char *chan, char *nick)
+{
+ Uid *ud;
+ User *u;
+
+ if (!source || !chan || !nick) {
+ return;
+ }
+
+ ud = find_uid(source);
+ u = finduser(nick);
+
+ send_cmd((UseTS6 ? (ud ? ud->uid : source) : source), "INVITE %s %s",
+ (UseTS6 ? (u ? u->uid : nick) : nick), chan);
+}
+
+/* SQUIT */
+void anope_cmd_squit(char *servname, char *message)
+{
+ if (!servname || !message) {
+ return;
+ }
+
+ send_cmd(NULL, "SQUIT %s :%s", servname, message);
+}
+
+int anope_event_mode(char *source, int ac, char **av)
+{
+ User *u, *u2;
+
+ if (ac < 2) {
+ return MOD_CONT;
+ }
+
+ if (*av[0] == '#' || *av[0] == '&') {
+ do_cmode(source, ac, av);
+ } else {
+ if (UseTS6) {
+ u = find_byuid(source);
+ u2 = find_byuid(av[0]);
+ av[0] = u2->nick;
+ do_umode(u->nick, ac, av);
+ } else {
+ do_umode(source, ac, av);
+ }
+ }
+ return MOD_CONT;
+}
+
+int anope_event_tmode(char *source, int ac, char **av)
+{
+ if (*av[1] == '#' || *av[1] == '&') {
+ do_cmode(source, ac, av);
+ }
+ return MOD_CONT;
+}
+
+void anope_cmd_351(char *source)
+{
+ send_cmd((UseTS6 ? TS6SID : ServerName),
+ "351 %s Anope-%s %s :%s - %s -- %s", source, version_number,
+ ServerName, ircd->name, version_flags, version_build);
+}
+
+/* Event: PROTOCTL */
+int anope_event_capab(char *source, int ac, char **av)
+{
+ capab_parse(ac, av);
+ return MOD_CONT;
+}
+
+/* SVSHOLD - set */
+void anope_cmd_svshold(char *nick)
+{
+ /* Not supported by this IRCD */
+}
+
+/* SVSHOLD - release */
+void anope_cmd_release_svshold(char *nick)
+{
+ /* Not Supported by this IRCD */
+}
+
+/* SVSNICK */
+void anope_cmd_svsnick(char *nick, char *newnick, time_t when)
+{
+ /* not supported */
+}
+
+void anope_cmd_guest_nick(char *nick, char *user, char *host, char *real,
+ char *modes)
+{
+ /* not supported */
+}
+
+void anope_cmd_svso(char *source, char *nick, char *flag)
+{
+ /* Not Supported by this IRCD */
+}
+
+void anope_cmd_unban(char *name, char *nick)
+{
+ /* Not Supported by this IRCD */
+}
+
+/* SVSMODE channel modes */
+
+void anope_cmd_svsmode_chan(char *name, char *mode, char *nick)
+{
+ /* Not Supported by this IRCD */
+}
+
+/* SVSMODE +d */
+/* sent if svid is something weird */
+void anope_cmd_svid_umode(char *nick, time_t ts)
+{
+ /* not supported */
+}
+
+/* SVSMODE +d */
+/* nc_change was = 1, and there is no na->status */
+void anope_cmd_nc_change(User * u)
+{
+ /* not supported */
+}
+
+/* SVSMODE +d */
+void anope_cmd_svid_umode2(User * u, char *ts)
+{
+ /* not supported */
+}
+
+void anope_cmd_svid_umode3(User * u, char *ts)
+{
+ /* not used */
+}
+
+/* NICK <newnick> */
+void anope_cmd_chg_nick(char *oldnick, char *newnick)
+{
+ if (!oldnick || !newnick) {
+ return;
+ }
+
+ send_cmd(oldnick, "NICK %s", newnick);
+}
+
+/*
+ * SVINFO
+ * parv[0] = sender prefix
+ * parv[1] = TS_CURRENT for the server
+ * parv[2] = TS_MIN for the server
+ * parv[3] = server is standalone or connected to non-TS only
+ * parv[4] = server's idea of UTC time
+ */
+int anope_event_svinfo(char *source, int ac, char **av)
+{
+ /* currently not used but removes the message : unknown message from server */
+ return MOD_CONT;
+}
+
+int anope_event_pass(char *source, int ac, char **av)
+{
+ if (UseTS6) {
+ TS6UPLINK = sstrdup(av[3]);
+ }
+ return MOD_CONT;
+}
+
+void anope_cmd_svsjoin(char *source, char *nick, char *chan)
+{
+ /* Not Supported by this IRCD */
+}
+
+void anope_cmd_svspart(char *source, char *nick, char *chan)
+{
+ /* Not Supported by this IRCD */
+}
+
+void anope_cmd_swhois(char *source, char *who, char *mask)
+{
+ /* not supported */
+}
+
+int anope_event_notice(char *source, int ac, char **av)
+{
+ return MOD_CONT;
+}
+
+int anope_event_admin(char *source, int ac, char **av)
+{
+ return MOD_CONT;
+}
+
+int anope_event_invite(char *source, int ac, char **av)
+{
+ return MOD_CONT;
+}
+
+int anope_event_bmask(char *source, int ac, char **av)
+{
+ Channel *c;
+ char *bans;
+ char *b;
+ int count, i;
+
+ /* :42X BMASK 1106409026 #ircops b :*!*@*.aol.com */
+ /* 0 1 2 3 */
+ c = findchan(av[1]);
+
+ if (c) {
+ bans = sstrdup(av[3]);
+ count = myNumToken(bans, ' ');
+ for (i = 0; i <= count - 1; i++) {
+ b = myStrGetToken(bans, ' ', i);
+ if (!stricmp(av[2], "b")) {
+ add_ban(c, b);
+ }
+ if (!stricmp(av[2], "e")) {
+ add_exception(c, b);
+ }
+ if (!stricmp(av[2], "I")) {
+ add_invite(c, b);
+ }
+ }
+ }
+ return MOD_CONT;
+}
+
+int anope_flood_mode_check(char *value)
+{
+ return 0;
+}
+
+int anope_event_error(char *source, int ac, char **av)
+{
+ if (ac >= 1) {
+ if (debug) {
+ alog("ERROR: %s", av[0]);
+ }
+ }
+ return MOD_CONT;
+}
+
+void anope_cmd_jupe(char *jserver, char *who, char *reason)
+{
+ char rbuf[256];
+
+ snprintf(rbuf, sizeof(rbuf), "Juped by %s%s%s", who,
+ reason ? ": " : "", reason ? reason : "");
+
+ anope_cmd_squit(jserver, rbuf);
+ anope_cmd_server(jserver, 2, rbuf);
+ new_server(me_server, jserver, rbuf, SERVER_JUPED, NULL);
+}
+
+/*
+ 1 = valid nick
+ 0 = nick is in valid
+*/
+int anope_valid_nick(char *nick)
+{
+ /* no hard coded invalid nicks */
+ return 1;
+}
+
+void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
+{
+ va_list args;
+ char buf[BUFSIZE];
+ char *s;
+ *buf = '\0';
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ va_end(args);
+ }
+ if (!buf) {
+ return;
+ } else {
+ s = normalizeBuffer(buf);
+ }
+
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
+}
+
+#endif
diff --git a/src/servers.c b/src/servers.c
index 69deec520..31c85f8e4 100644
--- a/src/servers.c
+++ b/src/servers.c
@@ -18,6 +18,8 @@ Server *servlist = NULL;
Server *me_server = NULL;
uint32 uplink_capab;
char *uplink;
+char *TS6UPLINK;
+char *TS6SID;
/* For first_server / next_server */
static Server *server_cur;
@@ -96,7 +98,7 @@ Server *new_server(Server * uplink, const char *name, const char *desc,
serv->desc = sstrdup(desc);
serv->flags = flags;
serv->uplink = uplink;
- serv->suid = suid;
+ serv->suid = sstrdup(suid);
serv->sync = -1;
serv->links = NULL;
serv->prev = NULL;
@@ -236,6 +238,43 @@ Server *findserver(Server * s, const char *name)
/*************************************************************************/
/**
+ * Find a server by UID, returns NULL if not found
+ * @param s Server struct
+ * @param name Server Name
+ * @return Server struct
+ */
+Server *findserver_uid(Server * s, const char *name)
+{
+ Server *sl;
+
+ if (!name || !*name) {
+ return NULL;
+ }
+
+ if (debug >= 3) {
+ alog("debug: findserver_uid(%p)", name);
+ }
+ while (s && s->suid && (stricmp(s->suid, name) != 0)) {
+ if (s->links) {
+ sl = findserver_uid(s->links, name);
+ if (sl) {
+ s = sl;
+ } else {
+ s = s->next;
+ }
+ } else {
+ s = s->next;
+ }
+ }
+ if (debug >= 3) {
+ alog("debug: findserver_uid(%s) -> %p", name, (void *) s);
+ }
+ return s;
+}
+
+/*************************************************************************/
+
+/**
* Find if the server is synced with the network
* @param s Server struct
* @param name Server Name
@@ -303,7 +342,14 @@ void do_squit(const char *source, int ac, char **av)
char buf[BUFSIZE];
Server *s;
- s = findserver(servlist, av[0]);
+ if (UseTS6 && ircd->ts6) {
+ s = findserver_uid(servlist, av[0]);
+ if (!s) {
+ s = findserver(servlist, av[0]);
+ }
+ } else {
+ s = findserver(servlist, av[0]);
+ }
if (!s) {
alog("SQUIT for nonexistent server (%s)!!", av[0]);
return;
diff --git a/src/ultimate2.c b/src/ultimate2.c
index fdccb13b7..853e88286 100644
--- a/src/ultimate2.c
+++ b/src/ultimate2.c
@@ -103,6 +103,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
"x", /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
}
,
{NULL}
@@ -1286,10 +1288,9 @@ int anope_event_motd(char *source, int ac, char **av)
/* EVENT: SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1745,7 +1746,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/ultimate3.c b/src/ultimate3.c
index d9a64f3a5..30535d808 100644
--- a/src/ultimate3.c
+++ b/src/ultimate3.c
@@ -105,6 +105,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
1, /* Sglines are enforced */
"x", /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
},
{NULL}
};
@@ -988,10 +990,9 @@ int anope_event_chgident(char *source, int ac, char **av)
/* EVENT: SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1823,7 +1824,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/unreal31.c b/src/unreal31.c
index 5f0bc8a0e..07a73454c 100644
--- a/src/unreal31.c
+++ b/src/unreal31.c
@@ -106,6 +106,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
"x", /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
},
{NULL}
};
@@ -1384,10 +1386,9 @@ int anope_event_chghost(char *source, int ac, char **av)
/* EVENT: SERVER */
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
- if (!stricmp(av[1], "1"))
+ if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
+ }
do_server(source, av[0], av[1], av[2], NULL);
return MOD_CONT;
}
@@ -1610,7 +1611,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif
diff --git a/src/unreal32.c b/src/unreal32.c
index 406b46384..333d9a878 100644
--- a/src/unreal32.c
+++ b/src/unreal32.c
@@ -105,6 +105,8 @@ IRCDVar ircd[] = {
1, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
"x", /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
},
{NULL}
};
diff --git a/src/users.c b/src/users.c
index 74d78bf58..732c26e29 100644
--- a/src/users.c
+++ b/src/users.c
@@ -17,6 +17,9 @@
#define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
User *userlist[1024];
+#define HASH2(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
+Uid *uidlist[1024];
+
int32 usercnt = 0, opcnt = 0;
uint32 maxusercnt = 0;
time_t maxusertime;
@@ -222,6 +225,9 @@ void delete_user(User * user)
free(user->vhost);
}
}
+ if (user->uid) {
+ free(user->uid);
+ }
Anope_Free(user->realname);
if (debug >= 2) {
alog("debug: delete_user(): remove from channels");
@@ -363,6 +369,99 @@ User *nextuser(void)
return current;
}
+User *find_byuid(const char *uid)
+{
+ User *u, *next;
+
+ u = first_uid();
+ while (u) {
+ next = next_uid();
+ if (!stricmp(uid, u->uid)) {
+ return u;
+ }
+ u = next;
+ }
+ return NULL;
+}
+
+User *first_uid(void)
+{
+ next_index = 0;
+ while (next_index < 1024 && current == NULL) {
+ current = userlist[next_index++];
+ }
+ if (debug >= 2) {
+ alog("debug: first_uid() returning %s %s",
+ current ? current->nick : "NULL (end of list)",
+ current ? current->uid : "");
+ }
+ return current;
+}
+
+User *next_uid(void)
+{
+ if (current)
+ current = current->next;
+ if (!current && next_index < 1024) {
+ while (next_index < 1024 && current == NULL)
+ current = userlist[next_index++];
+ }
+ if (debug >= 2) {
+ alog("debug: next_uid() returning %s %s",
+ current ? current->nick : "NULL (end of list)",
+ current ? current->uid : "");
+ }
+ return current;
+}
+
+Uid *new_uid(const char *nick, char *uid)
+{
+ Uid *u, **list;
+
+ u = scalloc(sizeof(Uid), 1);
+ if (!nick || !uid) {
+ return NULL;
+ }
+ strscpy(u->nick, nick, NICKMAX);
+ list = &uidlist[HASH2(u->nick)];
+ u->next = *list;
+ if (*list)
+ (*list)->prev = u;
+ *list = u;
+ u->uid = sstrdup(uid);
+ return u;
+}
+
+Uid *find_uid(const char *nick)
+{
+ Uid *u;
+ int i;
+
+ for (i = 0; i < 1024; i++) {
+ for (u = uidlist[i]; u; u = u->next) {
+ if (!stricmp(nick, u->nick)) {
+ return u;
+ }
+ }
+ }
+ return NULL;
+}
+
+Uid *find_nickuid(const char *uid)
+{
+ Uid *u;
+ int i;
+
+ for (i = 0; i < 1024; i++) {
+ for (u = uidlist[i]; u; u = u->next) {
+ if (!stricmp(uid, u->uid)) {
+ return u;
+ }
+ }
+ }
+ return NULL;
+}
+
/*************************************************************************/
/*************************************************************************/
@@ -509,7 +608,11 @@ User *do_nick(const char *source, char *nick, char *username, char *host,
user->timestamp = ts;
user->my_signon = time(NULL);
user->vhost = vhost ? sstrdup(vhost) : sstrdup(host);
- user->uid = uid; /* p10 stuff */
+ if (uid) {
+ user->uid = sstrdup(uid); /* p10/ts6 stuff */
+ } else {
+ user->uid = NULL;
+ }
user->vident = sstrdup(username);
if (CheckClones) {
diff --git a/src/viagra.c b/src/viagra.c
index 209f8440b..f6b76978a 100644
--- a/src/viagra.c
+++ b/src/viagra.c
@@ -103,6 +103,8 @@ IRCDVar ircd[] = {
0, /* Can remove User Channel Modes with SVSMODE */
0, /* Sglines are not enforced until user reconnects */
"x", /* vhost char */
+ 0, /* ts6 */
+ 1, /* support helper umode */
}
,
{NULL}
@@ -1038,8 +1040,6 @@ int anope_event_cs(char *source, int ac, char **av)
int anope_event_server(char *source, int ac, char **av)
{
- char *uplink;
-
if (!stricmp(av[1], "1")) {
uplink = sstrdup(av[0]);
}
@@ -1732,7 +1732,7 @@ void anope_cmd_ctcp(char *source, char *dest, const char *fmt, ...)
s = normalizeBuffer(buf);
}
- send_cmd(source, "%s NOTICE :\1%s \1", dest, s);
+ send_cmd(source, "NOTICE %s :\1%s \1", dest, s);
}
#endif