diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/channels.c | 87 | ||||
-rw-r--r-- | src/chanserv.c | 11 | ||||
-rw-r--r-- | src/core/cs_akick.c | 4 | ||||
-rw-r--r-- | src/core/cs_topic.c | 2 | ||||
-rw-r--r-- | src/core/os_set.c | 4 | ||||
-rw-r--r-- | src/init.c | 1 | ||||
-rw-r--r-- | src/modules/cs_appendtopic.c | 2 | ||||
-rw-r--r-- | src/protocol/charybdis.c | 11 | ||||
-rw-r--r-- | src/protocol/hybrid.c | 2 | ||||
-rw-r--r-- | src/protocol/plexus2.c | 2 | ||||
-rw-r--r-- | src/protocol/plexus3.c | 2 | ||||
-rw-r--r-- | src/protocol/ptlink.c | 2 | ||||
-rw-r--r-- | src/protocol/ratbox.c | 2 | ||||
-rw-r--r-- | src/protocol/shadowircd.c | 2 |
14 files changed, 70 insertions, 64 deletions
diff --git a/src/channels.c b/src/channels.c index e93ea8401..d3615b335 100644 --- a/src/channels.c +++ b/src/channels.c @@ -575,11 +575,13 @@ void do_join(const char *source, int ac, char **av) /* Make sure check_kick comes before chan_adduser, so banned users * don't get to see things like channel keys. */ - if (check_kick(user, s)) + /* If channel already exists, check_kick() will use correct TS. + * Otherwise, we lose. */ + if (check_kick(user, s, time(NULL))) continue; chan = findchan(s); - chan = join_user_update(user, chan, s); + chan = join_user_update(user, chan, s, time(NULL)); chan_set_correct_modes(user, chan, 1); send_event(EVENT_JOIN_CHANNEL, 3, EVENT_STOP, source, s); @@ -756,11 +758,13 @@ void do_sjoin(const char *source, int ac, char **av) Channel *c; User *user; Server *serv; + struct c_userlist *cu; char *s = NULL; char *end, cubuf[7], *end2, *cumodes[6]; int is_sqlined = 0; int ts = 0; int is_created = 0; + int keep_their_modes = 1; serv = findserver(servlist, source); @@ -769,10 +773,32 @@ void do_sjoin(const char *source, int ac, char **av) } else { ts = strtoul(av[0], NULL, 10); } + c = findchan(av[1]); + if (c != NULL) { + if (c->creation_time == 0 || ts == 0) + c->creation_time = 0; + else if (c->creation_time > ts) { + c->creation_time = ts; + for (cu = c->users; cu; cu = cu->next) { + /* XXX */ + cumodes[0] = "-ov"; + cumodes[1] = user->nick; + cumodes[2] = user->nick; + chan_set_modes(source, c, 3, cumodes, 2); + } + if (c->ci && c->ci->bi) { + /* This is ugly, but it always works */ + anope_cmd_part(c->ci->bi->nick, c->name, "TS reop"); + bot_join(c->ci); + } + /* XXX simple modes and bans */ + } else if (c->creation_time < ts) + keep_their_modes = 0; + } else + is_created = 1; /* Double check to avoid unknown modes that need parameters */ if (ac >= 4) { - c = findchan(av[1]); if (ircd->chansqline) { if (!c) is_sqlined = check_chan_sqline(av[1]); @@ -793,7 +819,7 @@ void do_sjoin(const char *source, int ac, char **av) if (ircd->sjoinbanchar) { - if (*s == ircd->sjoinbanchar) { + if (*s == ircd->sjoinbanchar && keep_their_modes) { add_ban(c, myStrGetToken(s, ircd->sjoinbanchar, 1)); if (!end) break; @@ -802,7 +828,7 @@ void do_sjoin(const char *source, int ac, char **av) } } if (ircd->sjoinexchar) { - if (*s == ircd->sjoinexchar) { + if (*s == ircd->sjoinexchar && keep_their_modes) { add_exception(c, myStrGetToken(s, ircd->sjoinexchar, 1)); if (!end) @@ -813,7 +839,7 @@ void do_sjoin(const char *source, int ac, char **av) } if (ircd->sjoininvchar) { - if (*s == ircd->sjoininvchar) { + if (*s == ircd->sjoininvchar && keep_their_modes) { add_invite(c, myStrGetToken(s, ircd->sjoininvchar, 1)); if (!end) break; @@ -846,7 +872,7 @@ void do_sjoin(const char *source, int ac, char **av) if (is_sqlined && !is_oper(user)) { anope_cmd_kick(s_OperServ, av[1], s, "Q-Lined"); } else { - if (!check_kick(user, av[1])) { + if (!check_kick(user, av[1], ts)) { send_event(EVENT_JOIN_CHANNEL, 3, EVENT_START, user->nick, av[1]); @@ -856,10 +882,10 @@ void do_sjoin(const char *source, int ac, char **av) * 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]); + c = join_user_update(user, c, av[1], ts); /* We update user mode on the channel */ - if (end2 - cubuf > 1) { + if (end2 - cubuf > 1 && keep_their_modes) { int i; for (i = 1; i < end2 - cubuf; i++) @@ -883,16 +909,13 @@ void do_sjoin(const char *source, int ac, char **av) s = end + 1; } - if (c) { - /* Set the timestamp */ - c->creation_time = ts; + if (c && keep_their_modes) { /* We now update the channel mode. */ chan_set_modes(source, c, ac - 3, &av[2], 2); } /* Unreal just had to be different */ } else if (ac == 3 && !ircd->ts6) { - c = findchan(av[1]); if (ircd->chansqline) { if (!c) is_sqlined = check_chan_sqline(av[1]); @@ -934,7 +957,7 @@ void do_sjoin(const char *source, int ac, char **av) if (is_sqlined && !is_oper(user)) { anope_cmd_kick(s_OperServ, av[1], s, "Q-Lined"); } else { - if (!check_kick(user, av[1])) { + if (!check_kick(user, av[1], ts)) { send_event(EVENT_JOIN_CHANNEL, 3, EVENT_START, user->nick, av[1]); @@ -944,10 +967,10 @@ void do_sjoin(const char *source, int ac, char **av) * 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]); + c = join_user_update(user, c, av[1], ts); /* We update user mode on the channel */ - if (end2 - cubuf > 1) { + if (end2 - cubuf > 1 && keep_their_modes) { int i; for (i = 1; i < end2 - cubuf; i++) @@ -967,12 +990,7 @@ void do_sjoin(const char *source, int ac, char **av) break; s = end + 1; } - - 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]); @@ -1014,7 +1032,7 @@ void do_sjoin(const char *source, int ac, char **av) if (is_sqlined && !is_oper(user)) { anope_cmd_kick(s_OperServ, av[1], s, "Q-Lined"); } else { - if (!check_kick(user, av[1])) { + if (!check_kick(user, av[1], ts)) { send_event(EVENT_JOIN_CHANNEL, 3, EVENT_START, user->nick, av[1]); @@ -1024,10 +1042,10 @@ void do_sjoin(const char *source, int ac, char **av) * 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]); + c = join_user_update(user, c, av[1], ts); /* We update user mode on the channel */ - if (end2 - cubuf > 1) { + if (end2 - cubuf > 1 && keep_their_modes) { int i; for (i = 1; i < end2 - cubuf; i++) @@ -1047,10 +1065,6 @@ void do_sjoin(const char *source, int ac, char **av) break; s = end + 1; } - - if (c) { - c->creation_time = ts; - } free(s); } else if (ac == 2) { if (UseTS6 && ircd->ts6) { @@ -1068,12 +1082,9 @@ void do_sjoin(const char *source, int ac, char **av) return; } - if (check_kick(user, av[1])) + if (check_kick(user, av[1], ts)) return; - c = findchan(av[1]); - if (!c) - is_created = 1; if (ircd->chansqline) { if (!c) is_sqlined = check_chan_sqline(av[1]); @@ -1085,8 +1096,7 @@ void do_sjoin(const char *source, int ac, char **av) send_event(EVENT_JOIN_CHANNEL, 3, EVENT_START, user->nick, av[1]); - c = join_user_update(user, c, av[1]); - c->creation_time = ts; + c = join_user_update(user, c, av[1], ts); if (is_created && c->ci) restore_topic(c->name); chan_set_correct_modes(user, c, 1); @@ -1559,7 +1569,7 @@ void chan_adduser2(User * user, Channel * c) chan_adduser, but splitted to make it more efficient to use for SJOINs). */ -Channel *chan_create(char *chan) +Channel *chan_create(char *chan, time_t ts) { Channel *c; Channel **list; @@ -1574,7 +1584,7 @@ Channel *chan_create(char *chan) if (*list) (*list)->prev = c; *list = c; - c->creation_time = time(NULL); + c->creation_time = ts; /* Store ChannelInfo pointer in channel record */ c->ci = cs_findchan(chan); if (c->ci) @@ -1798,13 +1808,14 @@ char *get_redirect(Channel * chan) /*************************************************************************/ -Channel *join_user_update(User * user, Channel * chan, char *name) +Channel *join_user_update(User * user, Channel * chan, char *name, + time_t chants) { struct u_chanlist *c; /* If it's a new channel, so we need to create it first. */ if (!chan) - chan = chan_create(name); + chan = chan_create(name, chants); if (debug) alog("debug: %s joins %s", user->nick, chan->name); diff --git a/src/chanserv.c b/src/chanserv.c index 547f337ce..f439369e9 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -1466,10 +1466,10 @@ static void timeout_leave(Timeout * to) * else, kickban the user with an appropriate message (could be either * AKICK or restricted access) and return 1. Note that this is called * _before_ the user is added to internal channel lists (so do_kick() is - * not called). + * not called). The channel TS must be given for a new channel. */ -int check_kick(User * user, char *chan) +int check_kick(User * user, char *chan, time_t chants) { ChannelInfo *ci = cs_findchan(chan); Channel *c; @@ -1563,8 +1563,7 @@ int check_kick(User * user, char *chan) * c may be NULL even if it exists */ if ((!(c = findchan(chan)) || c->usercount == 0) && !(ci->flags & CI_INHABIT)) { - anope_cmd_join(s_ChanServ, chan, - (c ? c->creation_time : time(NULL))); + anope_cmd_join(s_ChanServ, chan, (c ? c->creation_time : chants)); t = add_timeout(CSInhabit, timeout_leave, 0); t->data = sstrdup(chan); ci->flags |= CI_INHABIT; @@ -1646,7 +1645,7 @@ void restore_topic(char *chan) } if (ircd->join2set) { if (whosends(ci) == s_ChanServ) { - anope_cmd_join(s_ChanServ, chan, time(NULL)); + anope_cmd_join(s_ChanServ, chan, c->creation_time); anope_cmd_mode(NULL, chan, "+o %s", s_ChanServ); } } @@ -1708,7 +1707,7 @@ int check_topiclock(Channel * c, time_t topic_time) if (ircd->join2set) { if (whosends(ci) == s_ChanServ) { - anope_cmd_join(s_ChanServ, c->name, time(NULL)); + anope_cmd_join(s_ChanServ, c->name, c->creation_time); anope_cmd_mode(NULL, c->name, "+o %s", s_ChanServ); } } diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c index 4108f58e3..39eb6d25c 100644 --- a/src/core/cs_akick.c +++ b/src/core/cs_akick.c @@ -284,7 +284,7 @@ int do_akick(User * u) cu = c->users; while (cu) { next = cu->next; - if (check_kick(cu->user, c->name)) { + if (check_kick(cu->user, c->name, c->creation_time)) { argv[0] = sstrdup(c->name); argv[1] = sstrdup(cu->user->nick); if (akick->reason) @@ -553,7 +553,7 @@ int do_akick(User * u) while (cu) { next = cu->next; - if (check_kick(cu->user, c->name)) { + if (check_kick(cu->user, c->name, c->creation_time)) { argv[0] = sstrdup(c->name); argv[1] = sstrdup(cu->user->nick); argv[2] = sstrdup(CSAutokickReason); diff --git a/src/core/cs_topic.c b/src/core/cs_topic.c index c4af5fc5b..fe2a0b27d 100644 --- a/src/core/cs_topic.c +++ b/src/core/cs_topic.c @@ -103,7 +103,7 @@ int do_cs_topic(User * u) s_ChanServ, u->nick, u->username, u->host, c->name); if (ircd->join2set) { if (whosends(ci) == s_ChanServ) { - anope_cmd_join(s_ChanServ, c->name, time(NULL)); + anope_cmd_join(s_ChanServ, c->name, c->creation_time); anope_cmd_mode(NULL, c->name, "+o %s", s_ChanServ); } } diff --git a/src/core/os_set.c b/src/core/os_set.c index 240b60a5f..860270dfb 100644 --- a/src/core/os_set.c +++ b/src/core/os_set.c @@ -97,6 +97,7 @@ int do_set(User * u) char *option = strtok(NULL, " "); char *setting = strtok(NULL, " "); int index; + Channel *c; if (!option) { syntax_error(s_OperServ, u, "SET", OPER_SET_SYNTAX); @@ -185,7 +186,8 @@ int do_set(User * u) */ if (LogChannel && (stricmp(setting, "on") == 0)) { if (ircd->join2msg) { - anope_cmd_join(s_GlobalNoticer, LogChannel, time(NULL)); + c = findchan(LogChannel); + anope_cmd_join(s_GlobalNoticer, LogChannel, c ? c->creation_time : time(NULL)); } logchan = 1; alog("Now sending log messages to %s", LogChannel); diff --git a/src/init.c b/src/init.c index bfdc26600..e40297765 100644 --- a/src/init.c +++ b/src/init.c @@ -761,6 +761,7 @@ int init_secondary(int ac, char **av) /* And hybrid needs Global joined in the logchan */ if (logchan && ircd->join2msg) { + /* XXX might desync */ anope_cmd_join(s_GlobalNoticer, LogChannel, time(NULL)); } diff --git a/src/modules/cs_appendtopic.c b/src/modules/cs_appendtopic.c index 0967462c9..df68d0e91 100644 --- a/src/modules/cs_appendtopic.c +++ b/src/modules/cs_appendtopic.c @@ -147,7 +147,7 @@ int my_cs_appendtopic(User * u) s_ChanServ, u->nick, u->username, u->host, c->name); if (ircd->join2set) { if (whosends(ci) == s_ChanServ) { - anope_cmd_join(s_ChanServ, c->name, time(NULL)); + anope_cmd_join(s_ChanServ, c->name, c->creation_time); anope_cmd_mode(NULL, c->name, "+o %s", s_ChanServ); } } diff --git a/src/protocol/charybdis.c b/src/protocol/charybdis.c index d559e0941..317753945 100644 --- a/src/protocol/charybdis.c +++ b/src/protocol/charybdis.c @@ -907,16 +907,9 @@ void charybdis_cmd_unsqline(char *user) void charybdis_cmd_join(char *user, char *channel, time_t chantime) { Uid *ud; - time_t tstosend; - - /* Working around anope's TS brokenness, also making sure - * to *never* send an SJOIN with TS zero -- jilles */ - if (chantime == 0 || chantime == time(NULL)) - tstosend = 0x7FFFFFFF; - else - tstosend = chantime; + ud = find_uid(user); - send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) tstosend, + send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) chantime, channel, (UseTS6 ? (ud ? ud->uid : user) : user)); } diff --git a/src/protocol/hybrid.c b/src/protocol/hybrid.c index 1f23a918c..0ceceb017 100644 --- a/src/protocol/hybrid.c +++ b/src/protocol/hybrid.c @@ -714,7 +714,7 @@ void hybrid_cmd_unsqline(char *user) void hybrid_cmd_join(char *user, char *channel, time_t chantime) { - send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL), channel, + send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) chantime, channel, user); } diff --git a/src/protocol/plexus2.c b/src/protocol/plexus2.c index 91d33c78d..4b6e19f37 100644 --- a/src/protocol/plexus2.c +++ b/src/protocol/plexus2.c @@ -866,7 +866,7 @@ plexus_cmd_unsqline (char *user) void plexus_cmd_join (char *user, char *channel, time_t chantime) { - send_cmd (ServerName, "SJOIN %ld %s + :%s", (long int) time (NULL), channel, + send_cmd (ServerName, "SJOIN %ld %s + :%s", (long int) chantime, channel, user); } diff --git a/src/protocol/plexus3.c b/src/protocol/plexus3.c index aa5a42c99..c2ac6a934 100644 --- a/src/protocol/plexus3.c +++ b/src/protocol/plexus3.c @@ -843,7 +843,7 @@ plexus_cmd_unsqline (char *user) void plexus_cmd_join (char *user, char *channel, time_t chantime) { - send_cmd (ServerName, "SJOIN %ld %s + :%s", (long int) time (NULL), channel, + send_cmd (ServerName, "SJOIN %ld %s + :%s", (long int) chantime, channel, user); } diff --git a/src/protocol/ptlink.c b/src/protocol/ptlink.c index 81b085fad..cdab41385 100644 --- a/src/protocol/ptlink.c +++ b/src/protocol/ptlink.c @@ -723,7 +723,7 @@ void ptlink_cmd_unsqline(char *user) void ptlink_cmd_join(char *user, char *channel, time_t chantime) { - send_cmd(ServerName, "SJOIN %ld %s + :%s", (long int) time(NULL), + send_cmd(ServerName, "SJOIN %ld %s + :%s", (long int) chantime, channel, user); } diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c index 4f6e6267d..bd42a56c3 100644 --- a/src/protocol/ratbox.c +++ b/src/protocol/ratbox.c @@ -854,7 +854,7 @@ void ratbox_cmd_join(char *user, char *channel, time_t chantime) Uid *ud; ud = find_uid(user); - send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL), + send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) chantime, channel, (UseTS6 ? (ud ? ud->uid : user) : user)); } diff --git a/src/protocol/shadowircd.c b/src/protocol/shadowircd.c index 54757c98b..fe887db7f 100644 --- a/src/protocol/shadowircd.c +++ b/src/protocol/shadowircd.c @@ -888,7 +888,7 @@ void shadowircd_cmd_join(char *user, char *channel, time_t chantime) Uid *ud; ud = find_uid(user); - send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) time(NULL), + send_cmd(NULL, "SJOIN %ld %s + :%s", (long int) chantime, channel, (ud ? ud->uid : user)); } |