]> jfr.im git - irc/rqf/shadowircd.git/blob - src/channel.c
Backed out changeset 3097ade953f5
[irc/rqf/shadowircd.git] / src / channel.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * channel.c: Controls channels.
4 *
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
8 *
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.
13 *
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.
18 *
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
22 * USA
23 *
24 */
25
26 #include "stdinc.h"
27 #include "channel.h"
28 #include "chmode.h"
29 #include "client.h"
30 #include "common.h"
31 #include "hash.h"
32 #include "hook.h"
33 #include "match.h"
34 #include "ircd.h"
35 #include "numeric.h"
36 #include "s_serv.h" /* captab */
37 #include "s_user.h"
38 #include "send.h"
39 #include "whowas.h"
40 #include "s_conf.h" /* ConfigFileEntry, ConfigChannel */
41 #include "s_newconf.h"
42 #include "logger.h"
43 #include "packet.h"
44 #include "irc_dictionary.h"
45
46 struct config_channel_entry ConfigChannel;
47 rb_dlink_list global_channel_list;
48 static rb_bh *channel_heap;
49 static rb_bh *ban_heap;
50 static rb_bh *topic_heap;
51 static rb_bh *member_heap;
52
53 static int channel_capabs[] = { CAP_EX, CAP_IE,
54 CAP_SERVICE,
55 CAP_TS6
56 };
57
58 #define NCHCAPS (sizeof(channel_capabs)/sizeof(int))
59 #define NCHCAP_COMBOS (1 << NCHCAPS)
60
61 static struct ChCapCombo chcap_combos[NCHCAP_COMBOS];
62
63 static void free_topic(struct Channel *chptr);
64
65 static int h_can_join;
66 static int h_can_create_channel;
67 static int h_channel_join;
68
69 /* init_channels()
70 *
71 * input -
72 * output -
73 * side effects - initialises the various blockheaps
74 */
75 void
76 init_channels(void)
77 {
78 channel_heap = rb_bh_create(sizeof(struct Channel), CHANNEL_HEAP_SIZE, "channel_heap");
79 ban_heap = rb_bh_create(sizeof(struct Ban), BAN_HEAP_SIZE, "ban_heap");
80 topic_heap = rb_bh_create(TOPICLEN + 1 + USERHOST_REPLYLEN, TOPIC_HEAP_SIZE, "topic_heap");
81 member_heap = rb_bh_create(sizeof(struct membership), MEMBER_HEAP_SIZE, "member_heap");
82
83 h_can_join = register_hook("can_join");
84 h_channel_join = register_hook("channel_join");
85 h_can_create_channel = register_hook("can_create_channel");
86 }
87
88 /*
89 * allocate_channel - Allocates a channel
90 */
91 struct Channel *
92 allocate_channel(const char *chname)
93 {
94 struct Channel *chptr;
95 struct Dictionary *metadata;
96 chptr = rb_bh_alloc(channel_heap);
97 chptr->chname = rb_strdup(chname);
98
99 metadata = irc_dictionary_create(irccmp);
100 chptr->metadata = metadata;
101 return (chptr);
102 }
103
104 void
105 free_channel(struct Channel *chptr)
106 {
107 channel_metadata_clear(chptr);
108 rb_free(chptr->chname);
109 rb_bh_free(channel_heap, chptr);
110 }
111
112 struct Ban *
113 allocate_ban(const char *banstr, const char *who)
114 {
115 struct Ban *bptr;
116 bptr = rb_bh_alloc(ban_heap);
117 bptr->banstr = rb_strdup(banstr);
118 bptr->who = rb_strdup(who);
119
120 return (bptr);
121 }
122
123 void
124 free_ban(struct Ban *bptr)
125 {
126 rb_free(bptr->banstr);
127 rb_free(bptr->who);
128 rb_bh_free(ban_heap, bptr);
129 }
130
131
132 /* find_channel_membership()
133 *
134 * input - channel to find them in, client to find
135 * output - membership of client in channel, else NULL
136 * side effects -
137 */
138 struct membership *
139 find_channel_membership(struct Channel *chptr, struct Client *client_p)
140 {
141 struct membership *msptr;
142 rb_dlink_node *ptr;
143
144 if(!IsClient(client_p))
145 return NULL;
146
147 /* Pick the most efficient list to use to be nice to things like
148 * CHANSERV which could be in a large number of channels
149 */
150 if(rb_dlink_list_length(&chptr->members) < rb_dlink_list_length(&client_p->user->channel))
151 {
152 RB_DLINK_FOREACH(ptr, chptr->members.head)
153 {
154 msptr = ptr->data;
155
156 if(msptr->client_p == client_p)
157 return msptr;
158 }
159 }
160 else
161 {
162 RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
163 {
164 msptr = ptr->data;
165
166 if(msptr->chptr == chptr)
167 return msptr;
168 }
169 }
170
171 return NULL;
172 }
173
174 /* find_channel_status()
175 *
176 * input - membership to get status for, whether we can combine flags
177 * output - flags of user on channel
178 * side effects -
179 */
180 const char *
181 find_channel_status(struct membership *msptr, int combine)
182 {
183 static char buffer[5];
184 char *p;
185
186 p = buffer;
187
188 if(is_admin(msptr))
189 {
190 if(!combine)
191 return "!";
192 *p++ = '!';
193 }
194
195 if(is_chanop(msptr))
196 {
197 if(!combine)
198 return "@";
199 *p++ = '@';
200 }
201
202 if(is_halfop(msptr))
203 {
204 if(!combine)
205 return "%";
206 *p++ = '%';
207 }
208
209 if(is_voiced(msptr))
210 *p++ = '+';
211
212 *p = '\0';
213 return buffer;
214 }
215
216 /* is_halfop()
217 *
218 * input - membership to check for halfops
219 * output - 1 if the user is halfopped, 0 if the user is not or halfop
220 * is disabled.
221 * side effects -
222 *
223 */
224 int
225 is_halfop(struct membership *msptr)
226 {
227 if(!ConfigChannel.use_halfop)
228 return 0;
229 if(is_chmode_h(msptr))
230 return 1;
231 else
232 return 0;
233 }
234
235 /* is_admin()
236 *
237 * input - membership to check for admin
238 * output - 1 if the user is an admin, 0 if the user is not or admin
239 * is disabled.
240 * side effects -
241 *
242 */
243 int
244 is_admin(struct membership *msptr)
245 {
246 if(!ConfigChannel.use_admin)
247 return 0;
248 if(is_chmode_a(msptr))
249 return 1;
250 else
251 return 0;
252 }
253
254 /* is_any_op()
255 *
256 * input - membership to check for ops
257 * output - 1 if the user is op, halfop, or admin, 0 elsewise
258 * side effects -
259 */
260 int
261 is_any_op(struct membership *msptr)
262 {
263 if(is_chanop(msptr) || is_halfop(msptr) || is_admin(msptr))
264 return 1;
265 else
266 return 0;
267 }
268
269 /* is_chanop_voiced()
270 *
271 * input - memebership to check for status
272 * output - 1 if the user is op, halfop, admin, or voice, 0 elsewise
273 * side effects -
274 */
275 int
276 is_chanop_voiced(struct membership *msptr)
277 {
278 if(is_chanop(msptr) || is_voiced(msptr) || is_halfop(msptr) || is_admin(msptr))
279 return 1;
280 else
281 return 0;
282 }
283
284 /* can_kick_deop()
285 *
286 * input - two memeberships
287 * output - 1 if the first memebership can kick/deop the second, 0 elsewise
288 * side effects -
289 */
290 int
291 can_kick_deop(struct membership *source, struct membership *target)
292 {
293 if(is_chanop(source) && !is_admin(target))
294 return 1;
295 else if(is_halfop(source) && !is_any_op(target))
296 return 1;
297 else if(is_admin(source))
298 return 1;
299
300 return 0;
301 }
302
303 /* add_user_to_channel()
304 *
305 * input - channel to add client to, client to add, channel flags
306 * output -
307 * side effects - user is added to channel
308 */
309 void
310 add_user_to_channel(struct Channel *chptr, struct Client *client_p, int flags)
311 {
312 struct membership *msptr;
313
314 s_assert(client_p->user != NULL);
315 if(client_p->user == NULL)
316 return;
317
318 msptr = rb_bh_alloc(member_heap);
319
320 msptr->chptr = chptr;
321 msptr->client_p = client_p;
322 msptr->flags = flags;
323
324 rb_dlinkAdd(msptr, &msptr->usernode, &client_p->user->channel);
325 rb_dlinkAdd(msptr, &msptr->channode, &chptr->members);
326
327 if(MyClient(client_p))
328 rb_dlinkAdd(msptr, &msptr->locchannode, &chptr->locmembers);
329 }
330
331 /* remove_user_from_channel()
332 *
333 * input - membership pointer to remove from channel
334 * output -
335 * side effects - membership (thus user) is removed from channel
336 */
337 void
338 remove_user_from_channel(struct membership *msptr)
339 {
340 struct Client *client_p;
341 struct Channel *chptr;
342 s_assert(msptr != NULL);
343 if(msptr == NULL)
344 return;
345
346 client_p = msptr->client_p;
347 chptr = msptr->chptr;
348
349 rb_dlinkDelete(&msptr->usernode, &client_p->user->channel);
350 rb_dlinkDelete(&msptr->channode, &chptr->members);
351
352 if(client_p->servptr == &me)
353 rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
354
355 if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
356 destroy_channel(chptr);
357
358 rb_bh_free(member_heap, msptr);
359
360 return;
361 }
362
363 /* remove_user_from_channels()
364 *
365 * input - user to remove from all channels
366 * output -
367 * side effects - user is removed from all channels
368 */
369 void
370 remove_user_from_channels(struct Client *client_p)
371 {
372 struct Channel *chptr;
373 struct membership *msptr;
374 rb_dlink_node *ptr;
375 rb_dlink_node *next_ptr;
376
377 if(client_p == NULL)
378 return;
379
380 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->user->channel.head)
381 {
382 msptr = ptr->data;
383 chptr = msptr->chptr;
384
385 rb_dlinkDelete(&msptr->channode, &chptr->members);
386
387 if(client_p->servptr == &me)
388 rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
389
390 if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
391 destroy_channel(chptr);
392
393 rb_bh_free(member_heap, msptr);
394 }
395
396 client_p->user->channel.head = client_p->user->channel.tail = NULL;
397 client_p->user->channel.length = 0;
398 }
399
400 /* invalidate_bancache_user()
401 *
402 * input - user to invalidate ban cache for
403 * output -
404 * side effects - ban cache is invalidated for all memberships of that user
405 * to be used after a nick change
406 */
407 void
408 invalidate_bancache_user(struct Client *client_p)
409 {
410 struct membership *msptr;
411 rb_dlink_node *ptr;
412
413 if(client_p == NULL)
414 return;
415
416 RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
417 {
418 msptr = ptr->data;
419 msptr->bants = 0;
420 msptr->flags &= ~CHFL_BANNED;
421 }
422 }
423
424 /* check_channel_name()
425 *
426 * input - channel name
427 * output - 1 if valid channel name, else 0
428 * side effects -
429 */
430 int
431 check_channel_name(const char *name)
432 {
433 s_assert(name != NULL);
434 if(name == NULL)
435 return 0;
436
437 for (; *name; ++name)
438 {
439 if(!IsChanChar(*name))
440 return 0;
441 }
442
443 return 1;
444 }
445
446 /* free_channel_list()
447 *
448 * input - rb_dlink list to free
449 * output -
450 * side effects - list of b/e/I modes is cleared
451 */
452 void
453 free_channel_list(rb_dlink_list * list)
454 {
455 rb_dlink_node *ptr;
456 rb_dlink_node *next_ptr;
457 struct Ban *actualBan;
458
459 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
460 {
461 actualBan = ptr->data;
462 free_ban(actualBan);
463 }
464
465 list->head = list->tail = NULL;
466 list->length = 0;
467 }
468
469 /* destroy_channel()
470 *
471 * input - channel to destroy
472 * output -
473 * side effects - channel is obliterated
474 */
475 void
476 destroy_channel(struct Channel *chptr)
477 {
478 rb_dlink_node *ptr, *next_ptr;
479
480 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
481 {
482 del_invite(chptr, ptr->data);
483 }
484
485 /* free all bans/exceptions/denies */
486 free_channel_list(&chptr->banlist);
487 free_channel_list(&chptr->exceptlist);
488 free_channel_list(&chptr->invexlist);
489 free_channel_list(&chptr->quietlist);
490
491 /* Free the topic */
492 free_topic(chptr);
493
494 rb_dlinkDelete(&chptr->node, &global_channel_list);
495 del_from_channel_hash(chptr->chname, chptr);
496 free_channel(chptr);
497 }
498
499 /* channel_pub_or_secret()
500 *
501 * input - channel
502 * output - "=" if public, "@" if secret, else "*"
503 * side effects -
504 */
505 static const char *
506 channel_pub_or_secret(struct Channel *chptr)
507 {
508 if(PubChannel(chptr))
509 return ("=");
510 else if(SecretChannel(chptr))
511 return ("@");
512 return ("*");
513 }
514
515 /* channel_member_names()
516 *
517 * input - channel to list, client to list to, show endofnames
518 * output -
519 * side effects - client is given list of users on channel
520 */
521 void
522 channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eon)
523 {
524 struct membership *msptr;
525 struct Client *target_p;
526 rb_dlink_node *ptr;
527 char lbuf[BUFSIZE];
528 char *t;
529 int mlen;
530 int tlen;
531 int cur_len;
532 int is_member;
533 int stack = IsCapable(client_p, CLICAP_MULTI_PREFIX);
534
535 if(ShowChannel(client_p, chptr))
536 {
537 is_member = IsMember(client_p, chptr);
538
539 cur_len = mlen = rb_sprintf(lbuf, form_str(RPL_NAMREPLY),
540 me.name, client_p->name,
541 channel_pub_or_secret(chptr), chptr->chname);
542
543 t = lbuf + cur_len;
544
545 RB_DLINK_FOREACH(ptr, chptr->members.head)
546 {
547 msptr = ptr->data;
548 target_p = msptr->client_p;
549
550 if(IsInvisible(target_p) && !is_member)
551 continue;
552
553 /* space, possible "@+" prefix */
554 if(cur_len + strlen(target_p->name) + 3 >= BUFSIZE - 3)
555 {
556 *(t - 1) = '\0';
557 sendto_one(client_p, "%s", lbuf);
558 cur_len = mlen;
559 t = lbuf + mlen;
560 }
561
562 tlen = rb_sprintf(t, "%s%s ", find_channel_status(msptr, stack),
563 target_p->name);
564
565 cur_len += tlen;
566 t += tlen;
567 }
568
569 /* The old behaviour here was to always output our buffer,
570 * even if there are no clients we can show. This happens
571 * when a client does "NAMES" with no parameters, and all
572 * the clients on a -sp channel are +i. I dont see a good
573 * reason for keeping that behaviour, as it just wastes
574 * bandwidth. --anfl
575 */
576 if(cur_len != mlen)
577 {
578 *(t - 1) = '\0';
579 sendto_one(client_p, "%s", lbuf);
580 }
581 }
582
583 if(show_eon)
584 sendto_one(client_p, form_str(RPL_ENDOFNAMES),
585 me.name, client_p->name, chptr->chname);
586 }
587
588 /* del_invite()
589 *
590 * input - channel to remove invite from, client to remove
591 * output -
592 * side effects - user is removed from invite list, if exists
593 */
594 void
595 del_invite(struct Channel *chptr, struct Client *who)
596 {
597 rb_dlinkFindDestroy(who, &chptr->invites);
598 rb_dlinkFindDestroy(chptr, &who->user->invited);
599 }
600
601 /* is_banned()
602 *
603 * input - channel to check bans for, user to check bans against
604 * optional prebuilt buffers
605 * output - 1 if banned, else 0
606 * side effects -
607 */
608 int
609 is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr,
610 const char *s, const char *s2)
611 {
612 char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
613 char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
614 char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
615 char *s3 = NULL;
616 rb_dlink_node *ptr;
617 struct Ban *actualBan = NULL;
618 struct Ban *actualExcept = NULL;
619
620 if(!MyClient(who))
621 return 0;
622
623 /* if the buffers havent been built, do it here */
624 if(s == NULL)
625 {
626 rb_sprintf(src_host, "%s!%s@%s", who->name, who->username, who->host);
627 rb_sprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost);
628
629 s = src_host;
630 s2 = src_iphost;
631 }
632 if(who->localClient->mangledhost != NULL)
633 {
634 /* if host mangling mode enabled, also check their real host */
635 if(!strcmp(who->host, who->localClient->mangledhost))
636 {
637 rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost);
638 s3 = src_althost;
639 }
640 /* if host mangling mode not enabled and no other spoof,
641 * also check the mangled form of their host */
642 else if (!IsDynSpoof(who))
643 {
644 rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost);
645 s3 = src_althost;
646 }
647 }
648
649 RB_DLINK_FOREACH(ptr, chptr->banlist.head)
650 {
651 actualBan = ptr->data;
652 if(match(actualBan->banstr, s) ||
653 match(actualBan->banstr, s2) ||
654 match_cidr(actualBan->banstr, s2) ||
655 match_extban(actualBan->banstr, who, chptr, CHFL_BAN) ||
656 (s3 != NULL && match(actualBan->banstr, s3)))
657 break;
658 else
659 actualBan = NULL;
660 }
661
662 if((actualBan != NULL) && ConfigChannel.use_except)
663 {
664 RB_DLINK_FOREACH(ptr, chptr->exceptlist.head)
665 {
666 actualExcept = ptr->data;
667
668 /* theyre exempted.. */
669 if(match(actualExcept->banstr, s) ||
670 match(actualExcept->banstr, s2) ||
671 match_cidr(actualExcept->banstr, s2) ||
672 match_extban(actualExcept->banstr, who, chptr, CHFL_EXCEPTION) ||
673 (s3 != NULL && match(actualExcept->banstr, s3)))
674 {
675 /* cache the fact theyre not banned */
676 if(msptr != NULL)
677 {
678 msptr->bants = chptr->bants;
679 msptr->flags &= ~CHFL_BANNED;
680 }
681
682 return CHFL_EXCEPTION;
683 }
684 }
685 }
686
687 /* cache the banned/not banned status */
688 if(msptr != NULL)
689 {
690 msptr->bants = chptr->bants;
691
692 if(actualBan != NULL)
693 {
694 msptr->flags |= CHFL_BANNED;
695 return CHFL_BAN;
696 }
697 else
698 {
699 msptr->flags &= ~CHFL_BANNED;
700 return 0;
701 }
702 }
703
704 return ((actualBan ? CHFL_BAN : 0));
705 }
706
707 /* is_quieted()
708 *
709 * input - channel to check bans for, user to check bans against
710 * optional prebuilt buffers
711 * output - 1 if banned, else 0
712 * side effects -
713 */
714 int
715 is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr,
716 const char *s, const char *s2)
717 {
718 char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
719 char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
720 char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
721 char *s3 = NULL;
722 rb_dlink_node *ptr;
723 struct Ban *actualBan = NULL;
724 struct Ban *actualExcept = NULL;
725
726 if(!MyClient(who))
727 return 0;
728
729 /* if the buffers havent been built, do it here */
730 if(s == NULL)
731 {
732 rb_sprintf(src_host, "%s!%s@%s", who->name, who->username, who->host);
733 rb_sprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost);
734
735 s = src_host;
736 s2 = src_iphost;
737 }
738 if(who->localClient->mangledhost != NULL)
739 {
740 /* if host mangling mode enabled, also check their real host */
741 if(!strcmp(who->host, who->localClient->mangledhost))
742 {
743 rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost);
744 s3 = src_althost;
745 }
746 /* if host mangling mode not enabled and no other spoof,
747 * also check the mangled form of their host */
748 else if (!IsDynSpoof(who))
749 {
750 rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost);
751 s3 = src_althost;
752 }
753 }
754
755 RB_DLINK_FOREACH(ptr, chptr->quietlist.head)
756 {
757 actualBan = ptr->data;
758 if(match(actualBan->banstr, s) ||
759 match(actualBan->banstr, s2) ||
760 match_cidr(actualBan->banstr, s2) ||
761 match_extban(actualBan->banstr, who, chptr, CHFL_QUIET) ||
762 (s3 != NULL && match(actualBan->banstr, s3)))
763 break;
764 else
765 actualBan = NULL;
766 }
767
768 if((actualBan != NULL) && ConfigChannel.use_except)
769 {
770 RB_DLINK_FOREACH(ptr, chptr->exceptlist.head)
771 {
772 actualExcept = ptr->data;
773
774 /* theyre exempted.. */
775 if(match(actualExcept->banstr, s) ||
776 match(actualExcept->banstr, s2) ||
777 match_cidr(actualExcept->banstr, s2) ||
778 match_extban(actualExcept->banstr, who, chptr, CHFL_EXCEPTION) ||
779 (s3 != NULL && match(actualExcept->banstr, s3)))
780 {
781 /* cache the fact theyre not banned */
782 if(msptr != NULL)
783 {
784 msptr->bants = chptr->bants;
785 msptr->flags &= ~CHFL_BANNED;
786 }
787
788 return CHFL_EXCEPTION;
789 }
790 }
791 }
792
793 /* cache the banned/not banned status */
794 if(msptr != NULL)
795 {
796 msptr->bants = chptr->bants;
797
798 if(actualBan != NULL)
799 {
800 msptr->flags |= CHFL_BANNED;
801 return CHFL_BAN;
802 }
803 else
804 {
805 msptr->flags &= ~CHFL_BANNED;
806 return 0;
807 }
808 }
809
810 return ((actualBan ? CHFL_BAN : 0));
811 }
812
813 /* can_join()
814 *
815 * input - client to check, channel to check for, key
816 * output - reason for not being able to join, else 0
817 * side effects -
818 */
819 int
820 can_join(struct Client *source_p, struct Channel *chptr, char *key)
821 {
822 rb_dlink_node *invite = NULL;
823 rb_dlink_node *ptr;
824 struct Ban *invex = NULL;
825 char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
826 char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
827 char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
828 char text[10];
829 int use_althost = 0;
830 int i = 0;
831 hook_data_channel moduledata;
832 struct Metadata *md;
833 struct DictionaryIter iter;
834
835 s_assert(source_p->localClient != NULL);
836
837 rb_sprintf(src_host, "%s!%s@%s", source_p->name, source_p->username, source_p->host);
838 rb_sprintf(src_iphost, "%s!%s@%s", source_p->name, source_p->username, source_p->sockhost);
839 if(source_p->localClient->mangledhost != NULL)
840 {
841 /* if host mangling mode enabled, also check their real host */
842 if(!strcmp(source_p->host, source_p->localClient->mangledhost))
843 {
844 rb_sprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->orighost);
845 use_althost = 1;
846 }
847 /* if host mangling mode not enabled and no other spoof,
848 * also check the mangled form of their host */
849 else if (!IsDynSpoof(source_p))
850 {
851 rb_sprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->localClient->mangledhost);
852 use_althost = 1;
853 }
854 }
855
856 if((is_banned(chptr, source_p, NULL, src_host, src_iphost)) == CHFL_BAN)
857 return (ERR_BANNEDFROMCHAN);
858
859 rb_snprintf(text, sizeof(text), "K%s", source_p->id);
860
861 DICTIONARY_FOREACH(md, &iter, chptr->metadata)
862 {
863 if(!strcmp(md->value, "KICKNOREJOIN") && !strcmp(md->name, text) && (md->timevalue + 2 > rb_current_time()))
864 return ERR_KICKNOREJOIN;
865 /* cleanup any stale KICKNOREJOIN metadata we find while we're at it */
866 if(!strcmp(md->value, "KICKNOREJOIN") && !(md->timevalue + 2 > rb_current_time()))
867 channel_metadata_delete(chptr, md->name, 0);
868 }
869
870 if(chptr->mode.mode & MODE_INVITEONLY)
871 {
872 RB_DLINK_FOREACH(invite, source_p->user->invited.head)
873 {
874 if(invite->data == chptr)
875 break;
876 }
877 if(invite == NULL)
878 {
879 if(!ConfigChannel.use_invex)
880 return (ERR_INVITEONLYCHAN);
881 RB_DLINK_FOREACH(ptr, chptr->invexlist.head)
882 {
883 invex = ptr->data;
884 if(match(invex->banstr, src_host)
885 || match(invex->banstr, src_iphost)
886 || match_cidr(invex->banstr, src_iphost)
887 || match_extban(invex->banstr, source_p, chptr, CHFL_INVEX)
888 || (use_althost && match(invex->banstr, src_althost)))
889 break;
890 }
891 if(ptr == NULL)
892 return (ERR_INVITEONLYCHAN);
893 }
894 }
895
896 if(*chptr->mode.key && (EmptyString(key) || irccmp(chptr->mode.key, key)))
897 return (ERR_BADCHANNELKEY);
898
899 if(chptr->mode.limit &&
900 rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit)
901 i = ERR_CHANNELISFULL;
902 if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser))
903 i = ERR_NEEDREGGEDNICK;
904 /* join throttling stuff --nenolod */
905 else if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
906 {
907 if ((rb_current_time() - chptr->join_delta <=
908 chptr->mode.join_time) && (chptr->join_count >=
909 chptr->mode.join_num))
910 i = ERR_THROTTLE;
911 }
912
913 /* allow /invite to override +l/+r/+j also -- jilles */
914 if (i != 0 && invite == NULL)
915 {
916 RB_DLINK_FOREACH(invite, source_p->user->invited.head)
917 {
918 if(invite->data == chptr)
919 break;
920 }
921 if (invite == NULL)
922 return i;
923 }
924
925 moduledata.client = source_p;
926 moduledata.chptr = chptr;
927 moduledata.approved = 0;
928
929 call_hook(h_can_join, &moduledata);
930
931 return moduledata.approved;
932 }
933
934 /* can_send()
935 *
936 * input - user to check in channel, membership pointer
937 * output - whether can explicitly send or not, else CAN_SEND_NONOP
938 * side effects -
939 */
940 int
941 can_send(struct Channel *chptr, struct Client *source_p, struct membership *msptr)
942 {
943 if(IsServer(source_p) || IsService(source_p))
944 return CAN_SEND_OPV;
945
946 if(MyClient(source_p) && hash_find_resv(chptr->chname) &&
947 !IsOper(source_p) && !IsExemptResv(source_p))
948 return CAN_SEND_NO;
949
950 if(msptr == NULL)
951 {
952 msptr = find_channel_membership(chptr, source_p);
953
954 if(msptr == NULL)
955 {
956 /* if its +m or +n and theyre not in the channel,
957 * they cant send. we dont check bans here because
958 * theres no possibility of caching them --fl
959 */
960 if(chptr->mode.mode & MODE_NOPRIVMSGS || chptr->mode.mode & MODE_MODERATED)
961 return CAN_SEND_NO;
962 else
963 return CAN_SEND_NONOP;
964 }
965 }
966
967 if(is_chanop_voiced(msptr))
968 return CAN_SEND_OPV;
969
970 if(chptr->mode.mode & MODE_MODERATED)
971 return CAN_SEND_NO;
972
973 if(MyClient(source_p))
974 {
975 /* cached can_send */
976 if(msptr->bants == chptr->bants)
977 {
978 if(can_send_banned(msptr))
979 return CAN_SEND_NO;
980 }
981 else if(is_banned(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN
982 || is_quieted(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN)
983 return CAN_SEND_NO;
984 }
985
986 return CAN_SEND_NONOP;
987 }
988
989 /* find_bannickchange_channel()
990 * Input: client to check
991 * Output: channel preventing nick change
992 */
993 struct Channel *
994 find_bannickchange_channel(struct Client *client_p)
995 {
996 struct Channel *chptr;
997 struct membership *msptr;
998 rb_dlink_node *ptr;
999 char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
1000 char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
1001
1002 if (!MyClient(client_p) || IsOverride(client_p))
1003 return NULL;
1004
1005 rb_sprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host);
1006 rb_sprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost);
1007
1008 RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
1009 {
1010 msptr = ptr->data;
1011 chptr = msptr->chptr;
1012 if (is_chanop_voiced(msptr))
1013 continue;
1014 /* cached can_send */
1015 if (msptr->bants == chptr->bants)
1016 {
1017 if (can_send_banned(msptr))
1018 return chptr;
1019 }
1020 else if (is_banned(chptr, client_p, msptr, src_host, src_iphost) == CHFL_BAN
1021 || is_quieted(chptr, client_p, msptr, src_host, src_iphost) == CHFL_BAN)
1022 return chptr;
1023 }
1024 return NULL;
1025 }
1026
1027 /* find_nonickchange_channel()
1028 * Input: client to check
1029 * Output: channel preventing nick change
1030 */
1031 struct Channel *
1032 find_nonickchange_channel(struct Client *client_p)
1033 {
1034 struct Channel *chptr;
1035 struct membership *msptr;
1036 rb_dlink_node *ptr;
1037
1038 if (!MyClient(client_p))
1039 return NULL;
1040
1041 RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
1042 {
1043 msptr = ptr->data;
1044 chptr = msptr->chptr;
1045 if (chptr->mode.mode & MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
1046 return chptr;
1047 }
1048 return NULL;
1049 }
1050
1051 /* void check_spambot_warning(struct Client *source_p)
1052 * Input: Client to check, channel name or NULL if this is a part.
1053 * Output: none
1054 * Side-effects: Updates the client's oper_warn_count_down, warns the
1055 * IRC operators if necessary, and updates join_leave_countdown as
1056 * needed.
1057 */
1058 void
1059 check_spambot_warning(struct Client *source_p, const char *name)
1060 {
1061 int t_delta;
1062 int decrement_count;
1063 if((GlobalSetOptions.spam_num &&
1064 (source_p->localClient->join_leave_count >= GlobalSetOptions.spam_num)))
1065 {
1066 if(source_p->localClient->oper_warn_count_down > 0)
1067 source_p->localClient->oper_warn_count_down--;
1068 else
1069 source_p->localClient->oper_warn_count_down = 0;
1070 if(source_p->localClient->oper_warn_count_down == 0 &&
1071 name != NULL)
1072 {
1073 /* Its already known as a possible spambot */
1074 sendto_realops_snomask(SNO_BOTS, L_NETWIDE,
1075 "User %s (%s@%s) trying to join %s is a possible spambot",
1076 source_p->name,
1077 source_p->username, source_p->orighost, name);
1078 source_p->localClient->oper_warn_count_down = OPER_SPAM_COUNTDOWN;
1079 }
1080 }
1081 else
1082 {
1083 if((t_delta =
1084 (rb_current_time() - source_p->localClient->last_leave_time)) >
1085 JOIN_LEAVE_COUNT_EXPIRE_TIME)
1086 {
1087 decrement_count = (t_delta / JOIN_LEAVE_COUNT_EXPIRE_TIME);
1088 if(name != NULL)
1089 ;
1090 else if(decrement_count > source_p->localClient->join_leave_count)
1091 source_p->localClient->join_leave_count = 0;
1092 else
1093 source_p->localClient->join_leave_count -= decrement_count;
1094 }
1095 else
1096 {
1097 if((rb_current_time() -
1098 (source_p->localClient->last_join_time)) < GlobalSetOptions.spam_time)
1099 {
1100 /* oh, its a possible spambot */
1101 source_p->localClient->join_leave_count++;
1102 }
1103 }
1104 if(name != NULL)
1105 source_p->localClient->last_join_time = rb_current_time();
1106 else
1107 source_p->localClient->last_leave_time = rb_current_time();
1108 }
1109 }
1110
1111 /* check_splitmode()
1112 *
1113 * input -
1114 * output -
1115 * side effects - compares usercount and servercount against their split
1116 * values and adjusts splitmode accordingly
1117 */
1118 void
1119 check_splitmode(void *unused)
1120 {
1121 if(splitchecking && (ConfigChannel.no_join_on_split || ConfigChannel.no_create_on_split))
1122 {
1123 /* not split, we're being asked to check now because someone
1124 * has left
1125 */
1126 if(!splitmode)
1127 {
1128 if(eob_count < split_servers || Count.total < split_users)
1129 {
1130 splitmode = 1;
1131 sendto_realops_snomask(SNO_GENERAL, L_ALL,
1132 "Network split, activating splitmode");
1133 check_splitmode_ev = rb_event_addish("check_splitmode", check_splitmode, NULL, 2);
1134 }
1135 }
1136 /* in splitmode, check whether its finished */
1137 else if(eob_count >= split_servers && Count.total >= split_users)
1138 {
1139 splitmode = 0;
1140
1141 sendto_realops_snomask(SNO_GENERAL, L_ALL,
1142 "Network rejoined, deactivating splitmode");
1143
1144 rb_event_delete(check_splitmode_ev);
1145 check_splitmode_ev = NULL;
1146 }
1147 }
1148 }
1149
1150
1151 /* allocate_topic()
1152 *
1153 * input - channel to allocate topic for
1154 * output - 1 on success, else 0
1155 * side effects - channel gets a topic allocated
1156 */
1157 static void
1158 allocate_topic(struct Channel *chptr)
1159 {
1160 void *ptr;
1161
1162 if(chptr == NULL)
1163 return;
1164
1165 ptr = rb_bh_alloc(topic_heap);
1166
1167 /* Basically we allocate one large block for the topic and
1168 * the topic info. We then split it up into two and shove it
1169 * in the chptr
1170 */
1171 chptr->topic = ptr;
1172 chptr->topic_info = (char *) ptr + TOPICLEN + 1;
1173 *chptr->topic = '\0';
1174 *chptr->topic_info = '\0';
1175 }
1176
1177 /* free_topic()
1178 *
1179 * input - channel which has topic to free
1180 * output -
1181 * side effects - channels topic is free'd
1182 */
1183 static void
1184 free_topic(struct Channel *chptr)
1185 {
1186 void *ptr;
1187
1188 if(chptr == NULL || chptr->topic == NULL)
1189 return;
1190
1191 /* This is safe for now - If you change allocate_topic you
1192 * MUST change this as well
1193 */
1194 ptr = chptr->topic;
1195 rb_bh_free(topic_heap, ptr);
1196 chptr->topic = NULL;
1197 chptr->topic_info = NULL;
1198 }
1199
1200 /* set_channel_topic()
1201 *
1202 * input - channel, topic to set, topic info and topic ts
1203 * output -
1204 * side effects - channels topic, topic info and TS are set.
1205 */
1206 void
1207 set_channel_topic(struct Channel *chptr, const char *topic, const char *topic_info, time_t topicts)
1208 {
1209 if(strlen(topic) > 0)
1210 {
1211 if(chptr->topic == NULL)
1212 allocate_topic(chptr);
1213 rb_strlcpy(chptr->topic, topic, TOPICLEN + 1);
1214 rb_strlcpy(chptr->topic_info, topic_info, USERHOST_REPLYLEN);
1215 chptr->topic_time = topicts;
1216 }
1217 else
1218 {
1219 if(chptr->topic != NULL)
1220 free_topic(chptr);
1221 chptr->topic_time = 0;
1222 }
1223 }
1224
1225 /* has_common_channel()
1226 *
1227 * input - pointer to client
1228 * - pointer to another client
1229 * output - 1 if the two have a channel in common, 0 elsewise
1230 * side effects - none
1231 */
1232 int
1233 has_common_channel(struct Client *client1, struct Client *client2)
1234 {
1235 rb_dlink_node *ptr;
1236
1237 RB_DLINK_FOREACH(ptr, client1->user->channel.head)
1238 {
1239 if(IsMember(client2, ((struct membership *)ptr->data)->chptr))
1240 return 1;
1241 }
1242 return 0;
1243 }
1244
1245 /* channel_modes()
1246 *
1247 * inputs - pointer to channel
1248 * - pointer to client
1249 * output - string with simple modes
1250 * side effects - result from previous calls overwritten
1251 *
1252 * Stolen from ShadowIRCd 4 --nenolod
1253 */
1254 const char *
1255 channel_modes(struct Channel *chptr, struct Client *client_p)
1256 {
1257 int i;
1258 char buf1[BUFSIZE];
1259 char buf2[BUFSIZE];
1260 static char final[BUFSIZE];
1261 char *mbuf = buf1;
1262 char *pbuf = buf2;
1263
1264 *mbuf++ = '+';
1265 *pbuf = '\0';
1266
1267 for (i = 0; i < 256; i++)
1268 {
1269 if(chmode_table[i].set_func == chm_hidden && !IsOper(client_p) && IsClient(client_p))
1270 continue;
1271 if(chptr->mode.mode & chmode_flags[i])
1272 *mbuf++ = i;
1273 }
1274
1275 if(chptr->mode.limit)
1276 {
1277 *mbuf++ = 'l';
1278
1279 if(!IsClient(client_p) || IsMember(client_p, chptr))
1280 pbuf += rb_sprintf(pbuf, " %d", chptr->mode.limit);
1281 }
1282
1283 if(*chptr->mode.key)
1284 {
1285 *mbuf++ = 'k';
1286
1287 if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
1288 pbuf += rb_sprintf(pbuf, " %s", chptr->mode.key);
1289 }
1290
1291 if(chptr->mode.join_num)
1292 {
1293 *mbuf++ = 'j';
1294
1295 if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
1296 pbuf += rb_sprintf(pbuf, " %d:%d", chptr->mode.join_num,
1297 chptr->mode.join_time);
1298 }
1299
1300 if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p)))
1301 {
1302 *mbuf++ = 'f';
1303
1304 if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
1305 pbuf += rb_sprintf(pbuf, " %s", chptr->mode.forward);
1306 }
1307
1308 *mbuf = '\0';
1309
1310 rb_strlcpy(final, buf1, sizeof final);
1311 rb_strlcat(final, buf2, sizeof final);
1312 return final;
1313 }
1314
1315 /* Now lets do some stuff to keep track of what combinations of
1316 * servers exist...
1317 * Note that the number of combinations doubles each time you add
1318 * something to this list. Each one is only quick if no servers use that
1319 * combination, but if the numbers get too high here MODE will get too
1320 * slow. I suggest if you get more than 7 here, you consider getting rid
1321 * of some and merging or something. If it wasn't for irc+cs we would
1322 * probably not even need to bother about most of these, but unfortunately
1323 * we do. -A1kmm
1324 */
1325
1326 /* void init_chcap_usage_counts(void)
1327 *
1328 * Inputs - none
1329 * Output - none
1330 * Side-effects - Initialises the usage counts to zero. Fills in the
1331 * chcap_yes and chcap_no combination tables.
1332 */
1333 void
1334 init_chcap_usage_counts(void)
1335 {
1336 unsigned long m, c, y, n;
1337
1338 memset(chcap_combos, 0, sizeof(chcap_combos));
1339
1340 /* For every possible combination */
1341 for (m = 0; m < NCHCAP_COMBOS; m++)
1342 {
1343 /* Check each capab */
1344 for (c = y = n = 0; c < NCHCAPS; c++)
1345 {
1346 if((m & (1 << c)) == 0)
1347 n |= channel_capabs[c];
1348 else
1349 y |= channel_capabs[c];
1350 }
1351 chcap_combos[m].cap_yes = y;
1352 chcap_combos[m].cap_no = n;
1353 }
1354 }
1355
1356 /* void set_chcap_usage_counts(struct Client *serv_p)
1357 * Input: serv_p; The client whose capabs to register.
1358 * Output: none
1359 * Side-effects: Increments the usage counts for the correct capab
1360 * combination.
1361 */
1362 void
1363 set_chcap_usage_counts(struct Client *serv_p)
1364 {
1365 int n;
1366
1367 for (n = 0; n < NCHCAP_COMBOS; n++)
1368 {
1369 if(IsCapable(serv_p, chcap_combos[n].cap_yes) &&
1370 NotCapable(serv_p, chcap_combos[n].cap_no))
1371 {
1372 chcap_combos[n].count++;
1373 return;
1374 }
1375 }
1376
1377 /* This should be impossible -A1kmm. */
1378 s_assert(0);
1379 }
1380
1381 /* void set_chcap_usage_counts(struct Client *serv_p)
1382 *
1383 * Inputs - serv_p; The client whose capabs to register.
1384 * Output - none
1385 * Side-effects - Decrements the usage counts for the correct capab
1386 * combination.
1387 */
1388 void
1389 unset_chcap_usage_counts(struct Client *serv_p)
1390 {
1391 int n;
1392
1393 for (n = 0; n < NCHCAP_COMBOS; n++)
1394 {
1395 if(IsCapable(serv_p, chcap_combos[n].cap_yes) &&
1396 NotCapable(serv_p, chcap_combos[n].cap_no))
1397 {
1398 /* Hopefully capabs can't change dynamically or anything... */
1399 s_assert(chcap_combos[n].count > 0);
1400
1401 if(chcap_combos[n].count > 0)
1402 chcap_combos[n].count--;
1403 return;
1404 }
1405 }
1406
1407 /* This should be impossible -A1kmm. */
1408 s_assert(0);
1409 }
1410
1411 /* void send_cap_mode_changes(struct Client *client_p,
1412 * struct Client *source_p,
1413 * struct Channel *chptr, int cap, int nocap)
1414 * Input: The client sending(client_p), the source client(source_p),
1415 * the channel to send mode changes for(chptr)
1416 * Output: None.
1417 * Side-effects: Sends the appropriate mode changes to capable servers.
1418 *
1419 * Reverted back to my original design, except that we now keep a count
1420 * of the number of servers which each combination as an optimisation, so
1421 * the capabs combinations which are not needed are not worked out. -A1kmm
1422 */
1423 void
1424 send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
1425 struct Channel *chptr, struct ChModeChange mode_changes[], int mode_count)
1426 {
1427 static char modebuf[BUFSIZE];
1428 static char parabuf[BUFSIZE];
1429 int i, mbl, pbl, nc, mc, preflen, len;
1430 char *pbuf;
1431 const char *arg;
1432 int dir;
1433 int j;
1434 int cap;
1435 int nocap;
1436 int arglen;
1437
1438 /* Now send to servers... */
1439 for (j = 0; j < NCHCAP_COMBOS; j++)
1440 {
1441 if(chcap_combos[j].count == 0)
1442 continue;
1443
1444 mc = 0;
1445 nc = 0;
1446 pbl = 0;
1447 parabuf[0] = 0;
1448 pbuf = parabuf;
1449 dir = MODE_QUERY;
1450
1451 cap = chcap_combos[j].cap_yes;
1452 nocap = chcap_combos[j].cap_no;
1453
1454 mbl = preflen = rb_sprintf(modebuf, ":%s TMODE %ld %s ",
1455 use_id(source_p), (long) chptr->channelts,
1456 chptr->chname);
1457
1458 /* loop the list of - modes we have */
1459 for (i = 0; i < mode_count; i++)
1460 {
1461 /* if they dont support the cap we need, or they do support a cap they
1462 * cant have, then dont add it to the modebuf.. that way they wont see
1463 * the mode
1464 */
1465 if((mode_changes[i].letter == 0) ||
1466 ((cap & mode_changes[i].caps) != mode_changes[i].caps)
1467 || ((nocap & mode_changes[i].nocaps) != mode_changes[i].nocaps))
1468 continue;
1469
1470 if(!EmptyString(mode_changes[i].id))
1471 arg = mode_changes[i].id;
1472 else
1473 arg = mode_changes[i].arg;
1474
1475 if(arg)
1476 {
1477 arglen = strlen(arg);
1478
1479 /* dont even think about it! --fl */
1480 if(arglen > MODEBUFLEN - 5)
1481 continue;
1482 }
1483
1484 /* if we're creeping past the buf size, we need to send it and make
1485 * another line for the other modes
1486 * XXX - this could give away server topology with uids being
1487 * different lengths, but not much we can do, except possibly break
1488 * them as if they were the longest of the nick or uid at all times,
1489 * which even then won't work as we don't always know the uid -A1kmm.
1490 */
1491 if(arg && ((mc == MAXMODEPARAMSSERV) ||
1492 ((mbl + pbl + arglen + 4) > (BUFSIZE - 3))))
1493 {
1494 if(nc != 0)
1495 sendto_server(client_p, chptr, cap, nocap,
1496 "%s %s", modebuf, parabuf);
1497 nc = 0;
1498 mc = 0;
1499
1500 mbl = preflen;
1501 pbl = 0;
1502 pbuf = parabuf;
1503 parabuf[0] = 0;
1504 dir = MODE_QUERY;
1505 }
1506
1507 if(dir != mode_changes[i].dir)
1508 {
1509 modebuf[mbl++] = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
1510 dir = mode_changes[i].dir;
1511 }
1512
1513 modebuf[mbl++] = mode_changes[i].letter;
1514 modebuf[mbl] = 0;
1515 nc++;
1516
1517 if(arg != NULL)
1518 {
1519 len = rb_sprintf(pbuf, "%s ", arg);
1520 pbuf += len;
1521 pbl += len;
1522 mc++;
1523 }
1524 }
1525
1526 if(pbl && parabuf[pbl - 1] == ' ')
1527 parabuf[pbl - 1] = 0;
1528
1529 if(nc != 0)
1530 sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf);
1531 }
1532 }
1533
1534 void
1535 resv_chan_forcepart(const char *name, const char *reason, int temp_time)
1536 {
1537 rb_dlink_node *ptr;
1538 rb_dlink_node *next_ptr;
1539 struct Channel *chptr;
1540 struct membership *msptr;
1541 struct Client *target_p;
1542
1543 if(!ConfigChannel.resv_forcepart)
1544 return;
1545
1546 /* for each user on our server in the channel list
1547 * send them a PART, and notify opers.
1548 */
1549 chptr = find_channel(name);
1550 if(chptr != NULL)
1551 {
1552 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
1553 {
1554 msptr = ptr->data;
1555 target_p = msptr->client_p;
1556
1557 if(IsExemptResv(target_p))
1558 continue;
1559
1560 sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
1561 ":%s PART %s", target_p->id, chptr->chname);
1562
1563 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
1564 target_p->name, target_p->username,
1565 target_p->host, chptr->chname, target_p->name);
1566
1567 remove_user_from_channel(msptr);
1568
1569 /* notify opers & user they were removed from the channel */
1570 sendto_realops_snomask(SNO_GENERAL, L_ALL,
1571 "Forced PART for %s!%s@%s from %s (%s)",
1572 target_p->name, target_p->username,
1573 target_p->host, name, reason);
1574
1575 if(temp_time > 0)
1576 sendto_one_notice(target_p, ":*** Channel %s is temporarily unavailable on this server.",
1577 name);
1578 else
1579 sendto_one_notice(target_p, ":*** Channel %s is no longer available on this server.",
1580 name);
1581 }
1582 }
1583 }
1584
1585 /* Check what we will forward to, without sending any notices to the user
1586 * -- jilles
1587 */
1588 struct Channel *
1589 check_forward(struct Client *source_p, struct Channel *chptr,
1590 char *key)
1591 {
1592 int depth = 0, i;
1593
1594 /* User is +Q */
1595 if (IsNoForward(source_p))
1596 return NULL;
1597
1598 while (depth < 16)
1599 {
1600 chptr = find_channel(chptr->mode.forward);
1601 /* Can only forward to existing channels */
1602 if (chptr == NULL)
1603 return NULL;
1604 /* Already on there, show original error message */
1605 if (IsMember(source_p, chptr))
1606 return NULL;
1607 /* Juped. Sending a warning notice would be unfair */
1608 if (hash_find_resv(chptr->chname))
1609 return NULL;
1610 /* Don't forward to +Q channel */
1611 if (chptr->mode.mode & MODE_DISFORWARD)
1612 return NULL;
1613 i = can_join(source_p, chptr, key);
1614 if (i == 0)
1615 return chptr;
1616 if (i != ERR_INVITEONLYCHAN && i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_CHANNELISFULL)
1617 return NULL;
1618 depth++;
1619 }
1620
1621 return NULL;
1622 }
1623
1624 /*
1625 * do_join_0
1626 *
1627 * inputs - pointer to client doing join 0
1628 * output - NONE
1629 * side effects - Use has decided to join 0. This is legacy
1630 * from the days when channels were numbers not names. *sigh*
1631 */
1632 void
1633 do_join_0(struct Client *client_p, struct Client *source_p)
1634 {
1635 struct membership *msptr;
1636 struct Channel *chptr = NULL;
1637 rb_dlink_node *ptr;
1638
1639 /* Finish the flood grace period... */
1640 if(MyClient(source_p) && !IsFloodDone(source_p))
1641 flood_endgrace(source_p);
1642
1643 sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s JOIN 0", use_id(source_p));
1644
1645 while((ptr = source_p->user->channel.head))
1646 {
1647 if(source_p->user->channel.head && MyConnect(source_p) &&
1648 !IsOper(source_p) && !IsExemptSpambot(source_p))
1649 check_spambot_warning(source_p, NULL);
1650
1651 msptr = ptr->data;
1652 chptr = msptr->chptr;
1653 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
1654 source_p->name,
1655 source_p->username, source_p->host, chptr->chname);
1656 remove_user_from_channel(msptr);
1657 }
1658 }
1659
1660 int
1661 check_channel_name_loc(struct Client *source_p, const char *name)
1662 {
1663 const char *p;
1664
1665 s_assert(name != NULL);
1666 if(EmptyString(name))
1667 return 0;
1668
1669 if(ConfigFileEntry.disable_fake_channels && !IsOper(source_p))
1670 {
1671 for(p = name; *p; ++p)
1672 {
1673 if(!IsChanChar(*p) || IsFakeChanChar(*p))
1674 return 0;
1675 }
1676 }
1677 else
1678 {
1679 for(p = name; *p; ++p)
1680 {
1681 if(!IsChanChar(*p))
1682 return 0;
1683 }
1684 }
1685
1686 if(ConfigChannel.only_ascii_channels)
1687 {
1688 for(p = name; *p; ++p)
1689 if(*p < 33 || *p > 126)
1690 return 0;
1691 }
1692
1693
1694 return 1;
1695 }
1696
1697 void user_join(struct Client * client_p, struct Client * source_p, const char * channels, const char * keys)
1698 {
1699 static char jbuf[BUFSIZE];
1700 struct Channel *chptr = NULL;
1701 struct ConfItem *aconf;
1702 char *name;
1703 char *key = NULL;
1704 const char *modes;
1705 int i, flags = 0;
1706 char *p = NULL, *p2 = NULL;
1707 char *chanlist;
1708 char *mykey;
1709
1710 jbuf[0] = '\0';
1711
1712 if(channels == NULL)
1713 return;
1714
1715 /* rebuild the list of channels theyre supposed to be joining.
1716 * this code has a side effect of losing keys, but..
1717 */
1718 chanlist = LOCAL_COPY(channels);
1719 for(name = rb_strtok_r(chanlist, ",", &p); name; name = rb_strtok_r(NULL, ",", &p))
1720 {
1721 /* check the length and name of channel is ok */
1722 if(!check_channel_name_loc(source_p, name) || (strlen(name) > LOC_CHANNELLEN))
1723 {
1724 sendto_one_numeric(source_p, ERR_BADCHANNAME,
1725 form_str(ERR_BADCHANNAME), (unsigned char *) name);
1726 continue;
1727 }
1728
1729 /* join 0 parts all channels */
1730 if(*name == '0' && (name[1] == ',' || name[1] == '\0') && name == chanlist)
1731 {
1732 (void) strcpy(jbuf, "0");
1733 continue;
1734 }
1735
1736 /* check it begins with # or &, and local chans are disabled */
1737 else if(!IsChannelName(name) ||
1738 ( !ConfigChannel.use_local_channels && name[0] == '&'))
1739 {
1740 sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
1741 form_str(ERR_NOSUCHCHANNEL), name);
1742 continue;
1743 }
1744
1745 /* see if its resv'd */
1746 if(!IsExemptResv(source_p) && (aconf = hash_find_resv(name)))
1747 {
1748 sendto_one_numeric(source_p, ERR_BADCHANNAME,
1749 form_str(ERR_BADCHANNAME), name);
1750
1751 /* dont warn for opers */
1752 if(!IsExemptJupe(source_p) && !IsOper(source_p))
1753 sendto_realops_snomask(SNO_SPY, L_NETWIDE,
1754 "User %s (%s@%s) is attempting to join locally juped channel %s (%s)",
1755 source_p->name, source_p->username,
1756 source_p->orighost, name, aconf->passwd);
1757 /* dont update tracking for jupe exempt users, these
1758 * are likely to be spamtrap leaves
1759 */
1760 else if(IsExemptJupe(source_p))
1761 aconf->port--;
1762
1763 continue;
1764 }
1765
1766 if(splitmode && !IsOper(source_p) && (*name != '&') &&
1767 ConfigChannel.no_join_on_split)
1768 {
1769 sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
1770 me.name, source_p->name, name);
1771 continue;
1772 }
1773
1774 if(*jbuf)
1775 (void) strcat(jbuf, ",");
1776 (void) rb_strlcat(jbuf, name, sizeof(jbuf));
1777 }
1778
1779 if(keys != NULL)
1780 {
1781 mykey = LOCAL_COPY(keys);
1782 key = rb_strtok_r(mykey, ",", &p2);
1783 }
1784
1785 for(name = rb_strtok_r(jbuf, ",", &p); name;
1786 key = (key) ? rb_strtok_r(NULL, ",", &p2) : NULL, name = rb_strtok_r(NULL, ",", &p))
1787 {
1788 hook_data_channel_activity hook_info;
1789
1790 /* JOIN 0 simply parts all channels the user is in */
1791 if(*name == '0' && !atoi(name))
1792 {
1793 if(source_p->user->channel.head == NULL)
1794 continue;
1795
1796 do_join_0(&me, source_p);
1797 continue;
1798 }
1799
1800 /* look for the channel */
1801 if((chptr = find_channel(name)) != NULL)
1802 {
1803 if(IsMember(source_p, chptr))
1804 continue;
1805
1806 flags = 0;
1807 }
1808 else
1809 {
1810 hook_data_client_approval moduledata;
1811
1812 moduledata.client = source_p;
1813 moduledata.approved = 0;
1814
1815 call_hook(h_can_create_channel, &moduledata);
1816
1817 if(moduledata.approved != 0)
1818 {
1819 sendto_one(source_p, form_str(moduledata.approved),
1820 me.name, source_p->name, name);
1821 continue;
1822 }
1823
1824 if(splitmode && !IsOper(source_p) && (*name != '&') &&
1825 ConfigChannel.no_create_on_split)
1826 {
1827 sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
1828 me.name, source_p->name, name);
1829 continue;
1830 }
1831
1832 flags = CHFL_CHANOP;
1833 }
1834
1835 if((rb_dlink_list_length(&source_p->user->channel) >=
1836 (unsigned long) ConfigChannel.max_chans_per_user) &&
1837 (!IsOper(source_p) ||
1838 (rb_dlink_list_length(&source_p->user->channel) >=
1839 (unsigned long) ConfigChannel.max_chans_per_user * 3)))
1840 {
1841 sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
1842 me.name, source_p->name, name);
1843 return;
1844 }
1845
1846 if(chptr == NULL) /* If I already have a chptr, no point doing this */
1847 {
1848 chptr = get_or_create_channel(source_p, name, NULL);
1849
1850 if(chptr == NULL)
1851 {
1852 sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
1853 me.name, source_p->name, name);
1854 continue;
1855 }
1856 }
1857
1858 /* can_join checks for +i key, bans etc */
1859 if((i = can_join(source_p, chptr, key)))
1860 {
1861 if(IsOverride(source_p))
1862 {
1863 sendto_wallops_flags(UMODE_WALLOP, &me,
1864 "%s is overriding JOIN to [%s]",
1865 get_oper_name(source_p), chptr->chname);
1866 sendto_server(NULL, chptr, NOCAPS, NOCAPS,
1867 ":%s WALLOPS :%s is overriding JOIN to [%s]",
1868 me.name, get_oper_name(source_p), chptr->chname);
1869 }
1870 else if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) ||
1871 (!ConfigChannel.use_forward || (chptr = check_forward(source_p, chptr, key)) == NULL))
1872 {
1873 /* might be wrong, but is there any other better location for such?
1874 * see extensions/chm_operonly.c for other comments on this
1875 * -- dwr
1876 */
1877 if(i != ERR_CUSTOM)
1878 sendto_one(source_p, form_str(i), me.name, source_p->name, name);
1879
1880 continue;
1881 }
1882 else
1883 sendto_one_numeric(source_p, ERR_LINKCHANNEL, form_str(ERR_LINKCHANNEL), name, chptr->chname);
1884 }
1885
1886 if(flags == 0 &&
1887 !IsOper(source_p) && !IsExemptSpambot(source_p))
1888 check_spambot_warning(source_p, name);
1889
1890 /* add the user to the channel */
1891 add_user_to_channel(chptr, source_p, flags);
1892 if (chptr->mode.join_num &&
1893 rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
1894 {
1895 chptr->join_count = 0;
1896 chptr->join_delta = rb_current_time();
1897 }
1898 chptr->join_count++;
1899
1900 /* we send the user their join here, because we could have to
1901 * send a mode out next.
1902 */
1903 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
1904 source_p->name,
1905 source_p->username, source_p->host, chptr->chname);
1906
1907 /* its a new channel, set +nt and burst. */
1908 if(flags & CHFL_CHANOP)
1909 {
1910 chptr->channelts = rb_current_time();
1911
1912 /* autochanmodes stuff */
1913 if(ConfigChannel.autochanmodes)
1914 {
1915 char * ch;
1916 for(ch = ConfigChannel.autochanmodes; *ch; *ch++)
1917 {
1918 chptr->mode.mode |= chmode_table[*ch].mode_type;
1919 }
1920 }
1921 else
1922 {
1923 chptr->mode.mode |= MODE_TOPICLIMIT;
1924 chptr->mode.mode |= MODE_NOPRIVMSGS;
1925 }
1926
1927 modes = channel_modes(chptr, &me);
1928
1929 sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s %s",
1930 me.name, chptr->chname, modes);
1931
1932 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
1933 ":%s SJOIN %ld %s %s :@%s",
1934 me.id, (long) chptr->channelts,
1935 chptr->chname, modes, source_p->id);
1936 }
1937 else
1938 {
1939 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
1940 ":%s JOIN %ld %s +",
1941 use_id(source_p), (long) chptr->channelts,
1942 chptr->chname);
1943 }
1944
1945 del_invite(chptr, source_p);
1946
1947 if(chptr->topic != NULL)
1948 {
1949 sendto_one(source_p, form_str(RPL_TOPIC), me.name,
1950 source_p->name, chptr->chname, chptr->topic);
1951
1952 sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
1953 me.name, source_p->name, chptr->chname,
1954 chptr->topic_info, chptr->topic_time);
1955 }
1956
1957 channel_member_names(chptr, source_p, 1);
1958
1959 hook_info.client = source_p;
1960 hook_info.chptr = chptr;
1961 hook_info.key = key;
1962 call_hook(h_channel_join, &hook_info);
1963 }
1964
1965 return;
1966 }
1967
1968 /*
1969 * channel_metadata_add
1970 *
1971 * inputs - pointer to channel struct
1972 * - name of metadata item you wish to add
1973 * - value of metadata item
1974 * - 1 if metadata should be propegated, 0 if not
1975 * output - none
1976 * side effects - metadata is added to the channel in question
1977 * - metadata is propegated if propegate is set.
1978 */
1979 struct Metadata *
1980 channel_metadata_add(struct Channel *target, const char *name, const char *value, int propegate)
1981 {
1982 struct Metadata *md;
1983
1984 md = rb_malloc(sizeof(struct Metadata));
1985 md->name = rb_strdup(name);
1986 md->value = rb_strdup(value);
1987
1988 irc_dictionary_add(target->metadata, md->name, md);
1989
1990 if(propegate)
1991 sendto_match_servs(&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * METADATA ADD %s %s :%s",
1992 target->chname, name, value);
1993
1994 return md;
1995 }
1996
1997 /*
1998 * channel_metadata_time_add
1999 *
2000 * inputs - pointer to channel struct
2001 * - name of metadata item you wish to add
2002 * - time_t you wish to add
2003 * - value you wish to add
2004 * output - none
2005 * side effects - metadata is added to the channel in question
2006 */
2007 struct Metadata *
2008 channel_metadata_time_add(struct Channel *target, const char *name, time_t timevalue, const char *value)
2009 {
2010 struct Metadata *md;
2011
2012 md = rb_malloc(sizeof(struct Metadata));
2013 md->name = rb_strdup(name);
2014 md->value = rb_strdup(value);
2015 md->timevalue = timevalue;
2016
2017 irc_dictionary_add(target->metadata, md->name, md);
2018
2019 return md;
2020 }
2021
2022 /*
2023 * channel_metadata_delete
2024 *
2025 * inputs - pointer to channel struct
2026 * - name of metadata item you wish to delete
2027 * output - none
2028 * side effects - metadata is deleted from the channel in question
2029 * - deletion is propegated if propegate is set
2030 */
2031 void
2032 channel_metadata_delete(struct Channel *target, const char *name, int propegate)
2033 {
2034 struct Metadata *md = channel_metadata_find(target, name);
2035
2036 if(!md)
2037 return;
2038
2039 irc_dictionary_delete(target->metadata, md->name);
2040
2041 rb_free(md);
2042
2043 if(propegate)
2044 sendto_match_servs(&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * METADATA DELETE %s %s",
2045 target->chname, name);
2046 }
2047
2048 /*
2049 * channel_metadata_find
2050 *
2051 * inputs - pointer to channel struct
2052 * - name of metadata item you wish to read
2053 * output - the requested metadata, if it exists, elsewise null.
2054 * side effects -
2055 */
2056 struct Metadata *
2057 channel_metadata_find(struct Channel *target, const char *name)
2058 {
2059 if(!target)
2060 return NULL;
2061
2062 if(!target->metadata)
2063 return NULL;
2064
2065 return irc_dictionary_retrieve(target->metadata, name);
2066 }
2067
2068 /*
2069 * channel_metadata_clear
2070 *
2071 * inputs - pointer to channel struct
2072 * output - none
2073 * side effects - metadata is cleared from the channel in question
2074 */
2075 void
2076 channel_metadata_clear(struct Channel *chptr)
2077 {
2078 struct Metadata *md;
2079 struct DictionaryIter iter;
2080
2081 DICTIONARY_FOREACH(md, &iter, chptr->metadata)
2082 {
2083 channel_metadata_delete(chptr, md->name, 0);
2084 }
2085 }