2 * ircd-ratbox: A slightly useful ircd.
3 * m_join.c: Joins a channel.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 * $Id: m_join.c 3494 2007-05-27 13:07:27Z jilles $
38 #include "s_newconf.h"
45 static int m_join(struct Client
*, struct Client
*, int, const char **);
46 static int ms_join(struct Client
*, struct Client
*, int, const char **);
47 static int ms_sjoin(struct Client
*, struct Client
*, int, const char **);
49 struct Message join_msgtab
= {
50 "JOIN", 0, 0, 0, MFLG_SLOW
,
51 {mg_unreg
, {m_join
, 2}, {ms_join
, 2}, mg_ignore
, mg_ignore
, {m_join
, 2}}
54 struct Message sjoin_msgtab
= {
55 "SJOIN", 0, 0, 0, MFLG_SLOW
,
56 {mg_unreg
, mg_ignore
, mg_ignore
, {ms_sjoin
, 4}, mg_ignore
, mg_ignore
}
59 mapi_clist_av1 join_clist
[] = { &join_msgtab
, &sjoin_msgtab
, NULL
};
61 DECLARE_MODULE_AV1(join
, NULL
, NULL
, join_clist
, NULL
, NULL
, "$Revision: 3494 $");
63 static void set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
);
64 static void remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
);
66 static void remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
67 rb_dlink_list
* list
, char c
, int mems
);
69 static char modebuf
[MODEBUFLEN
];
70 static char omodebuf
[MODEBUFLEN
];
71 static char parabuf
[MODEBUFLEN
];
72 static const char *para
[MAXMODEPARAMS
];
73 static char *mbuf
, *ombuf
;
79 * parv[2] = channel password (key)
82 m_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
84 user_join(client_p
, source_p
, parv
[1], parc
> 2 ? parv
[2] : NULL
); /* channel.c */
91 * parv[1] = channel TS
93 * parv[3] = "+", formerly channel modes but now unused
94 * alternatively, a single "0" parameter parts all channels
97 ms_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
99 struct Channel
*chptr
;
100 static struct Mode mode
;
104 int keep_our_modes
= YES
;
105 int keep_new_modes
= YES
;
106 rb_dlink_node
*ptr
, *next_ptr
;
108 /* special case for join 0 */
109 if((parv
[1][0] == '0') && (parv
[1][1] == '\0') && parc
== 2)
111 do_join_0(client_p
, source_p
);
118 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
121 /* joins for local channels cant happen. */
122 if(parv
[2][0] == '&')
127 mode
.key
[0] = mode
.forward
[0] = '\0';
128 mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
130 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
133 newts
= atol(parv
[1]);
134 oldts
= chptr
->channelts
;
136 #ifdef IGNORE_BOGUS_TS
137 if(newts
< 800000000)
139 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
140 "*** Bogus TS %ld on %s ignored from %s",
141 (long) newts
, chptr
->chname
, client_p
->name
);
142 newts
= (oldts
== 0) ? oldts
: 800000000;
145 /* making a channel TS0 */
146 if(!isnew
&& !newts
&& oldts
)
148 sendto_channel_local(ALL_MEMBERS
, chptr
,
149 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
150 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
151 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
152 "Server %s changing TS on %s from %ld to 0",
153 source_p
->name
, chptr
->chname
, (long) oldts
);
158 chptr
->channelts
= newts
;
159 else if(newts
== 0 || oldts
== 0)
160 chptr
->channelts
= 0;
161 else if(newts
== oldts
)
163 else if(newts
< oldts
)
166 chptr
->channelts
= newts
;
171 /* Lost the TS, other side wins, so remove modes on this side */
174 set_final_mode(&mode
, &chptr
->mode
);
176 remove_our_modes(chptr
, source_p
);
177 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
179 del_invite(chptr
, ptr
->data
);
181 /* If setting -j, clear join throttle state -- jilles */
182 chptr
->join_count
= chptr
->join_delta
= 0;
183 sendto_channel_local(ALL_MEMBERS
, chptr
,
184 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
185 me
.name
, chptr
->chname
, chptr
->chname
,
186 (long) oldts
, (long) newts
);
187 /* Update capitalization in channel name, this makes the
188 * capitalization timestamped like modes are -- jilles */
189 strcpy(chptr
->chname
, parv
[2]);
191 sendto_channel_local(ALL_MEMBERS
, chptr
,
193 source_p
->servptr
->name
,
194 chptr
->chname
, modebuf
, parabuf
);
195 if(*omodebuf
!= '\0')
196 sendto_channel_local(ONLY_OPERS
, chptr
,
198 source_p
->servptr
->name
,
199 chptr
->chname
, modebuf
, parabuf
);
200 *omodebuf
= *modebuf
= *parabuf
= '\0';
203 if(!IsMember(source_p
, chptr
))
205 add_user_to_channel(chptr
, source_p
, CHFL_PEON
);
206 if (chptr
->mode
.join_num
&&
207 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
209 chptr
->join_count
= 0;
210 chptr
->join_delta
= rb_current_time();
213 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
214 source_p
->name
, source_p
->username
,
215 source_p
->host
, chptr
->chname
);
218 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
220 source_p
->id
, (long) chptr
->channelts
, chptr
->chname
);
225 ms_sjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
227 static char buf_uid
[BUFSIZE
];
228 static const char empty_modes
[] = "0";
229 struct Channel
*chptr
;
230 struct Client
*target_p
, *fakesource_p
;
233 static struct Mode mode
, *oldmode
;
236 int keep_our_modes
= 1;
237 int keep_new_modes
= 1;
248 int i
, joinc
= 0, timeslice
= 0;
249 static char empty
[] = "";
250 rb_dlink_node
*ptr
, *next_ptr
;
252 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
255 /* SJOIN's for local channels can't happen. */
259 omodebuf
[0] = modebuf
[0] = parabuf
[0] = mode
.key
[0] = mode
.forward
[0] = '\0';
260 pargs
= mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
262 /* Hide connecting server on netburst -- jilles */
263 if (ConfigServerHide
.flatten_links
&& !HasSentEob(source_p
))
266 fakesource_p
= source_p
;
270 newts
= atol(parv
[1]);
278 rb_strlcpy(mode
.forward
, parv
[4 + args
], sizeof(mode
.forward
));
284 sscanf(parv
[4 + args
], "%d:%d", &joinc
, ×lice
);
286 mode
.join_num
= joinc
;
287 mode
.join_time
= timeslice
;
292 rb_strlcpy(mode
.key
, parv
[4 + args
], sizeof(mode
.key
));
298 mode
.limit
= atoi(parv
[4 + args
]);
304 if(chmode_flags
[(int) *s
] != 0)
306 mode
.mode
|= chmode_flags
[(int) *s
];
315 /* remove any leading spaces */
322 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
323 return 0; /* channel name too long? */
326 oldts
= chptr
->channelts
;
327 oldmode
= &chptr
->mode
;
329 #ifdef IGNORE_BOGUS_TS
330 if(newts
< 800000000)
332 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
333 "*** Bogus TS %ld on %s ignored from %s",
334 (long) newts
, chptr
->chname
, client_p
->name
);
336 newts
= (oldts
== 0) ? oldts
: 800000000;
339 if(!isnew
&& !newts
&& oldts
)
341 sendto_channel_local(ALL_MEMBERS
, chptr
,
342 ":%s NOTICE %s :*** Notice -- TS for %s "
343 "changed from %ld to 0",
344 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
345 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
346 "Server %s changing TS on %s from %ld to 0",
347 source_p
->name
, chptr
->chname
, (long) oldts
);
352 chptr
->channelts
= newts
;
354 else if(newts
== 0 || oldts
== 0)
355 chptr
->channelts
= 0;
356 else if(newts
== oldts
)
358 else if(newts
< oldts
)
360 /* If configured, kick people trying to join +i/+k
361 * channels by recreating them on split servers.
362 * Don't kick if the source has sent EOB (services
363 * deopping everyone by TS-1 SJOIN).
365 if (ConfigChannel
.kick_on_split_riding
&&
366 !HasSentEob(source_p
) &&
367 ((mode
.mode
& MODE_INVITEONLY
) ||
368 (mode
.key
[0] != 0 && irccmp(mode
.key
, oldmode
->key
) != 0)))
370 struct membership
*msptr
;
372 int l
= rb_dlink_list_length(&chptr
->members
);
374 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
377 who
= msptr
->client_p
;
378 sendto_one(who
, ":%s KICK %s %s :Net Rider",
379 me
.name
, chptr
->chname
, who
->name
);
381 sendto_server(NULL
, chptr
, CAP_TS6
, NOCAPS
,
382 ":%s KICK %s %s :Net Rider",
383 me
.id
, chptr
->chname
,
385 remove_user_from_channel(msptr
);
391 /* Channel was emptied, create a new one */
392 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
393 return 0; /* oops! */
395 oldmode
= &chptr
->mode
;
399 chptr
->channelts
= newts
;
406 else if(keep_our_modes
)
408 mode
.mode
|= oldmode
->mode
;
409 if(oldmode
->limit
> mode
.limit
)
410 mode
.limit
= oldmode
->limit
;
411 if(strcmp(mode
.key
, oldmode
->key
) < 0)
412 strcpy(mode
.key
, oldmode
->key
);
413 if(oldmode
->join_num
> mode
.join_num
||
414 (oldmode
->join_num
== mode
.join_num
&&
415 oldmode
->join_time
> mode
.join_time
))
417 mode
.join_num
= oldmode
->join_num
;
418 mode
.join_time
= oldmode
->join_time
;
420 if(irccmp(mode
.forward
, oldmode
->forward
) < 0)
421 strcpy(mode
.forward
, oldmode
->forward
);
425 /* If setting -j, clear join throttle state -- jilles */
427 chptr
->join_count
= chptr
->join_delta
= 0;
430 set_final_mode(&mode
, oldmode
);
433 /* Lost the TS, other side wins, so remove modes on this side */
436 remove_our_modes(chptr
, fakesource_p
);
437 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
439 del_invite(chptr
, ptr
->data
);
442 if(rb_dlink_list_length(&chptr
->banlist
) > 0)
443 remove_ban_list(chptr
, fakesource_p
, &chptr
->banlist
, 'b', ALL_MEMBERS
);
444 if(rb_dlink_list_length(&chptr
->exceptlist
) > 0)
445 remove_ban_list(chptr
, fakesource_p
, &chptr
->exceptlist
,
447 if(rb_dlink_list_length(&chptr
->invexlist
) > 0)
448 remove_ban_list(chptr
, fakesource_p
, &chptr
->invexlist
,
450 if(rb_dlink_list_length(&chptr
->quietlist
) > 0)
451 remove_ban_list(chptr
, fakesource_p
, &chptr
->quietlist
,
455 sendto_channel_local(ALL_MEMBERS
, chptr
,
456 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
457 me
.name
, chptr
->chname
, chptr
->chname
,
458 (long) oldts
, (long) newts
);
459 /* Update capitalization in channel name, this makes the
460 * capitalization timestamped like modes are -- jilles */
461 strcpy(chptr
->chname
, parv
[2]);
465 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s MODE %s %s %s",
466 fakesource_p
->name
, chptr
->chname
, modebuf
, parabuf
);
468 if(*omodebuf
!= '\0')
469 sendto_channel_local(ONLY_OPERS
, chptr
, ":%s MODE %s %s %s",
470 fakesource_p
->name
, chptr
->chname
, omodebuf
, parabuf
);
472 *omodebuf
= *modebuf
= *parabuf
= '\0';
474 if(parv
[3][0] != '0' && keep_new_modes
)
475 modes
= channel_modes(chptr
, source_p
);
479 mlen_uid
= rb_sprintf(buf_uid
, ":%s SJOIN %ld %s %s :",
480 use_id(source_p
), (long) chptr
->channelts
, parv
[2], modes
);
481 ptr_uid
= buf_uid
+ mlen_uid
;
485 para
[0] = para
[1] = para
[2] = para
[3] = empty
;
487 len_nick
= len_uid
= 0;
489 /* if theres a space, theres going to be more than one nick, change the
490 * first space to \0, so s is just the first nick, and point p to the
493 if((p
= strchr(s
, ' ')) != NULL
)
504 for (i
= 0; i
< 2; i
++)
528 /* if the client doesnt exist or is fake direction, skip. */
529 if(!(target_p
= find_client(s
)) ||
530 (target_p
->from
!= client_p
) || !IsPerson(target_p
))
533 /* we assume for these we can fit at least one nick/uid in.. */
535 /* check we can fit another status+nick+space into a buffer */
536 if((mlen_uid
+ len_uid
+ IDLEN
+ 3) > (BUFSIZE
- 3))
538 *(ptr_uid
- 1) = '\0';
539 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
540 ptr_uid
= buf_uid
+ mlen_uid
;
572 /* copy the nick to the two buffers */
573 len
= rb_sprintf(ptr_uid
, "%s ", use_id(target_p
));
580 if(!IsMember(target_p
, chptr
))
582 add_user_to_channel(chptr
, target_p
, fl
);
583 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
585 target_p
->username
, target_p
->host
, parv
[2]);
589 /* If anyone can think of a way to do this that doesn't make babies cry
590 * I would love to hear it - Taros */
595 para
[pargs
++] = target_p
->name
;
599 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
602 if(pargs
>= MAXMODEPARAMS
)
605 sendto_channel_local(ALL_MEMBERS
, chptr
,
606 ":%s MODE %s %s %s %s %s %s",
607 fakesource_p
->name
, chptr
->chname
,
609 para
[0], para
[1], para
[2], para
[3]);
612 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
617 para
[pargs
++] = target_p
->name
;
621 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
624 if(pargs
>= MAXMODEPARAMS
)
627 sendto_channel_local(ALL_MEMBERS
, chptr
,
628 ":%s MODE %s %s %s %s %s %s",
629 fakesource_p
->name
, chptr
->chname
,
631 para
[0], para
[1], para
[2], para
[3]);
634 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
639 para
[pargs
++] = target_p
->name
;
643 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
646 if(pargs
>= MAXMODEPARAMS
)
649 sendto_channel_local(ALL_MEMBERS
, chptr
,
650 ":%s MODE %s %s %s %s %s %s",
651 fakesource_p
->name
, chptr
->chname
,
653 para
[0], para
[1], para
[2], para
[3]);
656 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
661 para
[pargs
++] = target_p
->name
;
667 para
[pargs
++] = target_p
->name
;
671 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
674 if(pargs
>= MAXMODEPARAMS
)
677 sendto_channel_local(ALL_MEMBERS
, chptr
,
678 ":%s MODE %s %s %s %s %s %s",
679 fakesource_p
->name
, chptr
->chname
,
681 para
[0], para
[1], para
[2], para
[3]);
684 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
689 para
[pargs
++] = target_p
->name
;
693 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
696 if(pargs
>= MAXMODEPARAMS
)
699 sendto_channel_local(ALL_MEMBERS
, chptr
,
700 ":%s MODE %s %s %s %s %s %s",
701 fakesource_p
->name
, chptr
->chname
,
703 para
[0], para
[1], para
[2], para
[3]);
706 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
711 para
[pargs
++] = target_p
->name
;
717 para
[pargs
++] = target_p
->name
;
721 /* its possible the +h has filled up MAXMODEPARAMS, if so, start
724 if(pargs
>= MAXMODEPARAMS
)
727 sendto_channel_local(ALL_MEMBERS
, chptr
,
728 ":%s MODE %s %s %s %s %s %s",
729 fakesource_p
->name
, chptr
->chname
,
731 para
[0], para
[1], para
[2], para
[3]);
734 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
739 para
[pargs
++] = target_p
->name
;
742 else if(fl
& CHFL_VOICE
)
745 para
[pargs
++] = target_p
->name
;
748 if(pargs
>= MAXMODEPARAMS
)
751 sendto_channel_local(ALL_MEMBERS
, chptr
,
752 ":%s MODE %s %s %s %s %s %s",
755 modebuf
, para
[0], para
[1], para
[2], para
[3]);
758 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
763 /* p points to the next nick */
766 /* if there was a trailing space and p was pointing to it, then we
767 * need to exit.. this has the side effect of breaking double spaces
768 * in an sjoin.. but that shouldnt happen anyway
770 if(s
&& (*s
== '\0'))
773 /* if p was NULL due to no spaces, s wont exist due to the above, so
774 * we cant check it for spaces.. if there are no spaces, then when
775 * we next get here, s will be NULL
777 if(s
&& ((p
= strchr(s
, ' ')) != NULL
))
786 sendto_channel_local(ALL_MEMBERS
, chptr
,
787 ":%s MODE %s %s %s %s %s %s",
788 fakesource_p
->name
, chptr
->chname
, modebuf
,
789 para
[0], CheckEmpty(para
[1]),
790 CheckEmpty(para
[2]), CheckEmpty(para
[3]));
793 if(!joins
&& !(chptr
->mode
.mode
& MODE_PERMANENT
) && isnew
)
795 destroy_channel(chptr
);
800 /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
803 *(ptr_uid
- 1) = '\0';
806 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
813 set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
)
815 int dir
= MODE_QUERY
, odir
= MODE_QUERY
;
816 char *pbuf
= parabuf
;
820 /* ok, first get a list of modes we need to add */
821 for (i
= 0; i
< 256; i
++)
823 if((mode
->mode
& chmode_flags
[i
]) && !(oldmode
->mode
& chmode_flags
[i
]))
825 if (chmode_table
[i
].set_func
== chm_hidden
)
847 /* now the ones we need to remove. */
848 for (i
= 0; i
< 256; i
++)
850 if((oldmode
->mode
& chmode_flags
[i
]) && !(mode
->mode
& chmode_flags
[i
]))
852 if(chmode_table
[i
].set_func
== chm_hidden
)
873 if(oldmode
->limit
&& !mode
->limit
)
882 if(oldmode
->key
[0] && !mode
->key
[0])
890 len
= rb_sprintf(pbuf
, "%s ", oldmode
->key
);
893 if(oldmode
->join_num
&& !mode
->join_num
)
902 if(oldmode
->forward
[0] && !mode
->forward
[0])
911 if(mode
->limit
&& oldmode
->limit
!= mode
->limit
)
919 len
= rb_sprintf(pbuf
, "%d ", mode
->limit
);
922 if(mode
->key
[0] && strcmp(oldmode
->key
, mode
->key
))
930 len
= rb_sprintf(pbuf
, "%s ", mode
->key
);
933 if(mode
->join_num
&& (oldmode
->join_num
!= mode
->join_num
|| oldmode
->join_time
!= mode
->join_time
))
941 len
= rb_sprintf(pbuf
, "%d:%d ", mode
->join_num
, mode
->join_time
);
944 if(mode
->forward
[0] && strcmp(oldmode
->forward
, mode
->forward
) && ConfigChannel
.use_forward
)
952 len
= rb_sprintf(pbuf
, "%s ", mode
->forward
);
966 remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
)
968 struct membership
*msptr
;
970 char lmodebuf
[MODEBUFLEN
];
971 char *lpara
[MAXMODEPARAMS
];
978 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
981 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
985 /* If anyone can think of a way to do this that doesn't make babies cry
986 * I would love to hear it - Taros */
990 msptr
->flags
&= ~CHFL_OWNER
;
991 lpara
[count
++] = msptr
->client_p
->name
;
994 /* Make sure it fits if +h, +o, or +v are involved */
997 if(count
>= MAXMODEPARAMS
)
1000 sendto_channel_local(ALL_MEMBERS
, chptr
,
1001 ":%s MODE %s %s %s %s %s %s",
1002 source_p
->name
, chptr
->chname
,
1003 lmodebuf
, lpara
[0], lpara
[1],
1004 lpara
[2], lpara
[3]);
1006 /* preserve the initial '-' */
1011 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1015 msptr
->flags
&= ~CHFL_CHANOP
;
1016 lpara
[count
++] = msptr
->client_p
->name
;
1019 if(is_halfop(msptr
))
1021 if(count
>= MAXMODEPARAMS
)
1024 sendto_channel_local(ALL_MEMBERS
, chptr
,
1025 ":%s MODE %s %s %s %s %s %s",
1026 source_p
->name
, chptr
->chname
,
1027 lmodebuf
, lpara
[0], lpara
[1],
1028 lpara
[2], lpara
[3]);
1030 /* preserve the initial '-' */
1035 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1039 msptr
->flags
&= ~CHFL_HALFOP
;
1040 lpara
[count
++] = msptr
->client_p
->name
;
1043 if(is_voiced(msptr
))
1045 if(count
>= MAXMODEPARAMS
)
1048 sendto_channel_local(ALL_MEMBERS
, chptr
,
1049 ":%s MODE %s %s %s %s %s %s",
1050 source_p
->name
, chptr
->chname
,
1051 lmodebuf
, lpara
[0], lpara
[1],
1052 lpara
[2], lpara
[3]);
1054 /* preserve the initial '-' */
1059 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1063 msptr
->flags
&= ~CHFL_VOICE
;
1064 lpara
[count
++] = msptr
->client_p
->name
;
1068 else if(is_chanop(msptr
))
1070 msptr
->flags
&= ~CHFL_CHANOP
;
1071 lpara
[count
++] = msptr
->client_p
->name
;
1074 /* Make sure it fits if +h or +v are involved */
1075 if(is_halfop(msptr
))
1077 if(count
>= MAXMODEPARAMS
)
1080 sendto_channel_local(ALL_MEMBERS
, chptr
,
1081 ":%s MODE %s %s %s %s %s %s",
1082 source_p
->name
, chptr
->chname
,
1083 lmodebuf
, lpara
[0], lpara
[1],
1084 lpara
[2], lpara
[3]);
1086 /* preserve the initial '-' */
1091 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1095 msptr
->flags
&= ~CHFL_HALFOP
;
1096 lpara
[count
++] = msptr
->client_p
->name
;
1099 if(is_voiced(msptr
))
1101 if(count
>= MAXMODEPARAMS
)
1104 sendto_channel_local(ALL_MEMBERS
, chptr
,
1105 ":%s MODE %s %s %s %s %s %s",
1106 source_p
->name
, chptr
->chname
,
1107 lmodebuf
, lpara
[0], lpara
[1],
1108 lpara
[2], lpara
[3]);
1110 /* preserve the initial '-' */
1115 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1119 msptr
->flags
&= ~CHFL_VOICE
;
1120 lpara
[count
++] = msptr
->client_p
->name
;
1124 else if(is_halfop(msptr
))
1126 msptr
->flags
&= ~CHFL_HALFOP
;
1127 lpara
[count
++] = msptr
->client_p
->name
;
1130 /* +hv, might not fit so check. */
1131 if(is_voiced(msptr
))
1133 if(count
>= MAXMODEPARAMS
)
1136 sendto_channel_local(ALL_MEMBERS
, chptr
,
1137 ":%s MODE %s %s %s %s %s %s",
1138 source_p
->name
, chptr
->chname
,
1139 lmodebuf
, lpara
[0], lpara
[1],
1140 lpara
[2], lpara
[3]);
1142 /* preserve the initial '-' */
1147 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1151 msptr
->flags
&= ~CHFL_VOICE
;
1152 lpara
[count
++] = msptr
->client_p
->name
;
1156 else if(is_voiced(msptr
))
1158 msptr
->flags
&= ~CHFL_VOICE
;
1159 lpara
[count
++] = msptr
->client_p
->name
;
1165 if(count
>= MAXMODEPARAMS
)
1168 sendto_channel_local(ALL_MEMBERS
, chptr
,
1169 ":%s MODE %s %s %s %s %s %s",
1170 source_p
->name
, chptr
->chname
, lmodebuf
,
1171 lpara
[0], lpara
[1], lpara
[2], lpara
[3]);
1176 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1184 sendto_channel_local(ALL_MEMBERS
, chptr
,
1185 ":%s MODE %s %s %s %s %s %s",
1186 source_p
->name
, chptr
->chname
, lmodebuf
,
1187 EmptyString(lpara
[0]) ? "" : lpara
[0],
1188 EmptyString(lpara
[1]) ? "" : lpara
[1],
1189 EmptyString(lpara
[2]) ? "" : lpara
[2],
1190 EmptyString(lpara
[3]) ? "" : lpara
[3]);
1195 /* remove_ban_list()
1197 * inputs - channel, source, list to remove, char of mode, caps needed
1199 * side effects - given list is removed, with modes issued to local clients
1202 remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
1203 rb_dlink_list
* list
, char c
, int mems
)
1205 static char lmodebuf
[BUFSIZE
];
1206 static char lparabuf
[BUFSIZE
];
1209 rb_dlink_node
*next_ptr
;
1212 int cur_len
, mlen
, plen
;
1216 cur_len
= mlen
= rb_sprintf(lmodebuf
, ":%s MODE %s -", source_p
->name
, chptr
->chname
);
1217 mbuf
= lmodebuf
+ mlen
;
1219 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, list
->head
)
1223 /* trailing space, and the mode letter itself */
1224 plen
= strlen(banptr
->banstr
) + 2;
1226 if(count
>= MAXMODEPARAMS
|| (cur_len
+ plen
) > BUFSIZE
- 4)
1228 /* remove trailing space */
1232 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1235 mbuf
= lmodebuf
+ mlen
;
1242 pbuf
+= rb_sprintf(pbuf
, "%s ", banptr
->banstr
);
1250 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1252 list
->head
= list
->tail
= NULL
;