ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/core/m_join.c
Revision: 632
Committed: Thu Jun 1 10:53:00 2006 UTC (17 years, 10 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/core/m_join.c
File size: 19292 byte(s)
Log Message:
- Added channel::disable_fake_channels which disallows creation of channels
  that have ascii 2, 3, 31 and 160 in their names.
- Minor improvements and cleanups to channel name validation routines
  backported from 7.3

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_join.c: Joins a channel.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "tools.h"
27     #include "handlers.h"
28     #include "channel.h"
29     #include "channel_mode.h"
30     #include "client.h"
31     #include "common.h" /* bleah */
32     #include "hash.h"
33     #include "irc_string.h"
34     #include "sprintf_irc.h"
35     #include "ircd.h"
36     #include "list.h"
37     #include "numeric.h"
38     #include "send.h"
39     #include "s_serv.h"
40     #include "s_conf.h"
41     #include "msg.h"
42     #include "parse.h"
43     #include "modules.h"
44    
45    
46     static void m_join(struct Client *, struct Client *, int, char **);
47     static void ms_join(struct Client *, struct Client *, int, char **);
48     static void do_join_0(struct Client *client_p, struct Client *source_p);
49    
50     static void set_final_mode(struct Mode *, struct Mode *);
51     static void remove_our_modes(struct Channel *, struct Client *);
52     static void remove_a_mode(struct Channel *, struct Client *, int, char);
53    
54     static char modebuf[MODEBUFLEN];
55     static char parabuf[MODEBUFLEN];
56     static char sendbuf[MODEBUFLEN];
57     static char *mbuf;
58    
59     struct Message join_msgtab = {
60     "JOIN", 0, 0, 2, 0, MFLG_SLOW, 0,
61     {m_unregistered, m_join, ms_join, m_ignore, m_join, m_ignore}
62     };
63    
64     #ifndef STATIC_MODULES
65     void
66     _modinit(void)
67     {
68     mod_add_cmd(&join_msgtab);
69     }
70    
71     void
72     _moddeinit(void)
73     {
74     mod_del_cmd(&join_msgtab);
75     }
76    
77 knight 31 const char *_version = "$Revision$";
78 adx 30 #endif
79    
80 michael 488 /* last0() stolen from ircu */
81     static char *
82     last0(struct Client *client_p, struct Client *source_p, char *chanlist)
83     {
84     char *p;
85     int join0 = 0;
86    
87     for (p = chanlist; *p; ++p) /* find last "JOIN 0" */
88     {
89     if (*p == '0' && (*(p + 1) == ',' || *(p + 1) == '\0'))
90     {
91     if ((*p + 1) == ',')
92     ++p;
93    
94     chanlist = p + 1;
95     join0 = 1;
96     }
97     else
98     {
99     while (*p != ',' && *p != '\0') /* skip past channel name */
100     ++p;
101    
102     if (*p == '\0') /* hit the end */
103     break;
104     }
105     }
106    
107     if (join0)
108     do_join_0(client_p, source_p);
109    
110     return chanlist;
111     }
112    
113 adx 30 /* m_join()
114     * parv[0] = sender prefix
115     * parv[1] = channel
116     * parv[2] = channel password (key)
117     */
118     static void
119     m_join(struct Client *client_p, struct Client *source_p,
120     int parc, char *parv[])
121     {
122 michael 488 char *p = NULL;
123     char *key_list = NULL;
124     char *chan_list = NULL;
125     char *chan = NULL;
126 adx 30 struct Channel *chptr = NULL;
127 michael 488 int i = 0;
128 adx 30 unsigned int flags = 0;
129    
130 michael 632 if (EmptyString(parv[1]))
131 adx 30 {
132     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
133     me.name, source_p->name, "JOIN");
134     return;
135     }
136    
137 michael 487 assert(client_p == source_p);
138 adx 30
139 michael 488 key_list = parv[2];
140     chan_list = last0(client_p, source_p, parv[1]);
141 michael 487
142 michael 488 for (chan = strtoken(&p, chan_list, ","); chan;
143     chan = strtoken(&p, NULL, ","))
144 adx 30 {
145 michael 488 char *key = NULL;
146 adx 30
147 michael 488 /* If we have any more keys, take the first for this channel. */
148     if (!EmptyString(key_list) && (key_list = strchr(key = key_list, ',')))
149     *key_list++ = '\0';
150    
151     /* Empty keys are the same as no keys. */
152     if (key && *key == '\0')
153     key = NULL;
154    
155 michael 632 if (!check_channel_name(chan, 1))
156 michael 488 {
157     sendto_one(source_p, form_str(ERR_BADCHANNAME),
158     me.name, source_p->name, chan);
159 adx 30 continue;
160 michael 488 }
161 adx 30
162 michael 488 if (ConfigChannel.disable_local_channels && (*chan == '&'))
163     {
164     sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
165     me.name, source_p->name, chan);
166     continue;
167     }
168    
169     if (!IsExemptResv(source_p) &&
170     !(IsOper(source_p) && ConfigFileEntry.oper_pass_resv) &&
171     (!hash_find_resv(chan) == ConfigChannel.restrict_channels))
172     {
173     sendto_one(source_p, form_str(ERR_BADCHANNAME),
174     me.name, source_p->name, chan);
175     sendto_realops_flags(UMODE_SPY, L_ALL,
176     "User %s (%s@%s) is attempting to join locally juped channel %s",
177     source_p->name, source_p->username, source_p->host, chan);
178     continue;
179     }
180    
181     if ((dlink_list_length(&source_p->channel) >= ConfigChannel.max_chans_per_user) &&
182     (!IsOper(source_p) || (dlink_list_length(&source_p->channel) >=
183     ConfigChannel.max_chans_per_user * 3)))
184     {
185 michael 494 sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
186     me.name, source_p->name, chan);
187     break;
188 michael 488 }
189    
190     if ((chptr = hash_find_channel(chan)) != NULL)
191     {
192     if (IsMember(source_p, chptr))
193     continue;
194    
195     if (splitmode && !IsOper(source_p) && (*chan != '&') &&
196     ConfigChannel.no_join_on_split)
197     {
198     sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
199     me.name, source_p->name, chan);
200     continue;
201     }
202    
203     /*
204     * This should never be the case unless there is some sort of
205     * persistant channels.
206     */
207     if (dlink_list_length(&chptr->members) == 0)
208     flags = CHFL_CHANOP;
209     else
210     flags = 0;
211     }
212     else
213     {
214     if (splitmode && !IsOper(source_p) && (*chan != '&') &&
215     (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
216     {
217     sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
218     me.name, source_p->name, chan);
219     continue;
220     }
221    
222     flags = CHFL_CHANOP;
223 michael 632 chptr = make_channel(chan);
224 michael 488 }
225    
226 adx 30 if (!IsOper(source_p))
227     check_spambot_warning(source_p, chptr->chname);
228    
229     /*
230     * can_join checks for +i key, bans.
231     */
232     if ((i = can_join(source_p, chptr, key)))
233     {
234 michael 488 sendto_one(source_p, form_str(i), me.name,
235     source_p->name, chptr->chname);
236 adx 30 continue;
237     }
238    
239     add_user_to_channel(chptr, source_p, flags, YES);
240    
241     /*
242 michael 488 * Set timestamp if appropriate, and propagate
243     */
244 adx 30 if (flags & CHFL_CHANOP)
245     {
246     chptr->channelts = CurrentTime;
247     chptr->mode.mode |= MODE_TOPICLIMIT;
248     chptr->mode.mode |= MODE_NOPRIVMSGS;
249    
250     sendto_server(client_p, source_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
251     ":%s SJOIN %lu %s +nt :@%s",
252     me.id, (unsigned long)chptr->channelts,
253     chptr->chname, source_p->id);
254     sendto_server(client_p, source_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
255     ":%s SJOIN %lu %s +nt :@%s",
256     me.name, (unsigned long)chptr->channelts,
257 michael 632 chptr->chname, source_p->name);
258 adx 30 /*
259     * notify all other users on the new channel
260     */
261     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
262     source_p->name, source_p->username,
263     source_p->host, chptr->chname);
264 michael 488 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +nt",
265 adx 30 me.name, chptr->chname);
266     }
267     else
268     {
269     sendto_server(client_p, source_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
270     ":%s JOIN %lu %s +",
271     source_p->id, (unsigned long)chptr->channelts,
272     chptr->chname);
273     sendto_server(client_p, source_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
274     ":%s SJOIN %lu %s + :%s",
275     me.name, (unsigned long)chptr->channelts,
276     chptr->chname, source_p->name);
277    
278     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
279     source_p->name, source_p->username,
280     source_p->host, chptr->chname);
281     }
282    
283     del_invite(chptr, source_p);
284    
285     if (chptr->topic != NULL)
286     {
287     sendto_one(source_p, form_str(RPL_TOPIC), me.name,
288     source_p->name, chptr->chname, chptr->topic);
289    
290     sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
291     me.name, source_p->name, chptr->chname,
292     chptr->topic_info, chptr->topic_time);
293     }
294    
295     channel_member_names(source_p, chptr, 1);
296    
297 michael 487 source_p->localClient->last_join_time = CurrentTime;
298 adx 30 }
299     }
300    
301     /* ms_join()
302     *
303     * inputs - parv[0] = uid
304     * parv[1] = ts
305     * parv[2] = channel name
306     * parv[3] = modes
307     * output - none
308     * side effects - handles remote JOIN's sent by servers. In TSora
309     * remote clients are joined using SJOIN, hence a
310     * JOIN sent by a server on behalf of a client is an error.
311     * here, the initial code is in to take an extra parameter
312     * and use it for the TimeStamp on a new channel.
313     */
314     static void
315     ms_join(struct Client *client_p, struct Client *source_p,
316     int parc, char *parv[])
317     {
318 michael 632 time_t newts = 0;
319     time_t oldts = 0;
320     int args = 0;
321     int keep_our_modes = 1;
322     int keep_new_modes = 1;
323     int isnew = 0;
324     const char *s = NULL;
325     const char *servername = NULL;
326     struct Channel *chptr = NULL;
327     struct Mode mode, *oldmode;
328 adx 30
329 michael 632 if (parc == 2 && !irccmp(parv[1], "0"))
330 adx 30 {
331     do_join_0(client_p, source_p);
332     return;
333     }
334    
335 michael 632 if (parc < 4 || *parv[2] == '&')
336 adx 30 return;
337    
338 michael 632 if (!check_channel_name(parv[2], 0))
339     {
340     sendto_realops_flags(UMODE_DEBUG, L_ALL,
341     "*** Too long or invalid channel name from %s: %s",
342     client_p->name, parv[2]);
343 adx 30 return;
344 michael 632 }
345 adx 30
346     mbuf = modebuf;
347     mode.mode = mode.limit = 0;
348     mode.key[0] = '\0';
349    
350 michael 632 for (s = parv[3]; *s; ++s)
351 adx 30 {
352 michael 632 switch (*s)
353 adx 30 {
354     case 't':
355     mode.mode |= MODE_TOPICLIMIT;
356     break;
357     case 'n':
358     mode.mode |= MODE_NOPRIVMSGS;
359     break;
360     case 's':
361     mode.mode |= MODE_SECRET;
362     break;
363     case 'm':
364     mode.mode |= MODE_MODERATED;
365     break;
366     case 'i':
367     mode.mode |= MODE_INVITEONLY;
368     break;
369     case 'p':
370     mode.mode |= MODE_PRIVATE;
371     break;
372     case 'k':
373 michael 632 if (parc < 5 + args)
374 adx 30 return;
375    
376     strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
377     args++;
378     break;
379     case 'l':
380 michael 632 if (parc < 5 + args)
381 adx 30 return;
382    
383     mode.limit = atoi(parv[4 + args]);
384     args++;
385     break;
386     }
387     }
388    
389    
390 michael 632 if ((chptr = hash_find_channel(parv[2])) == NULL)
391     {
392     isnew = 1;
393     chptr = make_channel(parv[2]);
394     }
395    
396     newts = atol(parv[1]);
397 adx 30 oldts = chptr->channelts;
398     oldmode = &chptr->mode;
399    
400     if (ConfigFileEntry.ignore_bogus_ts)
401     {
402     if (newts < 800000000)
403     {
404     sendto_realops_flags(UMODE_DEBUG, L_ALL,
405     "*** Bogus TS %lu on %s ignored from %s",
406     (unsigned long)newts, chptr->chname,
407     client_p->name);
408    
409     newts = (oldts == 0) ? 0 : 800000000;
410     }
411     }
412     else
413     {
414     if (!newts && !isnew && oldts)
415     {
416     sendto_channel_local(ALL_MEMBERS, NO, chptr,
417     ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to 0",
418     me.name, chptr->chname, chptr->chname, (unsigned long)oldts);
419     sendto_realops_flags(UMODE_ALL, L_ALL,
420     "Server %s changing TS on %s from %lu to 0",
421     source_p->name, chptr->chname, (unsigned long)oldts);
422     }
423     }
424    
425     if (isnew)
426     chptr->channelts = newts;
427     else if (newts == 0 || oldts == 0)
428     chptr->channelts = 0;
429     else if (newts == oldts)
430     ;
431     else if (newts < oldts)
432     {
433     keep_our_modes = NO;
434     chptr->channelts = newts;
435     }
436     else
437     keep_new_modes = NO;
438    
439     if (!keep_new_modes)
440     mode = *oldmode;
441     else if (keep_our_modes)
442     {
443     mode.mode |= oldmode->mode;
444     if (oldmode->limit > mode.limit)
445     mode.limit = oldmode->limit;
446     if (strcmp(mode.key, oldmode->key) < 0)
447     strcpy(mode.key, oldmode->key);
448     }
449    
450     set_final_mode(&mode, oldmode);
451     chptr->mode = mode;
452    
453     /* Lost the TS, other side wins, so remove modes on this side */
454     if (!keep_our_modes)
455     {
456     remove_our_modes(chptr, source_p);
457     sendto_channel_local(ALL_MEMBERS, NO, chptr,
458     ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to %lu",
459     me.name, chptr->chname, chptr->chname,
460     (unsigned long)oldts, (unsigned long)newts);
461     }
462    
463     if (*modebuf != '\0')
464     {
465     servername = (ConfigServerHide.hide_servers || IsHidden(source_p)) ?
466     me.name : source_p->name;
467    
468     /* This _SHOULD_ be to ALL_MEMBERS
469     * It contains only +imnpstlk, etc */
470     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s %s",
471     servername, chptr->chname, modebuf, parabuf);
472     }
473    
474     if (!IsMember(source_p, chptr))
475     {
476     add_user_to_channel(chptr, source_p, 0, YES);
477     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
478     source_p->name, source_p->username,
479     source_p->host, chptr->chname);
480     }
481    
482     sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS, NOFLAGS,
483     ":%s JOIN %lu %s +",
484     ID(source_p), (unsigned long)chptr->channelts, chptr->chname);
485     sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6, NOFLAGS,
486     ":%s SJOIN %lu %s + :%s",
487     source_p->servptr->name, (unsigned long)chptr->channelts,
488     chptr->chname, source_p->name);
489     }
490    
491     /* do_join_0()
492     *
493     * inputs - pointer to client doing join 0
494     * output - NONE
495     * side effects - Use has decided to join 0. This is legacy
496     * from the days when channels were numbers not names. *sigh*
497     * There is a bunch of evilness necessary here due to
498     * anti spambot code.
499     */
500     static void
501     do_join_0(struct Client *client_p, struct Client *source_p)
502     {
503     struct Channel *chptr = NULL;
504 michael 488 dlink_node *ptr = NULL, *ptr_next = NULL;
505 adx 30
506 michael 488 if (source_p->channel.head && MyConnect(source_p) && !IsOper(source_p))
507 adx 30 check_spambot_warning(source_p, NULL);
508    
509     DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->channel.head)
510     {
511     chptr = ((struct Membership *)ptr->data)->chptr;
512    
513 michael 488 sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS, NOFLAGS,
514     ":%s PART %s", ID(source_p), chptr->chname);
515     sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6, NOFLAGS,
516     ":%s PART %s", source_p->name, chptr->chname);
517     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s",
518     source_p->name, source_p->username,
519     source_p->host, chptr->chname);
520 adx 30
521 michael 488 remove_user_from_channel(ptr->data);
522 adx 30 }
523     }
524    
525     /* set_final_mode()
526     *
527     * inputs - pointer to mode to setup
528     * - pointer to old mode
529     * output - NONE
530     * side effects -
531     */
532     static const struct mode_letter
533     {
534     unsigned int mode;
535     unsigned char letter;
536     } flags[] = {
537     { MODE_NOPRIVMSGS, 'n' },
538     { MODE_TOPICLIMIT, 't' },
539     { MODE_SECRET, 's' },
540     { MODE_MODERATED, 'm' },
541     { MODE_INVITEONLY, 'i' },
542     { MODE_PRIVATE, 'p' },
543     { 0, '\0' }
544     };
545    
546     static void
547     set_final_mode(struct Mode *mode, struct Mode *oldmode)
548     {
549     char *pbuf = parabuf;
550     int what = 0;
551     int len;
552     int i;
553    
554     for (i = 0; flags[i].letter; i++)
555     {
556     if ((flags[i].mode & mode->mode) &&
557     !(flags[i].mode & oldmode->mode))
558     {
559     if (what != 1)
560     {
561     *mbuf++ = '+';
562     what = 1;
563     }
564     *mbuf++ = flags[i].letter;
565     }
566     }
567    
568     for (i = 0; flags[i].letter; i++)
569     {
570     if ((flags[i].mode & oldmode->mode) &&
571     !(flags[i].mode & mode->mode))
572     {
573     if (what != -1)
574     {
575     *mbuf++ = '-';
576     what = -1;
577     }
578     *mbuf++ = flags[i].letter;
579     }
580     }
581    
582     if (oldmode->limit != 0 && mode->limit == 0)
583     {
584     if (what != -1)
585     {
586     *mbuf++ = '-';
587     what = -1;
588     }
589     *mbuf++ = 'l';
590     }
591    
592     if (oldmode->key[0] && !mode->key[0])
593     {
594     if (what != -1)
595     {
596     *mbuf++ = '-';
597     what = -1;
598     }
599     *mbuf++ = 'k';
600     len = ircsprintf(pbuf, "%s ", oldmode->key);
601     pbuf += len;
602     }
603    
604     if (mode->limit != 0 && oldmode->limit != mode->limit)
605     {
606     if (what != 1)
607     {
608     *mbuf++ = '+';
609     what = 1;
610     }
611     *mbuf++ = 'l';
612     len = ircsprintf(pbuf, "%d ", mode->limit);
613     pbuf += len;
614     }
615    
616     if (mode->key[0] && strcmp(oldmode->key, mode->key))
617     {
618     if (what != 1)
619     {
620     *mbuf++ = '+';
621     what = 1;
622     }
623     *mbuf++ = 'k';
624     len = ircsprintf(pbuf, "%s ", mode->key);
625     pbuf += len;
626     }
627     *mbuf = '\0';
628     }
629    
630     /* remove_our_modes()
631     *
632     * inputs - pointer to channel to remove modes from
633     * - client pointer
634     * output - NONE
635     * side effects - Go through the local members, remove all their
636     * chanop modes etc., this side lost the TS.
637     */
638     static void
639     remove_our_modes(struct Channel *chptr, struct Client *source_p)
640     {
641     remove_a_mode(chptr, source_p, CHFL_CHANOP, 'o');
642     #ifdef HALFOPS
643     remove_a_mode(chptr, source_p, CHFL_HALFOP, 'h');
644     #endif
645     remove_a_mode(chptr, source_p, CHFL_VOICE, 'v');
646     }
647    
648     /* remove_a_mode()
649     *
650     * inputs -
651     * output - NONE
652     * side effects - remove ONE mode from a channel
653     */
654     static void
655     remove_a_mode(struct Channel *chptr, struct Client *source_p,
656     int mask, char flag)
657     {
658     dlink_node *ptr;
659     struct Membership *ms;
660     char lmodebuf[MODEBUFLEN];
661     const char *lpara[MAXMODEPARAMS];
662     int count = 0;
663     int lcount;
664    
665     mbuf = lmodebuf;
666     *mbuf++ = '-';
667    
668     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
669     lpara[lcount] = "";
670     sendbuf[0] = '\0';
671    
672     DLINK_FOREACH(ptr, chptr->members.head)
673     {
674     ms = ptr->data;
675    
676     if ((ms->flags & mask) == 0)
677     continue;
678    
679     ms->flags &= ~mask;
680    
681     lpara[count++] = ms->client_p->name;
682    
683     *mbuf++ = flag;
684    
685     if (count >= MAXMODEPARAMS)
686     {
687     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
688     {
689     if (*lpara[lcount] == '\0')
690     break;
691    
692     strlcat(sendbuf, " ", sizeof(sendbuf));
693     strlcat(sendbuf, lpara[lcount], sizeof(sendbuf));
694     lpara[lcount] = "";
695     }
696    
697     *mbuf = '\0';
698     sendto_channel_local(ALL_MEMBERS, NO, chptr,
699     ":%s MODE %s %s%s",
700     (IsHidden(source_p) ||
701     ConfigServerHide.hide_servers) ?
702     me.name : source_p->name,
703     chptr->chname, lmodebuf, sendbuf);
704     mbuf = lmodebuf;
705     *mbuf++ = '-';
706     count = 0;
707     sendbuf[0] = '\0';
708     }
709     }
710    
711     if (count != 0)
712     {
713     *mbuf = '\0';
714     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
715     {
716     if (*lpara[lcount] == '\0')
717     break;
718    
719     strlcat(sendbuf, " ", sizeof(sendbuf));
720     strlcat(sendbuf, lpara[lcount], sizeof(sendbuf));
721     }
722     sendto_channel_local(ALL_MEMBERS, NO, chptr,
723     ":%s MODE %s %s%s",
724     (IsHidden(source_p) || ConfigServerHide.hide_servers) ?
725     me.name : source_p->name,
726     chptr->chname, lmodebuf, sendbuf);
727     }
728     }
729    

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision