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 me_svsjoin(struct Client
*, struct Client
*, int, const char **);
47 static int ms_join(struct Client
*, struct Client
*, int, const char **);
48 static int ms_sjoin(struct Client
*, struct Client
*, int, const char **);
50 struct Message join_msgtab
= {
51 "JOIN", 0, 0, 0, MFLG_SLOW
,
52 {mg_unreg
, {m_join
, 2}, {ms_join
, 2}, mg_ignore
, mg_ignore
, {m_join
, 2}}
55 struct Message svsjoin_msgtab
= {
56 "SVSJOIN", 0, 0, 0, MFLG_SLOW
,
57 {mg_ignore
, mg_ignore
, mg_ignore
, mg_ignore
, {me_svsjoin
, 3}, mg_ignore
}
60 struct Message sjoin_msgtab
= {
61 "SJOIN", 0, 0, 0, MFLG_SLOW
,
62 {mg_unreg
, mg_ignore
, mg_ignore
, {ms_sjoin
, 4}, mg_ignore
, mg_ignore
}
65 mapi_clist_av1 join_clist
[] = { &join_msgtab
, &svsjoin_msgtab
, &sjoin_msgtab
, NULL
};
67 DECLARE_MODULE_AV1(join
, NULL
, NULL
, join_clist
, NULL
, NULL
, "$Revision: 3494 $");
69 static void set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
);
70 static void remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
);
72 static void remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
73 rb_dlink_list
* list
, char c
, int mems
);
75 static char modebuf
[MODEBUFLEN
];
76 static char omodebuf
[MODEBUFLEN
];
77 static char parabuf
[MODEBUFLEN
];
78 static const char *para
[MAXMODEPARAMS
];
79 static char *mbuf
, *ombuf
;
85 * parv[2] = channel password (key)
88 m_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
90 user_join(client_p
, source_p
, parv
[1], parc
> 2 ? parv
[2] : NULL
); /* channel.c */
96 * me_svsjoin - small function to allow services to forcejoin clients, mainly for ns_ajoin
97 * parv[1] = user to act on (join to a channel)
99 * This does allow opers to "forcejoin" users to channels with operserv/raw or by writing a
100 * custom module (where they can make it not log anything), but the former bitches that it's
101 * being used and the latter...Can probably be done anyway with enough hackyness if this
102 * command didn't exist so it's not all that bad.
105 me_svsjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
107 struct Client
*target_p
;
109 if(!(source_p
->flags
& FLAGS_SERVICE
))
112 if((target_p
= find_person(parv
[1])) == NULL
)
115 user_join(&me
, target_p
, parv
[2], NULL
);
121 * parv[1] = channel TS
123 * parv[3] = "+", formerly channel modes but now unused
124 * alternatively, a single "0" parameter parts all channels
127 ms_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
129 struct Channel
*chptr
;
130 static struct Mode mode
;
134 int keep_our_modes
= YES
;
135 int keep_new_modes
= YES
;
136 rb_dlink_node
*ptr
, *next_ptr
;
138 /* special case for join 0 */
139 if((parv
[1][0] == '0') && (parv
[1][1] == '\0') && parc
== 2)
141 do_join_0(client_p
, source_p
);
148 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
151 /* joins for local channels cant happen. */
152 if(parv
[2][0] == '&')
157 mode
.key
[0] = mode
.forward
[0] = '\0';
158 mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
160 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
163 newts
= atol(parv
[1]);
164 oldts
= chptr
->channelts
;
166 #ifdef IGNORE_BOGUS_TS
167 if(newts
< 800000000)
169 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
170 "*** Bogus TS %ld on %s ignored from %s",
171 (long) newts
, chptr
->chname
, client_p
->name
);
172 newts
= (oldts
== 0) ? oldts
: 800000000;
175 /* making a channel TS0 */
176 if(!isnew
&& !newts
&& oldts
)
178 sendto_channel_local(ALL_MEMBERS
, chptr
,
179 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
180 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
181 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
182 "Server %s changing TS on %s from %ld to 0",
183 source_p
->name
, chptr
->chname
, (long) oldts
);
188 chptr
->channelts
= newts
;
189 else if(newts
== 0 || oldts
== 0)
190 chptr
->channelts
= 0;
191 else if(newts
== oldts
)
193 else if(newts
< oldts
)
196 chptr
->channelts
= newts
;
201 /* Lost the TS, other side wins, so remove modes on this side */
204 set_final_mode(&mode
, &chptr
->mode
);
206 remove_our_modes(chptr
, source_p
);
207 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
209 del_invite(chptr
, ptr
->data
);
211 /* If setting -j, clear join throttle state -- jilles */
212 chptr
->join_count
= chptr
->join_delta
= 0;
213 sendto_channel_local(ALL_MEMBERS
, chptr
,
214 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
215 me
.name
, chptr
->chname
, chptr
->chname
,
216 (long) oldts
, (long) newts
);
217 /* Update capitalization in channel name, this makes the
218 * capitalization timestamped like modes are -- jilles */
219 strcpy(chptr
->chname
, parv
[2]);
221 sendto_channel_local(ALL_MEMBERS
, chptr
,
223 source_p
->servptr
->name
,
224 chptr
->chname
, modebuf
, parabuf
);
225 if(*omodebuf
!= '\0')
226 sendto_channel_local(ONLY_OPERS
, chptr
,
228 source_p
->servptr
->name
,
229 chptr
->chname
, modebuf
, parabuf
);
230 *omodebuf
= *modebuf
= *parabuf
= '\0';
233 if(!IsMember(source_p
, chptr
))
235 add_user_to_channel(chptr
, source_p
, CHFL_PEON
);
236 if (chptr
->mode
.join_num
&&
237 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
239 chptr
->join_count
= 0;
240 chptr
->join_delta
= rb_current_time();
243 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
244 source_p
->name
, source_p
->username
,
245 source_p
->host
, chptr
->chname
);
248 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
250 source_p
->id
, (long) chptr
->channelts
, chptr
->chname
);
255 ms_sjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
257 static char buf_uid
[BUFSIZE
];
258 static const char empty_modes
[] = "0";
259 struct Channel
*chptr
;
260 struct Client
*target_p
, *fakesource_p
;
263 static struct Mode mode
, *oldmode
;
266 int keep_our_modes
= 1;
267 int keep_new_modes
= 1;
278 int i
, joinc
= 0, timeslice
= 0;
279 static char empty
[] = "";
280 rb_dlink_node
*ptr
, *next_ptr
;
282 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
285 /* SJOIN's for local channels can't happen. */
289 omodebuf
[0] = modebuf
[0] = parabuf
[0] = mode
.key
[0] = mode
.forward
[0] = '\0';
290 pargs
= mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
292 /* Hide connecting server on netburst -- jilles */
293 if (ConfigServerHide
.flatten_links
&& !HasSentEob(source_p
))
296 fakesource_p
= source_p
;
300 newts
= atol(parv
[1]);
308 rb_strlcpy(mode
.forward
, parv
[4 + args
], sizeof(mode
.forward
));
314 sscanf(parv
[4 + args
], "%d:%d", &joinc
, ×lice
);
316 mode
.join_num
= joinc
;
317 mode
.join_time
= timeslice
;
322 rb_strlcpy(mode
.key
, parv
[4 + args
], sizeof(mode
.key
));
328 mode
.limit
= atoi(parv
[4 + args
]);
334 if(chmode_flags
[(int) *s
] != 0)
336 mode
.mode
|= chmode_flags
[(int) *s
];
345 /* remove any leading spaces */
352 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
353 return 0; /* channel name too long? */
356 oldts
= chptr
->channelts
;
357 oldmode
= &chptr
->mode
;
359 #ifdef IGNORE_BOGUS_TS
360 if(newts
< 800000000)
362 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
363 "*** Bogus TS %ld on %s ignored from %s",
364 (long) newts
, chptr
->chname
, client_p
->name
);
366 newts
= (oldts
== 0) ? oldts
: 800000000;
369 if(!isnew
&& !newts
&& oldts
)
371 sendto_channel_local(ALL_MEMBERS
, chptr
,
372 ":%s NOTICE %s :*** Notice -- TS for %s "
373 "changed from %ld to 0",
374 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
375 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
376 "Server %s changing TS on %s from %ld to 0",
377 source_p
->name
, chptr
->chname
, (long) oldts
);
382 chptr
->channelts
= newts
;
384 else if(newts
== 0 || oldts
== 0)
385 chptr
->channelts
= 0;
386 else if(newts
== oldts
)
388 else if(newts
< oldts
)
390 /* If configured, kick people trying to join +i/+k
391 * channels by recreating them on split servers.
392 * Don't kick if the source has sent EOB (services
393 * deopping everyone by TS-1 SJOIN).
395 if (ConfigChannel
.kick_on_split_riding
&&
396 !HasSentEob(source_p
) &&
397 ((mode
.mode
& MODE_INVITEONLY
) ||
398 (mode
.key
[0] != 0 && irccmp(mode
.key
, oldmode
->key
) != 0)))
400 struct membership
*msptr
;
402 int l
= rb_dlink_list_length(&chptr
->members
);
404 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
407 who
= msptr
->client_p
;
408 sendto_one(who
, ":%s KICK %s %s :Net Rider",
409 me
.name
, chptr
->chname
, who
->name
);
411 sendto_server(NULL
, chptr
, CAP_TS6
, NOCAPS
,
412 ":%s KICK %s %s :Net Rider",
413 me
.id
, chptr
->chname
,
415 remove_user_from_channel(msptr
);
421 /* Channel was emptied, create a new one */
422 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
423 return 0; /* oops! */
425 oldmode
= &chptr
->mode
;
429 chptr
->channelts
= newts
;
436 else if(keep_our_modes
)
438 mode
.mode
|= oldmode
->mode
;
439 if(oldmode
->limit
> mode
.limit
)
440 mode
.limit
= oldmode
->limit
;
441 if(strcmp(mode
.key
, oldmode
->key
) < 0)
442 strcpy(mode
.key
, oldmode
->key
);
443 if(oldmode
->join_num
> mode
.join_num
||
444 (oldmode
->join_num
== mode
.join_num
&&
445 oldmode
->join_time
> mode
.join_time
))
447 mode
.join_num
= oldmode
->join_num
;
448 mode
.join_time
= oldmode
->join_time
;
450 if(irccmp(mode
.forward
, oldmode
->forward
) < 0)
451 strcpy(mode
.forward
, oldmode
->forward
);
455 /* If setting -j, clear join throttle state -- jilles */
457 chptr
->join_count
= chptr
->join_delta
= 0;
460 set_final_mode(&mode
, oldmode
);
463 /* Lost the TS, other side wins, so remove modes on this side */
466 remove_our_modes(chptr
, fakesource_p
);
467 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
469 del_invite(chptr
, ptr
->data
);
472 if(rb_dlink_list_length(&chptr
->banlist
) > 0)
473 remove_ban_list(chptr
, fakesource_p
, &chptr
->banlist
, 'b', ALL_MEMBERS
);
474 if(rb_dlink_list_length(&chptr
->exceptlist
) > 0)
475 remove_ban_list(chptr
, fakesource_p
, &chptr
->exceptlist
,
477 if(rb_dlink_list_length(&chptr
->invexlist
) > 0)
478 remove_ban_list(chptr
, fakesource_p
, &chptr
->invexlist
,
480 if(rb_dlink_list_length(&chptr
->quietlist
) > 0)
481 remove_ban_list(chptr
, fakesource_p
, &chptr
->quietlist
,
485 sendto_channel_local(ALL_MEMBERS
, chptr
,
486 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
487 me
.name
, chptr
->chname
, chptr
->chname
,
488 (long) oldts
, (long) newts
);
489 /* Update capitalization in channel name, this makes the
490 * capitalization timestamped like modes are -- jilles */
491 strcpy(chptr
->chname
, parv
[2]);
495 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s MODE %s %s %s",
496 fakesource_p
->name
, chptr
->chname
, modebuf
, parabuf
);
498 if(*omodebuf
!= '\0')
499 sendto_channel_local(ONLY_OPERS
, chptr
, ":%s MODE %s %s %s",
500 fakesource_p
->name
, chptr
->chname
, omodebuf
, parabuf
);
502 *omodebuf
= *modebuf
= *parabuf
= '\0';
504 if(parv
[3][0] != '0' && keep_new_modes
)
505 modes
= channel_modes(chptr
, source_p
);
509 mlen_uid
= rb_sprintf(buf_uid
, ":%s SJOIN %ld %s %s :",
510 use_id(source_p
), (long) chptr
->channelts
, parv
[2], modes
);
511 ptr_uid
= buf_uid
+ mlen_uid
;
515 para
[0] = para
[1] = para
[2] = para
[3] = empty
;
517 len_nick
= len_uid
= 0;
519 /* if theres a space, theres going to be more than one nick, change the
520 * first space to \0, so s is just the first nick, and point p to the
523 if((p
= strchr(s
, ' ')) != NULL
)
534 for (i
= 0; i
< 2; i
++)
558 /* if the client doesnt exist or is fake direction, skip. */
559 if(!(target_p
= find_client(s
)) ||
560 (target_p
->from
!= client_p
) || !IsPerson(target_p
))
563 /* we assume for these we can fit at least one nick/uid in.. */
565 /* check we can fit another status+nick+space into a buffer */
566 if((mlen_uid
+ len_uid
+ IDLEN
+ 3) > (BUFSIZE
- 3))
568 *(ptr_uid
- 1) = '\0';
569 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
570 ptr_uid
= buf_uid
+ mlen_uid
;
602 /* copy the nick to the two buffers */
603 len
= rb_sprintf(ptr_uid
, "%s ", use_id(target_p
));
610 if(!IsMember(target_p
, chptr
))
612 add_user_to_channel(chptr
, target_p
, fl
);
613 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
615 target_p
->username
, target_p
->host
, parv
[2]);
619 /* If anyone can think of a way to do this that doesn't make babies cry
620 * I would love to hear it - Taros */
625 para
[pargs
++] = target_p
->name
;
629 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
632 if(pargs
>= MAXMODEPARAMS
)
635 sendto_channel_local(ALL_MEMBERS
, chptr
,
636 ":%s MODE %s %s %s %s %s %s",
637 fakesource_p
->name
, chptr
->chname
,
639 para
[0], para
[1], para
[2], para
[3]);
642 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
647 para
[pargs
++] = target_p
->name
;
651 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
654 if(pargs
>= MAXMODEPARAMS
)
657 sendto_channel_local(ALL_MEMBERS
, chptr
,
658 ":%s MODE %s %s %s %s %s %s",
659 fakesource_p
->name
, chptr
->chname
,
661 para
[0], para
[1], para
[2], para
[3]);
664 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
669 para
[pargs
++] = target_p
->name
;
673 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
676 if(pargs
>= MAXMODEPARAMS
)
679 sendto_channel_local(ALL_MEMBERS
, chptr
,
680 ":%s MODE %s %s %s %s %s %s",
681 fakesource_p
->name
, chptr
->chname
,
683 para
[0], para
[1], para
[2], para
[3]);
686 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
691 para
[pargs
++] = target_p
->name
;
697 para
[pargs
++] = target_p
->name
;
701 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
704 if(pargs
>= MAXMODEPARAMS
)
707 sendto_channel_local(ALL_MEMBERS
, chptr
,
708 ":%s MODE %s %s %s %s %s %s",
709 fakesource_p
->name
, chptr
->chname
,
711 para
[0], para
[1], para
[2], para
[3]);
714 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
719 para
[pargs
++] = target_p
->name
;
723 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
726 if(pargs
>= MAXMODEPARAMS
)
729 sendto_channel_local(ALL_MEMBERS
, chptr
,
730 ":%s MODE %s %s %s %s %s %s",
731 fakesource_p
->name
, chptr
->chname
,
733 para
[0], para
[1], para
[2], para
[3]);
736 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
741 para
[pargs
++] = target_p
->name
;
747 para
[pargs
++] = target_p
->name
;
751 /* its possible the +h has filled up MAXMODEPARAMS, if so, start
754 if(pargs
>= MAXMODEPARAMS
)
757 sendto_channel_local(ALL_MEMBERS
, chptr
,
758 ":%s MODE %s %s %s %s %s %s",
759 fakesource_p
->name
, chptr
->chname
,
761 para
[0], para
[1], para
[2], para
[3]);
764 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
769 para
[pargs
++] = target_p
->name
;
772 else if(fl
& CHFL_VOICE
)
775 para
[pargs
++] = target_p
->name
;
778 if(pargs
>= MAXMODEPARAMS
)
781 sendto_channel_local(ALL_MEMBERS
, chptr
,
782 ":%s MODE %s %s %s %s %s %s",
785 modebuf
, para
[0], para
[1], para
[2], para
[3]);
788 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
793 /* p points to the next nick */
796 /* if there was a trailing space and p was pointing to it, then we
797 * need to exit.. this has the side effect of breaking double spaces
798 * in an sjoin.. but that shouldnt happen anyway
800 if(s
&& (*s
== '\0'))
803 /* if p was NULL due to no spaces, s wont exist due to the above, so
804 * we cant check it for spaces.. if there are no spaces, then when
805 * we next get here, s will be NULL
807 if(s
&& ((p
= strchr(s
, ' ')) != NULL
))
816 sendto_channel_local(ALL_MEMBERS
, chptr
,
817 ":%s MODE %s %s %s %s %s %s",
818 fakesource_p
->name
, chptr
->chname
, modebuf
,
819 para
[0], CheckEmpty(para
[1]),
820 CheckEmpty(para
[2]), CheckEmpty(para
[3]));
823 if(!joins
&& !(chptr
->mode
.mode
& MODE_PERMANENT
) && isnew
)
825 destroy_channel(chptr
);
830 /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
833 *(ptr_uid
- 1) = '\0';
836 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
843 set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
)
845 int dir
= MODE_QUERY
, odir
= MODE_QUERY
;
846 char *pbuf
= parabuf
;
850 /* ok, first get a list of modes we need to add */
851 for (i
= 0; i
< 256; i
++)
853 if((mode
->mode
& chmode_flags
[i
]) && !(oldmode
->mode
& chmode_flags
[i
]))
855 if (chmode_table
[i
].set_func
== chm_hidden
)
877 /* now the ones we need to remove. */
878 for (i
= 0; i
< 256; i
++)
880 if((oldmode
->mode
& chmode_flags
[i
]) && !(mode
->mode
& chmode_flags
[i
]))
882 if(chmode_table
[i
].set_func
== chm_hidden
)
903 if(oldmode
->limit
&& !mode
->limit
)
912 if(oldmode
->key
[0] && !mode
->key
[0])
920 len
= rb_sprintf(pbuf
, "%s ", oldmode
->key
);
923 if(oldmode
->join_num
&& !mode
->join_num
)
932 if(oldmode
->forward
[0] && !mode
->forward
[0])
941 if(mode
->limit
&& oldmode
->limit
!= mode
->limit
)
949 len
= rb_sprintf(pbuf
, "%d ", mode
->limit
);
952 if(mode
->key
[0] && strcmp(oldmode
->key
, mode
->key
))
960 len
= rb_sprintf(pbuf
, "%s ", mode
->key
);
963 if(mode
->join_num
&& (oldmode
->join_num
!= mode
->join_num
|| oldmode
->join_time
!= mode
->join_time
))
971 len
= rb_sprintf(pbuf
, "%d:%d ", mode
->join_num
, mode
->join_time
);
974 if(mode
->forward
[0] && strcmp(oldmode
->forward
, mode
->forward
) && ConfigChannel
.use_forward
)
982 len
= rb_sprintf(pbuf
, "%s ", mode
->forward
);
996 remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
)
998 struct membership
*msptr
;
1000 char lmodebuf
[MODEBUFLEN
];
1001 char *lpara
[MAXMODEPARAMS
];
1008 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1011 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
1015 /* If anyone can think of a way to do this that doesn't make babies cry
1016 * I would love to hear it - Taros */
1020 msptr
->flags
&= ~CHFL_ADMIN
;
1021 lpara
[count
++] = msptr
->client_p
->name
;
1024 /* Make sure it fits if +h, +o, or +v are involved */
1025 if(is_chanop(msptr
))
1027 if(count
>= MAXMODEPARAMS
)
1030 sendto_channel_local(ALL_MEMBERS
, chptr
,
1031 ":%s MODE %s %s %s %s %s %s",
1032 source_p
->name
, chptr
->chname
,
1033 lmodebuf
, lpara
[0], lpara
[1],
1034 lpara
[2], lpara
[3]);
1036 /* preserve the initial '-' */
1041 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1045 msptr
->flags
&= ~CHFL_CHANOP
;
1046 lpara
[count
++] = msptr
->client_p
->name
;
1049 if(is_halfop(msptr
))
1051 if(count
>= MAXMODEPARAMS
)
1054 sendto_channel_local(ALL_MEMBERS
, chptr
,
1055 ":%s MODE %s %s %s %s %s %s",
1056 source_p
->name
, chptr
->chname
,
1057 lmodebuf
, lpara
[0], lpara
[1],
1058 lpara
[2], lpara
[3]);
1060 /* preserve the initial '-' */
1065 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1069 msptr
->flags
&= ~CHFL_HALFOP
;
1070 lpara
[count
++] = msptr
->client_p
->name
;
1073 if(is_voiced(msptr
))
1075 if(count
>= MAXMODEPARAMS
)
1078 sendto_channel_local(ALL_MEMBERS
, chptr
,
1079 ":%s MODE %s %s %s %s %s %s",
1080 source_p
->name
, chptr
->chname
,
1081 lmodebuf
, lpara
[0], lpara
[1],
1082 lpara
[2], lpara
[3]);
1084 /* preserve the initial '-' */
1089 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1093 msptr
->flags
&= ~CHFL_VOICE
;
1094 lpara
[count
++] = msptr
->client_p
->name
;
1098 else if(is_chanop(msptr
))
1100 msptr
->flags
&= ~CHFL_CHANOP
;
1101 lpara
[count
++] = msptr
->client_p
->name
;
1104 /* Make sure it fits if +h or +v are involved */
1105 if(is_halfop(msptr
))
1107 if(count
>= MAXMODEPARAMS
)
1110 sendto_channel_local(ALL_MEMBERS
, chptr
,
1111 ":%s MODE %s %s %s %s %s %s",
1112 source_p
->name
, chptr
->chname
,
1113 lmodebuf
, lpara
[0], lpara
[1],
1114 lpara
[2], lpara
[3]);
1116 /* preserve the initial '-' */
1121 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1125 msptr
->flags
&= ~CHFL_HALFOP
;
1126 lpara
[count
++] = msptr
->client_p
->name
;
1129 if(is_voiced(msptr
))
1131 if(count
>= MAXMODEPARAMS
)
1134 sendto_channel_local(ALL_MEMBERS
, chptr
,
1135 ":%s MODE %s %s %s %s %s %s",
1136 source_p
->name
, chptr
->chname
,
1137 lmodebuf
, lpara
[0], lpara
[1],
1138 lpara
[2], lpara
[3]);
1140 /* preserve the initial '-' */
1145 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1149 msptr
->flags
&= ~CHFL_VOICE
;
1150 lpara
[count
++] = msptr
->client_p
->name
;
1154 else if(is_halfop(msptr
))
1156 msptr
->flags
&= ~CHFL_HALFOP
;
1157 lpara
[count
++] = msptr
->client_p
->name
;
1160 /* +hv, might not fit so check. */
1161 if(is_voiced(msptr
))
1163 if(count
>= MAXMODEPARAMS
)
1166 sendto_channel_local(ALL_MEMBERS
, chptr
,
1167 ":%s MODE %s %s %s %s %s %s",
1168 source_p
->name
, chptr
->chname
,
1169 lmodebuf
, lpara
[0], lpara
[1],
1170 lpara
[2], lpara
[3]);
1172 /* preserve the initial '-' */
1177 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1181 msptr
->flags
&= ~CHFL_VOICE
;
1182 lpara
[count
++] = msptr
->client_p
->name
;
1186 else if(is_voiced(msptr
))
1188 msptr
->flags
&= ~CHFL_VOICE
;
1189 lpara
[count
++] = msptr
->client_p
->name
;
1195 if(count
>= MAXMODEPARAMS
)
1198 sendto_channel_local(ALL_MEMBERS
, chptr
,
1199 ":%s MODE %s %s %s %s %s %s",
1200 source_p
->name
, chptr
->chname
, lmodebuf
,
1201 lpara
[0], lpara
[1], lpara
[2], lpara
[3]);
1206 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1214 sendto_channel_local(ALL_MEMBERS
, chptr
,
1215 ":%s MODE %s %s %s %s %s %s",
1216 source_p
->name
, chptr
->chname
, lmodebuf
,
1217 EmptyString(lpara
[0]) ? "" : lpara
[0],
1218 EmptyString(lpara
[1]) ? "" : lpara
[1],
1219 EmptyString(lpara
[2]) ? "" : lpara
[2],
1220 EmptyString(lpara
[3]) ? "" : lpara
[3]);
1225 /* remove_ban_list()
1227 * inputs - channel, source, list to remove, char of mode, caps needed
1229 * side effects - given list is removed, with modes issued to local clients
1232 remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
1233 rb_dlink_list
* list
, char c
, int mems
)
1235 static char lmodebuf
[BUFSIZE
];
1236 static char lparabuf
[BUFSIZE
];
1239 rb_dlink_node
*next_ptr
;
1242 int cur_len
, mlen
, plen
;
1246 cur_len
= mlen
= rb_sprintf(lmodebuf
, ":%s MODE %s -", source_p
->name
, chptr
->chname
);
1247 mbuf
= lmodebuf
+ mlen
;
1249 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, list
->head
)
1253 /* trailing space, and the mode letter itself */
1254 plen
= strlen(banptr
->banstr
) + 2;
1256 if(count
>= MAXMODEPARAMS
|| (cur_len
+ plen
) > BUFSIZE
- 4)
1258 /* remove trailing space */
1262 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1265 mbuf
= lmodebuf
+ mlen
;
1272 pbuf
+= rb_sprintf(pbuf
, "%s ", banptr
->banstr
);
1280 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1282 list
->head
= list
->tail
= NULL
;