X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/dd9be678f1c9a8213a314f0a4b50de9f3710cee0..080bb5cf257c1b4383010742a7bf948593b8e0af:/src/channel.c diff --git a/src/channel.c b/src/channel.c index e372a2f..61332aa 100644 --- a/src/channel.c +++ b/src/channel.c @@ -26,12 +26,12 @@ #include "stdinc.h" #include "channel.h" +#include "chmode.h" #include "client.h" #include "common.h" #include "hash.h" #include "hook.h" -#include "irc_string.h" -#include "sprintf_irc.h" +#include "match.h" #include "ircd.h" #include "numeric.h" #include "s_serv.h" /* captab */ @@ -40,15 +40,14 @@ #include "whowas.h" #include "s_conf.h" /* ConfigFileEntry, ConfigChannel */ #include "s_newconf.h" -#include "s_log.h" +#include "logger.h" -extern rb_dlink_list global_channel_list; - -extern struct config_channel_entry ConfigChannel; -extern rb_bh *channel_heap; -extern rb_bh *ban_heap; -extern rb_bh *topic_heap; -extern rb_bh *member_heap; +struct config_channel_entry ConfigChannel; +rb_dlink_list global_channel_list; +static rb_bh *channel_heap; +static rb_bh *ban_heap; +static rb_bh *topic_heap; +static rb_bh *member_heap; static int channel_capabs[] = { CAP_EX, CAP_IE, CAP_SERVICE, @@ -242,8 +241,6 @@ remove_user_from_channel(struct membership *msptr) if(client_p->servptr == &me) rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers); - chptr->users_last = rb_current_time(); - if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) destroy_channel(chptr); @@ -279,8 +276,6 @@ remove_user_from_channels(struct Client *client_p) if(client_p->servptr == &me) rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers); - chptr->users_last = rb_current_time(); - if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) destroy_channel(chptr); @@ -923,19 +918,14 @@ check_spambot_warning(struct Client *source_p, const char *name) source_p->localClient->oper_warn_count_down--; else source_p->localClient->oper_warn_count_down = 0; - if(source_p->localClient->oper_warn_count_down == 0) + if(source_p->localClient->oper_warn_count_down == 0 && + name != NULL) { /* Its already known as a possible spambot */ - if(name != NULL) - sendto_realops_snomask(SNO_BOTS, L_NETWIDE, - "User %s (%s@%s) trying to join %s is a possible spambot", - source_p->name, - source_p->username, source_p->orighost, name); - else - sendto_realops_snomask(SNO_BOTS, L_NETWIDE, - "User %s (%s@%s) is a possible spambot", - source_p->name, - source_p->username, source_p->orighost); + sendto_realops_snomask(SNO_BOTS, L_NETWIDE, + "User %s (%s@%s) trying to join %s is a possible spambot", + source_p->name, + source_p->username, source_p->orighost, name); source_p->localClient->oper_warn_count_down = OPER_SPAM_COUNTDOWN; } } @@ -946,7 +936,9 @@ check_spambot_warning(struct Client *source_p, const char *name) JOIN_LEAVE_COUNT_EXPIRE_TIME) { decrement_count = (t_delta / JOIN_LEAVE_COUNT_EXPIRE_TIME); - if(decrement_count > source_p->localClient->join_leave_count) + if(name != NULL) + ; + else if(decrement_count > source_p->localClient->join_leave_count) source_p->localClient->join_leave_count = 0; else source_p->localClient->join_leave_count -= decrement_count; @@ -1001,6 +993,7 @@ check_splitmode(void *unused) "Network rejoined, deactivating splitmode"); rb_event_delete(check_splitmode_ev); + check_splitmode_ev = NULL; } } } @@ -1068,8 +1061,8 @@ set_channel_topic(struct Channel *chptr, const char *topic, const char *topic_in { if(chptr->topic == NULL) allocate_topic(chptr); - strlcpy(chptr->topic, topic, TOPICLEN + 1); - strlcpy(chptr->topic_info, topic_info, USERHOST_REPLYLEN); + rb_strlcpy(chptr->topic, topic, TOPICLEN + 1); + rb_strlcpy(chptr->topic_info, topic_info, USERHOST_REPLYLEN); chptr->topic_time = topicts; } else @@ -1080,25 +1073,6 @@ set_channel_topic(struct Channel *chptr, const char *topic, const char *topic_in } } -const struct mode_letter chmode_flags[] = -{ - {MODE_INVITEONLY, 'i'}, - {MODE_MODERATED, 'm'}, - {MODE_NOPRIVMSGS, 'n'}, - {MODE_PRIVATE, 'p'}, - {MODE_SECRET, 's'}, - {MODE_TOPICLIMIT, 't'}, - {MODE_NOCOLOR, 'c'}, - {MODE_FREEINVITE, 'g'}, - {MODE_OPMODERATE, 'z'}, - {MODE_EXLIMIT, 'L'}, - {MODE_PERMANENT, 'P'}, - {MODE_FREETARGET, 'F'}, - {MODE_DISFORWARD, 'Q'}, - {MODE_REGONLY, 'r'}, - {0, '\0'} -}; - /* channel_modes() * * inputs - pointer to channel @@ -1121,9 +1095,9 @@ channel_modes(struct Channel *chptr, struct Client *client_p) *mbuf++ = '+'; *pbuf = '\0'; - for (i = 0; chmode_flags[i].mode; ++i) - if(chptr->mode.mode & chmode_flags[i].mode) - *mbuf++ = chmode_flags[i].letter; + for (i = 0; i < 256; i++) + if(chptr->mode.mode & chmode_flags[i]) + *mbuf++ = i; if(chptr->mode.limit) { @@ -1160,8 +1134,8 @@ channel_modes(struct Channel *chptr, struct Client *client_p) *mbuf = '\0'; - strlcpy(final, buf1, sizeof final); - strlcat(final, buf2, sizeof final); + rb_strlcpy(final, buf1, sizeof final); + rb_strlcat(final, buf2, sizeof final); return final; } @@ -1304,13 +1278,9 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, cap = chcap_combos[j].cap_yes; nocap = chcap_combos[j].cap_no; - if(cap & CAP_TS6) - mbl = preflen = rb_sprintf(modebuf, ":%s TMODE %ld %s ", - use_id(source_p), (long) chptr->channelts, - chptr->chname); - else - mbl = preflen = rb_sprintf(modebuf, ":%s MODE %s ", - source_p->name, chptr->chname); + mbl = preflen = rb_sprintf(modebuf, ":%s TMODE %ld %s ", + use_id(source_p), (long) chptr->channelts, + chptr->chname); /* loop the list of - modes we have */ for (i = 0; i < mode_count; i++) @@ -1324,7 +1294,7 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, || ((nocap & mode_changes[i].nocaps) != mode_changes[i].nocaps)) continue; - if((cap & CAP_TS6) && !EmptyString(mode_changes[i].id)) + if(!EmptyString(mode_changes[i].id)) arg = mode_changes[i].id; else arg = mode_changes[i].arg; @@ -1387,3 +1357,42 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf); } } + +/* Check what we will forward to, without sending any notices to the user + * -- jilles + */ +struct Channel * +check_forward(struct Client *source_p, struct Channel *chptr, + char *key) +{ + int depth = 0, i; + + /* User is +Q */ + if (IsNoForward(source_p)) + return NULL; + + while (depth < 16) + { + chptr = find_channel(chptr->mode.forward); + /* Can only forward to existing channels */ + if (chptr == NULL) + return NULL; + /* Already on there, show original error message */ + if (IsMember(source_p, chptr)) + return NULL; + /* Juped. Sending a warning notice would be unfair */ + if (hash_find_resv(chptr->chname)) + return NULL; + /* Don't forward to +Q channel */ + if (chptr->mode.mode & MODE_DISFORWARD) + return NULL; + i = can_join(source_p, chptr, key); + if (i == 0) + return chptr; + if (i != ERR_INVITEONLYCHAN && i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_CHANNELISFULL) + return NULL; + depth++; + } + + return NULL; +}