X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/67b90240c4f15588f944de99391b2f98bc9cb0f7..1fbf6db6629fd4b6d66ebf09b654572559432a7e:/modules/core/m_join.c diff --git a/modules/core/m_join.c b/modules/core/m_join.c index d245023..3a5d05c 100644 --- a/modules/core/m_join.c +++ b/modules/core/m_join.c @@ -60,9 +60,6 @@ mapi_clist_av1 join_clist[] = { &join_msgtab, &sjoin_msgtab, NULL }; DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, NULL, NULL, "$Revision: 3494 $"); -static void do_join_0(struct Client *client_p, struct Client *source_p); -static int check_channel_name_loc(struct Client *source_p, const char *name); - static void set_final_mode(struct Mode *mode, struct Mode *oldmode); static void remove_our_modes(struct Channel *chptr, struct Client *source_p); @@ -70,9 +67,10 @@ static void remove_ban_list(struct Channel *chptr, struct Client *source_p, rb_dlink_list * list, char c, int mems); static char modebuf[MODEBUFLEN]; +static char omodebuf[MODEBUFLEN]; static char parabuf[MODEBUFLEN]; static const char *para[MAXMODEPARAMS]; -static char *mbuf; +static char *mbuf, *ombuf; static int pargs; /* @@ -83,7 +81,7 @@ static int pargs; static int m_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { - user_join(source_p, parv[1], parc > 2 ? parv[2] : NULL); /* channel.c */ + user_join(client_p, source_p, parv[1], parc > 2 ? parv[2] : NULL); /* channel.c */ return 0; } @@ -125,6 +123,7 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char * return 0; mbuf = modebuf; + ombuf = omodebuf; mode.key[0] = mode.forward[0] = '\0'; mode.mode = mode.limit = mode.join_num = mode.join_time = 0; @@ -193,7 +192,12 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char * ":%s MODE %s %s %s", source_p->servptr->name, chptr->chname, modebuf, parabuf); - *modebuf = *parabuf = '\0'; + if(*omodebuf != '\0') + sendto_channel_local(ONLY_OPERS, chptr, + ":%s MODE %s %s %s", + source_p->servptr->name, + chptr->chname, modebuf, parabuf); + *omodebuf = *modebuf = *parabuf = '\0'; } if(!IsMember(source_p, chptr)) @@ -252,7 +256,7 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char if(*parv[2] == '&') return 0; - modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0'; + omodebuf[0] = modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0'; pargs = mode.mode = mode.limit = mode.join_num = mode.join_time = 0; /* Hide connecting server on netburst -- jilles */ @@ -262,6 +266,7 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char fakesource_p = source_p; mbuf = modebuf; + ombuf = omodebuf; newts = atol(parv[1]); s = parv[3]; @@ -460,7 +465,11 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s", fakesource_p->name, chptr->chname, modebuf, parabuf); - *modebuf = *parabuf = '\0'; + if(*omodebuf != '\0') + sendto_channel_local(ONLY_OPERS, chptr, ":%s MODE %s %s %s", + fakesource_p->name, chptr->chname, omodebuf, parabuf); + + *omodebuf = *modebuf = *parabuf = '\0'; if(parv[3][0] != '0' && keep_new_modes) modes = channel_modes(chptr, source_p); @@ -472,6 +481,7 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char ptr_uid = buf_uid + mlen_uid; mbuf = modebuf; + ombuf = omodebuf; para[0] = para[1] = para[2] = para[3] = empty; pargs = 0; len_nick = len_uid = 0; @@ -493,11 +503,21 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char for (i = 0; i < 2; i++) { - if(*s == '@') + if(*s == '!') + { + fl |= CHFL_OWNER; + s++; + } + else if(*s == '@') { fl |= CHFL_CHANOP; s++; } + else if(*s == '%') + { + fl |= CHFL_HALFOP; + s++; + } else if(*s == '+') { fl |= CHFL_VOICE; @@ -523,12 +543,24 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char if(keep_new_modes) { + if(fl & CHFL_OWNER) + { + *ptr_uid++ = '!'; + len_nick++; + len_uid++; + } if(fl & CHFL_CHANOP) { *ptr_uid++ = '@'; len_nick++; len_uid++; } + if(fl & CHFL_HALFOP) + { + *ptr_uid++ = '%'; + len_nick++; + len_uid++; + } if(fl & CHFL_VOICE) { *ptr_uid++ = '+'; @@ -554,12 +586,108 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char joins++; } + /* If anyone can think of a way to do this that doesn't make babies cry + * I would love to hear it - Taros */ + + if(fl & CHFL_OWNER) + { + *mbuf++ = 'a'; + para[pargs++] = target_p->name; + + if(fl & CHFL_CHANOP) + { + /* its possible the +a has filled up MAXMODEPARAMS, if so, start + * a new buffer + */ + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, + modebuf, + para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + *mbuf++ = 'o'; + para[pargs++] = target_p->name; + } + if(fl & CHFL_HALFOP) + { + /* its possible the +a has filled up MAXMODEPARAMS, if so, start + * a new buffer + */ + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, + modebuf, + para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + *mbuf++ = 'h'; + para[pargs++] = target_p->name; + } + if(fl & CHFL_VOICE) + { + /* its possible the +a has filled up MAXMODEPARAMS, if so, start + * a new buffer + */ + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, + modebuf, + para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + *mbuf++ = 'v'; + para[pargs++] = target_p->name; + } + } if(fl & CHFL_CHANOP) { *mbuf++ = 'o'; para[pargs++] = target_p->name; - /* a +ov user.. bleh */ + if(fl & CHFL_HALFOP) + { + /* its possible the +o has filled up MAXMODEPARAMS, if so, start + * a new buffer + */ + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, + modebuf, + para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + *mbuf++ = 'h'; + para[pargs++] = target_p->name; + } if(fl & CHFL_VOICE) { /* its possible the +o has filled up MAXMODEPARAMS, if so, start @@ -583,6 +711,34 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char para[pargs++] = target_p->name; } } + if(fl & CHFL_HALFOP) + { + *mbuf++ = 'h'; + para[pargs++] = target_p->name; + + if(fl & CHFL_VOICE) + { + /* its possible the +h has filled up MAXMODEPARAMS, if so, start + * a new buffer + */ + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, + modebuf, + para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + *mbuf++ = 'v'; + para[pargs++] = target_p->name; + } + } else if(fl & CHFL_VOICE) { *mbuf++ = 'v'; @@ -652,82 +808,11 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char return 0; } -/* - * do_join_0 - * - * inputs - pointer to client doing join 0 - * output - NONE - * side effects - Use has decided to join 0. This is legacy - * from the days when channels were numbers not names. *sigh* - */ -static void -do_join_0(struct Client *client_p, struct Client *source_p) -{ - struct membership *msptr; - struct Channel *chptr = NULL; - rb_dlink_node *ptr; - - /* Finish the flood grace period... */ - if(MyClient(source_p) && !IsFloodDone(source_p)) - flood_endgrace(source_p); - - sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s JOIN 0", use_id(source_p)); - - while((ptr = source_p->user->channel.head)) - { - if(MyConnect(source_p) && - !IsOper(source_p) && !IsExemptSpambot(source_p)) - check_spambot_warning(source_p, NULL); - - msptr = ptr->data; - chptr = msptr->chptr; - sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", - source_p->name, - source_p->username, source_p->host, chptr->chname); - remove_user_from_channel(msptr); - } -} - -static int -check_channel_name_loc(struct Client *source_p, const char *name) -{ - const char *p; - - s_assert(name != NULL); - if(EmptyString(name)) - return 0; - - if(ConfigFileEntry.disable_fake_channels && !IsOper(source_p)) - { - for(p = name; *p; ++p) - { - if(!IsChanChar(*p) || IsFakeChanChar(*p)) - return 0; - } - } - else - { - for(p = name; *p; ++p) - { - if(!IsChanChar(*p)) - return 0; - } - } - - if(ConfigChannel.only_ascii_channels) - { - for(p = name; *p; ++p) - if(*p < 33 || *p > 126) - return 0; - } - - return 1; -} static void set_final_mode(struct Mode *mode, struct Mode *oldmode) { - int dir = MODE_QUERY; + int dir = MODE_QUERY, odir = MODE_QUERY; char *pbuf = parabuf; int len; int i; @@ -737,12 +822,25 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) { if((mode->mode & chmode_flags[i]) && !(oldmode->mode & chmode_flags[i])) { - if(dir != MODE_ADD) + if (chmode_table[i].set_func == chm_hidden) { - *mbuf++ = '+'; - dir = MODE_ADD; + if(odir != MODE_ADD) + { + *ombuf++ = '+'; + odir = MODE_ADD; + } + *ombuf++ = i; + } + else + { + if(dir != MODE_ADD) + { + *mbuf++ = '+'; + dir = MODE_ADD; + } + *mbuf++ = i; + } - *mbuf++ = i; } } @@ -751,12 +849,24 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) { if((oldmode->mode & chmode_flags[i]) && !(mode->mode & chmode_flags[i])) { - if(dir != MODE_DEL) + if(chmode_table[i].set_func == chm_hidden) + { + if(odir != MODE_DEL) + { + *ombuf++ = '-'; + odir = MODE_DEL; + } + *ombuf++ = i; + } + else { - *mbuf++ = '-'; - dir = MODE_DEL; + if(dir != MODE_DEL) + { + *mbuf++ = '-'; + dir = MODE_DEL; + } + *mbuf++ = i; } - *mbuf++ = i; } } @@ -872,13 +982,152 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p) { msptr = ptr->data; - if(is_chanop(msptr)) + /* If anyone can think of a way to do this that doesn't make babies cry + * I would love to hear it - Taros */ + + if(is_owner(msptr)) + { + msptr->flags &= ~CHFL_OWNER; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'a'; + + /* Make sure it fits if +h, +o, or +v are involved */ + if(is_chanop(msptr)) + { + if(count >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + source_p->name, chptr->chname, + lmodebuf, lpara[0], lpara[1], + lpara[2], lpara[3]); + + /* preserve the initial '-' */ + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + + for(i = 0; i < MAXMODEPARAMS; i++) + lpara[i] = NULL; + } + + msptr->flags &= ~CHFL_CHANOP; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'o'; + } + if(is_halfop(msptr)) + { + if(count >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + source_p->name, chptr->chname, + lmodebuf, lpara[0], lpara[1], + lpara[2], lpara[3]); + + /* preserve the initial '-' */ + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + + for(i = 0; i < MAXMODEPARAMS; i++) + lpara[i] = NULL; + } + + msptr->flags &= ~CHFL_HALFOP; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'h'; + } + if(is_voiced(msptr)) + { + if(count >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + source_p->name, chptr->chname, + lmodebuf, lpara[0], lpara[1], + lpara[2], lpara[3]); + + /* preserve the initial '-' */ + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + + for(i = 0; i < MAXMODEPARAMS; i++) + lpara[i] = NULL; + } + + msptr->flags &= ~CHFL_VOICE; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'v'; + } + } + else if(is_chanop(msptr)) { msptr->flags &= ~CHFL_CHANOP; lpara[count++] = msptr->client_p->name; *mbuf++ = 'o'; - /* +ov, might not fit so check. */ + /* Make sure it fits if +h or +v are involved */ + if(is_halfop(msptr)) + { + if(count >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + source_p->name, chptr->chname, + lmodebuf, lpara[0], lpara[1], + lpara[2], lpara[3]); + + /* preserve the initial '-' */ + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + + for(i = 0; i < MAXMODEPARAMS; i++) + lpara[i] = NULL; + } + + msptr->flags &= ~CHFL_HALFOP; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'h'; + } + if(is_voiced(msptr)) + { + if(count >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + source_p->name, chptr->chname, + lmodebuf, lpara[0], lpara[1], + lpara[2], lpara[3]); + + /* preserve the initial '-' */ + mbuf = lmodebuf; + *mbuf++ = '-'; + count = 0; + + for(i = 0; i < MAXMODEPARAMS; i++) + lpara[i] = NULL; + } + + msptr->flags &= ~CHFL_VOICE; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'v'; + } + } + else if(is_halfop(msptr)) + { + msptr->flags &= ~CHFL_HALFOP; + lpara[count++] = msptr->client_p->name; + *mbuf++ = 'h'; + + /* +hv, might not fit so check. */ if(is_voiced(msptr)) { if(count >= MAXMODEPARAMS)