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
37 #include "s_newconf.h"
44 static int m_join(struct Client
*, struct Client
*, int, const char **);
45 static int me_svsjoin(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 svsjoin_msgtab
= {
55 "SVSJOIN", 0, 0, 0, MFLG_SLOW
,
56 {mg_ignore
, mg_ignore
, mg_ignore
, mg_ignore
, {me_svsjoin
, 3}, mg_ignore
}
59 struct Message sjoin_msgtab
= {
60 "SJOIN", 0, 0, 0, MFLG_SLOW
,
61 {mg_unreg
, mg_ignore
, mg_ignore
, {ms_sjoin
, 4}, mg_ignore
, mg_ignore
}
64 mapi_clist_av1 join_clist
[] = { &join_msgtab
, &svsjoin_msgtab
, &sjoin_msgtab
, NULL
};
66 DECLARE_MODULE_AV1(join
, NULL
, NULL
, join_clist
, NULL
, NULL
, "$Revision: 3494 $");
68 static void set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
);
69 static void remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
);
71 static void remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
72 rb_dlink_list
* list
, char c
, int mems
);
74 static char modebuf
[MODEBUFLEN
];
75 static char omodebuf
[MODEBUFLEN
];
76 static char parabuf
[MODEBUFLEN
];
77 static const char *para
[MAXMODEPARAMS
];
78 static char *mbuf
, *ombuf
;
84 * parv[2] = channel password (key)
87 m_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
89 user_join(client_p
, source_p
, parv
[1], parc
> 2 ? parv
[2] : NULL
); /* channel.c */
95 * me_svsjoin - small function to allow services to forcejoin clients, mainly for ns_ajoin
96 * parv[1] = user to act on (join to a channel)
98 * This does allow opers to "forcejoin" users to channels with operserv/raw or by writing a
99 * custom module (where they can make it not log anything), but the former bitches that it's
100 * being used and the latter...Can probably be done anyway with enough hackyness if this
101 * command didn't exist so it's not all that bad.
104 me_svsjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
106 struct Client
*target_p
;
108 if(!(source_p
->flags
& FLAGS_SERVICE
))
111 if((target_p
= find_person(parv
[1])) == NULL
)
114 if(!MyClient(target_p
))
117 user_join(&me
, target_p
, parv
[2], NULL
);
123 * parv[1] = channel TS
125 * parv[3] = "+", formerly channel modes but now unused
126 * alternatively, a single "0" parameter parts all channels
129 ms_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
131 struct Channel
*chptr
;
132 static struct Mode mode
;
136 int keep_our_modes
= YES
;
137 int keep_new_modes
= YES
;
138 rb_dlink_node
*ptr
, *next_ptr
;
140 /* special case for join 0 */
141 if((parv
[1][0] == '0') && (parv
[1][1] == '\0') && parc
== 2)
143 do_join_0(client_p
, source_p
);
150 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
153 /* joins for local channels cant happen. */
154 if(parv
[2][0] == '&')
159 mode
.key
[0] = mode
.forward
[0] = '\0';
160 mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
162 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
165 newts
= atol(parv
[1]);
166 oldts
= chptr
->channelts
;
168 #ifdef IGNORE_BOGUS_TS
169 if(newts
< 800000000)
171 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
172 "*** Bogus TS %ld on %s ignored from %s",
173 (long) newts
, chptr
->chname
, client_p
->name
);
174 newts
= (oldts
== 0) ? oldts
: 800000000;
177 /* making a channel TS0 */
178 if(!isnew
&& !newts
&& oldts
)
180 sendto_channel_local(ALL_MEMBERS
, chptr
,
181 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
182 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
183 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
184 "Server %s changing TS on %s from %ld to 0",
185 source_p
->name
, chptr
->chname
, (long) oldts
);
190 chptr
->channelts
= newts
;
191 else if(newts
== 0 || oldts
== 0)
192 chptr
->channelts
= 0;
193 else if(newts
== oldts
)
195 else if(newts
< oldts
)
198 chptr
->channelts
= newts
;
203 /* Lost the TS, other side wins, so remove modes on this side */
206 set_final_mode(&mode
, &chptr
->mode
);
208 remove_our_modes(chptr
, source_p
);
209 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
211 del_invite(chptr
, ptr
->data
);
213 /* If setting -j, clear join throttle state -- jilles */
214 chptr
->join_count
= chptr
->join_delta
= 0;
215 sendto_channel_local(ALL_MEMBERS
, chptr
,
216 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
217 me
.name
, chptr
->chname
, chptr
->chname
,
218 (long) oldts
, (long) newts
);
219 /* Update capitalization in channel name, this makes the
220 * capitalization timestamped like modes are -- jilles */
221 strcpy(chptr
->chname
, parv
[2]);
223 sendto_channel_local(ALL_MEMBERS
, chptr
,
225 source_p
->servptr
->name
,
226 chptr
->chname
, modebuf
, parabuf
);
227 if(*omodebuf
!= '\0')
228 sendto_channel_local(ONLY_OPERS
, chptr
,
230 source_p
->servptr
->name
,
231 chptr
->chname
, modebuf
, parabuf
);
232 *omodebuf
= *modebuf
= *parabuf
= '\0';
234 /* since we're dropping our modes, we want to clear the mlock as well. --nenolod */
235 set_channel_mlock(client_p
, source_p
, chptr
, NULL
, FALSE
);
238 if(!IsMember(source_p
, chptr
))
240 add_user_to_channel(chptr
, source_p
, CHFL_PEON
);
241 if (chptr
->mode
.join_num
&&
242 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
244 chptr
->join_count
= 0;
245 chptr
->join_delta
= rb_current_time();
248 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
249 source_p
->name
, source_p
->username
,
250 source_p
->host
, chptr
->chname
);
253 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
255 source_p
->id
, (long) chptr
->channelts
, chptr
->chname
);
260 ms_sjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
262 static char buf_uid
[BUFSIZE
];
263 static const char empty_modes
[] = "0";
264 struct Channel
*chptr
;
265 struct Client
*target_p
, *fakesource_p
;
268 static struct Mode mode
, *oldmode
;
271 int keep_our_modes
= 1;
272 int keep_new_modes
= 1;
283 int i
, joinc
= 0, timeslice
= 0;
284 static char empty
[] = "";
285 rb_dlink_node
*ptr
, *next_ptr
;
287 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
290 /* SJOIN's for local channels can't happen. */
294 omodebuf
[0] = modebuf
[0] = parabuf
[0] = mode
.key
[0] = mode
.forward
[0] = '\0';
295 pargs
= mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
297 /* Hide connecting server on netburst -- jilles */
298 if (ConfigServerHide
.flatten_links
&& !HasSentEob(source_p
))
301 fakesource_p
= source_p
;
305 newts
= atol(parv
[1]);
313 rb_strlcpy(mode
.forward
, parv
[4 + args
], sizeof(mode
.forward
));
319 sscanf(parv
[4 + args
], "%d:%d", &joinc
, ×lice
);
321 mode
.join_num
= joinc
;
322 mode
.join_time
= timeslice
;
327 rb_strlcpy(mode
.key
, parv
[4 + args
], sizeof(mode
.key
));
333 mode
.limit
= atoi(parv
[4 + args
]);
339 if(chmode_flags
[(int) *s
] != 0)
341 mode
.mode
|= chmode_flags
[(int) *s
];
350 /* remove any leading spaces */
357 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
358 return 0; /* channel name too long? */
361 oldts
= chptr
->channelts
;
362 oldmode
= &chptr
->mode
;
364 #ifdef IGNORE_BOGUS_TS
365 if(newts
< 800000000)
367 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
368 "*** Bogus TS %ld on %s ignored from %s",
369 (long) newts
, chptr
->chname
, client_p
->name
);
371 newts
= (oldts
== 0) ? oldts
: 800000000;
374 if(!isnew
&& !newts
&& oldts
)
376 sendto_channel_local(ALL_MEMBERS
, chptr
,
377 ":%s NOTICE %s :*** Notice -- TS for %s "
378 "changed from %ld to 0",
379 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
380 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
381 "Server %s changing TS on %s from %ld to 0",
382 source_p
->name
, chptr
->chname
, (long) oldts
);
387 chptr
->channelts
= newts
;
389 else if(newts
== 0 || oldts
== 0)
390 chptr
->channelts
= 0;
391 else if(newts
== oldts
)
393 else if(newts
< oldts
)
395 /* If configured, kick people trying to join +i/+k
396 * channels by recreating them on split servers.
397 * If the source has sent EOB, assume this is some
398 * sort of hack by services. If cmode +i is set,
399 * services can send kicks if needed; if the key
400 * differs, services cannot kick in a race-free
401 * manner so do so here.
403 if (ConfigChannel
.kick_on_split_riding
&&
404 ((!HasSentEob(source_p
) &&
405 mode
.mode
& MODE_INVITEONLY
) ||
406 (mode
.key
[0] != 0 && irccmp(mode
.key
, oldmode
->key
) != 0)))
408 struct membership
*msptr
;
410 int l
= rb_dlink_list_length(&chptr
->members
);
412 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
415 who
= msptr
->client_p
;
416 sendto_one(who
, ":%s KICK %s %s :Net Rider",
417 me
.name
, chptr
->chname
, who
->name
);
419 sendto_server(NULL
, chptr
, CAP_TS6
, NOCAPS
,
420 ":%s KICK %s %s :Net Rider",
421 me
.id
, chptr
->chname
,
423 remove_user_from_channel(msptr
);
429 /* Channel was emptied, create a new one */
430 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
431 return 0; /* oops! */
433 oldmode
= &chptr
->mode
;
437 chptr
->channelts
= newts
;
444 else if(keep_our_modes
)
446 mode
.mode
|= oldmode
->mode
;
447 if(oldmode
->limit
> mode
.limit
)
448 mode
.limit
= oldmode
->limit
;
449 if(strcmp(mode
.key
, oldmode
->key
) < 0)
450 strcpy(mode
.key
, oldmode
->key
);
451 if(oldmode
->join_num
> mode
.join_num
||
452 (oldmode
->join_num
== mode
.join_num
&&
453 oldmode
->join_time
> mode
.join_time
))
455 mode
.join_num
= oldmode
->join_num
;
456 mode
.join_time
= oldmode
->join_time
;
458 if(irccmp(mode
.forward
, oldmode
->forward
) < 0)
459 strcpy(mode
.forward
, oldmode
->forward
);
463 /* If setting -j, clear join throttle state -- jilles */
465 chptr
->join_count
= chptr
->join_delta
= 0;
468 set_final_mode(&mode
, oldmode
);
471 /* Lost the TS, other side wins, so remove modes on this side */
474 remove_our_modes(chptr
, fakesource_p
);
475 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
477 del_invite(chptr
, ptr
->data
);
480 if(rb_dlink_list_length(&chptr
->banlist
) > 0)
481 remove_ban_list(chptr
, fakesource_p
, &chptr
->banlist
, 'b', ALL_MEMBERS
);
482 if(rb_dlink_list_length(&chptr
->exceptlist
) > 0)
483 remove_ban_list(chptr
, fakesource_p
, &chptr
->exceptlist
,
485 if(rb_dlink_list_length(&chptr
->invexlist
) > 0)
486 remove_ban_list(chptr
, fakesource_p
, &chptr
->invexlist
,
488 if(rb_dlink_list_length(&chptr
->quietlist
) > 0)
489 remove_ban_list(chptr
, fakesource_p
, &chptr
->quietlist
,
493 sendto_channel_local(ALL_MEMBERS
, chptr
,
494 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
495 me
.name
, chptr
->chname
, chptr
->chname
,
496 (long) oldts
, (long) newts
);
497 /* Update capitalization in channel name, this makes the
498 * capitalization timestamped like modes are -- jilles */
499 strcpy(chptr
->chname
, parv
[2]);
501 /* since we're dropping our modes, we want to clear the mlock as well. --nenolod */
502 set_channel_mlock(client_p
, source_p
, chptr
, NULL
, FALSE
);
506 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s MODE %s %s %s",
507 fakesource_p
->name
, chptr
->chname
, modebuf
, parabuf
);
509 if(*omodebuf
!= '\0')
510 sendto_channel_local(ONLY_OPERS
, chptr
, ":%s MODE %s %s %s",
511 fakesource_p
->name
, chptr
->chname
, omodebuf
, parabuf
);
513 *omodebuf
= *modebuf
= *parabuf
= '\0';
515 if(parv
[3][0] != '0' && keep_new_modes
)
516 modes
= channel_modes(chptr
, source_p
);
520 mlen_uid
= rb_sprintf(buf_uid
, ":%s SJOIN %ld %s %s :",
521 use_id(source_p
), (long) chptr
->channelts
, parv
[2], modes
);
522 ptr_uid
= buf_uid
+ mlen_uid
;
526 para
[0] = para
[1] = para
[2] = para
[3] = empty
;
528 len_nick
= len_uid
= 0;
530 /* if theres a space, theres going to be more than one nick, change the
531 * first space to \0, so s is just the first nick, and point p to the
534 if((p
= strchr(s
, ' ')) != NULL
)
545 for (i
= 0; i
< 4; i
++)
569 /* if the client doesnt exist or is fake direction, skip. */
570 if(!(target_p
= find_client(s
)) ||
571 (target_p
->from
!= client_p
) || !IsPerson(target_p
))
574 /* we assume for these we can fit at least one nick/uid in.. */
576 /* check we can fit another status+nick+space into a buffer */
577 if((mlen_uid
+ len_uid
+ IDLEN
+ 3) > (BUFSIZE
- 3))
579 *(ptr_uid
- 1) = '\0';
580 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
581 ptr_uid
= buf_uid
+ mlen_uid
;
613 /* copy the nick to the two buffers */
614 len
= rb_sprintf(ptr_uid
, "%s ", use_id(target_p
));
621 if(!IsMember(target_p
, chptr
))
623 add_user_to_channel(chptr
, target_p
, fl
);
624 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
626 target_p
->username
, target_p
->host
, parv
[2]);
630 /* If anyone can think of a way to do this that doesn't make babies cry
631 * I would love to hear it - Taros */
636 para
[pargs
++] = target_p
->name
;
640 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
643 if(pargs
>= MAXMODEPARAMS
)
646 sendto_channel_local(ALL_MEMBERS
, chptr
,
647 ":%s MODE %s %s %s %s %s %s",
648 fakesource_p
->name
, chptr
->chname
,
650 para
[0], para
[1], para
[2], para
[3]);
653 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
658 para
[pargs
++] = target_p
->name
;
662 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
665 if(pargs
>= MAXMODEPARAMS
)
668 sendto_channel_local(ALL_MEMBERS
, chptr
,
669 ":%s MODE %s %s %s %s %s %s",
670 fakesource_p
->name
, chptr
->chname
,
672 para
[0], para
[1], para
[2], para
[3]);
675 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
680 para
[pargs
++] = target_p
->name
;
684 /* its possible the +a has filled up MAXMODEPARAMS, if so, start
687 if(pargs
>= MAXMODEPARAMS
)
690 sendto_channel_local(ALL_MEMBERS
, chptr
,
691 ":%s MODE %s %s %s %s %s %s",
692 fakesource_p
->name
, chptr
->chname
,
694 para
[0], para
[1], para
[2], para
[3]);
697 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
702 para
[pargs
++] = target_p
->name
;
705 else if(fl
& CHFL_CHANOP
)
708 para
[pargs
++] = target_p
->name
;
712 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
715 if(pargs
>= MAXMODEPARAMS
)
718 sendto_channel_local(ALL_MEMBERS
, chptr
,
719 ":%s MODE %s %s %s %s %s %s",
720 fakesource_p
->name
, chptr
->chname
,
722 para
[0], para
[1], para
[2], para
[3]);
725 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
730 para
[pargs
++] = target_p
->name
;
734 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
737 if(pargs
>= MAXMODEPARAMS
)
740 sendto_channel_local(ALL_MEMBERS
, chptr
,
741 ":%s MODE %s %s %s %s %s %s",
742 fakesource_p
->name
, chptr
->chname
,
744 para
[0], para
[1], para
[2], para
[3]);
747 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
752 para
[pargs
++] = target_p
->name
;
755 else if(fl
& CHFL_HALFOP
)
758 para
[pargs
++] = target_p
->name
;
762 /* its possible the +h has filled up MAXMODEPARAMS, if so, start
765 if(pargs
>= MAXMODEPARAMS
)
768 sendto_channel_local(ALL_MEMBERS
, chptr
,
769 ":%s MODE %s %s %s %s %s %s",
770 fakesource_p
->name
, chptr
->chname
,
772 para
[0], para
[1], para
[2], para
[3]);
775 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
780 para
[pargs
++] = target_p
->name
;
783 else if(fl
& CHFL_VOICE
)
786 para
[pargs
++] = target_p
->name
;
789 if(pargs
>= MAXMODEPARAMS
)
792 sendto_channel_local(ALL_MEMBERS
, chptr
,
793 ":%s MODE %s %s %s %s %s %s",
796 modebuf
, para
[0], para
[1], para
[2], para
[3]);
799 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
804 /* p points to the next nick */
807 /* if there was a trailing space and p was pointing to it, then we
808 * need to exit.. this has the side effect of breaking double spaces
809 * in an sjoin.. but that shouldnt happen anyway
811 if(s
&& (*s
== '\0'))
814 /* if p was NULL due to no spaces, s wont exist due to the above, so
815 * we cant check it for spaces.. if there are no spaces, then when
816 * we next get here, s will be NULL
818 if(s
&& ((p
= strchr(s
, ' ')) != NULL
))
827 sendto_channel_local(ALL_MEMBERS
, chptr
,
828 ":%s MODE %s %s %s %s %s %s",
829 fakesource_p
->name
, chptr
->chname
, modebuf
,
830 para
[0], CheckEmpty(para
[1]),
831 CheckEmpty(para
[2]), CheckEmpty(para
[3]));
834 if(!joins
&& !(chptr
->mode
.mode
& MODE_PERMANENT
) && isnew
)
836 destroy_channel(chptr
);
841 /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
844 *(ptr_uid
- 1) = '\0';
847 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
854 set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
)
856 int dir
= MODE_QUERY
, odir
= MODE_QUERY
;
857 char *pbuf
= parabuf
;
861 /* ok, first get a list of modes we need to add */
862 for (i
= 0; i
< 256; i
++)
864 if((mode
->mode
& chmode_flags
[i
]) && !(oldmode
->mode
& chmode_flags
[i
]))
866 if (chmode_table
[i
].set_func
== chm_hidden
)
888 /* now the ones we need to remove. */
889 for (i
= 0; i
< 256; i
++)
891 if((oldmode
->mode
& chmode_flags
[i
]) && !(mode
->mode
& chmode_flags
[i
]))
893 if(chmode_table
[i
].set_func
== chm_hidden
)
914 if(oldmode
->limit
&& !mode
->limit
)
923 if(oldmode
->key
[0] && !mode
->key
[0])
931 len
= rb_sprintf(pbuf
, "%s ", oldmode
->key
);
934 if(oldmode
->join_num
&& !mode
->join_num
)
943 if(oldmode
->forward
[0] && !mode
->forward
[0])
952 if(mode
->limit
&& oldmode
->limit
!= mode
->limit
)
960 len
= rb_sprintf(pbuf
, "%d ", mode
->limit
);
963 if(mode
->key
[0] && strcmp(oldmode
->key
, mode
->key
))
971 len
= rb_sprintf(pbuf
, "%s ", mode
->key
);
974 if(mode
->join_num
&& (oldmode
->join_num
!= mode
->join_num
|| oldmode
->join_time
!= mode
->join_time
))
982 len
= rb_sprintf(pbuf
, "%d:%d ", mode
->join_num
, mode
->join_time
);
985 if(mode
->forward
[0] && strcmp(oldmode
->forward
, mode
->forward
) && ConfigChannel
.use_forward
)
993 len
= rb_sprintf(pbuf
, "%s ", mode
->forward
);
1007 remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
)
1009 struct membership
*msptr
;
1011 char lmodebuf
[MODEBUFLEN
];
1012 char *lpara
[MAXMODEPARAMS
];
1019 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1022 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
1026 /* If anyone can think of a way to do this that doesn't make babies cry
1027 * I would love to hear it - Taros */
1031 msptr
->flags
&= ~CHFL_ADMIN
;
1032 lpara
[count
++] = msptr
->client_p
->name
;
1035 /* Make sure it fits if +h, +o, or +v are involved */
1036 if(is_chanop(msptr
))
1038 if(count
>= MAXMODEPARAMS
)
1041 sendto_channel_local(ALL_MEMBERS
, chptr
,
1042 ":%s MODE %s %s %s %s %s %s",
1043 source_p
->name
, chptr
->chname
,
1044 lmodebuf
, lpara
[0], lpara
[1],
1045 lpara
[2], lpara
[3]);
1047 /* preserve the initial '-' */
1052 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1056 msptr
->flags
&= ~CHFL_CHANOP
;
1057 lpara
[count
++] = msptr
->client_p
->name
;
1060 if(is_halfop(msptr
))
1062 if(count
>= MAXMODEPARAMS
)
1065 sendto_channel_local(ALL_MEMBERS
, chptr
,
1066 ":%s MODE %s %s %s %s %s %s",
1067 source_p
->name
, chptr
->chname
,
1068 lmodebuf
, lpara
[0], lpara
[1],
1069 lpara
[2], lpara
[3]);
1071 /* preserve the initial '-' */
1076 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1080 msptr
->flags
&= ~CHFL_HALFOP
;
1081 lpara
[count
++] = msptr
->client_p
->name
;
1084 if(is_voiced(msptr
))
1086 if(count
>= MAXMODEPARAMS
)
1089 sendto_channel_local(ALL_MEMBERS
, chptr
,
1090 ":%s MODE %s %s %s %s %s %s",
1091 source_p
->name
, chptr
->chname
,
1092 lmodebuf
, lpara
[0], lpara
[1],
1093 lpara
[2], lpara
[3]);
1095 /* preserve the initial '-' */
1100 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1104 msptr
->flags
&= ~CHFL_VOICE
;
1105 lpara
[count
++] = msptr
->client_p
->name
;
1109 else if(is_chanop(msptr
))
1111 msptr
->flags
&= ~CHFL_CHANOP
;
1112 lpara
[count
++] = msptr
->client_p
->name
;
1115 /* Make sure it fits if +h or +v are involved */
1116 if(is_halfop(msptr
))
1118 if(count
>= MAXMODEPARAMS
)
1121 sendto_channel_local(ALL_MEMBERS
, chptr
,
1122 ":%s MODE %s %s %s %s %s %s",
1123 source_p
->name
, chptr
->chname
,
1124 lmodebuf
, lpara
[0], lpara
[1],
1125 lpara
[2], lpara
[3]);
1127 /* preserve the initial '-' */
1132 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1136 msptr
->flags
&= ~CHFL_HALFOP
;
1137 lpara
[count
++] = msptr
->client_p
->name
;
1140 if(is_voiced(msptr
))
1142 if(count
>= MAXMODEPARAMS
)
1145 sendto_channel_local(ALL_MEMBERS
, chptr
,
1146 ":%s MODE %s %s %s %s %s %s",
1147 source_p
->name
, chptr
->chname
,
1148 lmodebuf
, lpara
[0], lpara
[1],
1149 lpara
[2], lpara
[3]);
1151 /* preserve the initial '-' */
1156 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1160 msptr
->flags
&= ~CHFL_VOICE
;
1161 lpara
[count
++] = msptr
->client_p
->name
;
1165 else if(is_halfop(msptr
))
1167 msptr
->flags
&= ~CHFL_HALFOP
;
1168 lpara
[count
++] = msptr
->client_p
->name
;
1171 /* +hv, might not fit so check. */
1172 if(is_voiced(msptr
))
1174 if(count
>= MAXMODEPARAMS
)
1177 sendto_channel_local(ALL_MEMBERS
, chptr
,
1178 ":%s MODE %s %s %s %s %s %s",
1179 source_p
->name
, chptr
->chname
,
1180 lmodebuf
, lpara
[0], lpara
[1],
1181 lpara
[2], lpara
[3]);
1183 /* preserve the initial '-' */
1188 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1192 msptr
->flags
&= ~CHFL_VOICE
;
1193 lpara
[count
++] = msptr
->client_p
->name
;
1197 else if(is_voiced(msptr
))
1199 msptr
->flags
&= ~CHFL_VOICE
;
1200 lpara
[count
++] = msptr
->client_p
->name
;
1206 if(count
>= MAXMODEPARAMS
)
1209 sendto_channel_local(ALL_MEMBERS
, chptr
,
1210 ":%s MODE %s %s %s %s %s %s",
1211 source_p
->name
, chptr
->chname
, lmodebuf
,
1212 lpara
[0], lpara
[1], lpara
[2], lpara
[3]);
1217 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1225 sendto_channel_local(ALL_MEMBERS
, chptr
,
1226 ":%s MODE %s %s %s %s %s %s",
1227 source_p
->name
, chptr
->chname
, lmodebuf
,
1228 EmptyString(lpara
[0]) ? "" : lpara
[0],
1229 EmptyString(lpara
[1]) ? "" : lpara
[1],
1230 EmptyString(lpara
[2]) ? "" : lpara
[2],
1231 EmptyString(lpara
[3]) ? "" : lpara
[3]);
1236 /* remove_ban_list()
1238 * inputs - channel, source, list to remove, char of mode, caps needed
1240 * side effects - given list is removed, with modes issued to local clients
1243 remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
1244 rb_dlink_list
* list
, char c
, int mems
)
1246 static char lmodebuf
[BUFSIZE
];
1247 static char lparabuf
[BUFSIZE
];
1250 rb_dlink_node
*next_ptr
;
1253 int cur_len
, mlen
, plen
;
1257 cur_len
= mlen
= rb_sprintf(lmodebuf
, ":%s MODE %s -", source_p
->name
, chptr
->chname
);
1258 mbuf
= lmodebuf
+ mlen
;
1260 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, list
->head
)
1264 /* trailing space, and the mode letter itself */
1265 plen
= strlen(banptr
->banstr
) + 2;
1267 if(count
>= MAXMODEPARAMS
|| (cur_len
+ plen
) > BUFSIZE
- 4)
1269 /* remove trailing space */
1273 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1276 mbuf
= lmodebuf
+ mlen
;
1283 pbuf
+= rb_sprintf(pbuf
, "%s ", banptr
->banstr
);
1291 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1293 list
->head
= list
->tail
= NULL
;