ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_join.c
Revision: 494
Committed: Wed Mar 1 16:26:31 2006 UTC (20 years, 4 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/core/m_join.c
File size: 19562 byte(s)
Log Message:
- Break the loop if a client has reached its channel limit

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     if (*parv[1] == '\0')
131     {
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     if (!IsChanPrefix(*chan) || !check_channel_name(chan))
156     {
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 (strlen(chan) > LOCAL_CHANNELLEN)
170     {
171     sendto_one(source_p, form_str(ERR_BADCHANNAME),
172     me.name, source_p->name, chan);
173     continue;
174     }
175    
176     if (!IsExemptResv(source_p) &&
177     !(IsOper(source_p) && ConfigFileEntry.oper_pass_resv) &&
178     (!hash_find_resv(chan) == ConfigChannel.restrict_channels))
179     {
180     sendto_one(source_p, form_str(ERR_BADCHANNAME),
181     me.name, source_p->name, chan);
182     sendto_realops_flags(UMODE_SPY, L_ALL,
183     "User %s (%s@%s) is attempting to join locally juped channel %s",
184     source_p->name, source_p->username, source_p->host, chan);
185     continue;
186     }
187    
188     if ((dlink_list_length(&source_p->channel) >= ConfigChannel.max_chans_per_user) &&
189     (!IsOper(source_p) || (dlink_list_length(&source_p->channel) >=
190     ConfigChannel.max_chans_per_user * 3)))
191     {
192 michael 494 sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
193     me.name, source_p->name, chan);
194     break;
195 michael 488 }
196    
197     if ((chptr = hash_find_channel(chan)) != NULL)
198     {
199     if (IsMember(source_p, chptr))
200     continue;
201    
202     if (splitmode && !IsOper(source_p) && (*chan != '&') &&
203     ConfigChannel.no_join_on_split)
204     {
205     sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
206     me.name, source_p->name, chan);
207     continue;
208     }
209    
210     /*
211     * This should never be the case unless there is some sort of
212     * persistant channels.
213     */
214     if (dlink_list_length(&chptr->members) == 0)
215     flags = CHFL_CHANOP;
216     else
217     flags = 0;
218     }
219     else
220     {
221     if (splitmode && !IsOper(source_p) && (*chan != '&') &&
222     (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
223     {
224     sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
225     me.name, source_p->name, chan);
226     continue;
227     }
228    
229     flags = CHFL_CHANOP;
230    
231     if ((chptr = get_or_create_channel(source_p, chan, NULL)) == NULL)
232     {
233     sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
234     me.name, source_p->name, chan);
235     continue;
236     }
237     }
238    
239 adx 30 if (!IsOper(source_p))
240     check_spambot_warning(source_p, chptr->chname);
241    
242     /*
243     * can_join checks for +i key, bans.
244     */
245     if ((i = can_join(source_p, chptr, key)))
246     {
247 michael 488 sendto_one(source_p, form_str(i), me.name,
248     source_p->name, chptr->chname);
249 adx 30 continue;
250     }
251    
252     add_user_to_channel(chptr, source_p, flags, YES);
253    
254     /*
255 michael 488 * Set timestamp if appropriate, and propagate
256     */
257 adx 30 if (flags & CHFL_CHANOP)
258     {
259     chptr->channelts = CurrentTime;
260     chptr->mode.mode |= MODE_TOPICLIMIT;
261     chptr->mode.mode |= MODE_NOPRIVMSGS;
262    
263     sendto_server(client_p, source_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
264     ":%s SJOIN %lu %s +nt :@%s",
265     me.id, (unsigned long)chptr->channelts,
266     chptr->chname, source_p->id);
267     sendto_server(client_p, source_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
268     ":%s SJOIN %lu %s +nt :@%s",
269     me.name, (unsigned long)chptr->channelts,
270     chptr->chname, parv[0]);
271     /*
272     * notify all other users on the new channel
273     */
274     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
275     source_p->name, source_p->username,
276     source_p->host, chptr->chname);
277 michael 488 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +nt",
278 adx 30 me.name, chptr->chname);
279     }
280     else
281     {
282     sendto_server(client_p, source_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
283     ":%s JOIN %lu %s +",
284     source_p->id, (unsigned long)chptr->channelts,
285     chptr->chname);
286     sendto_server(client_p, source_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
287     ":%s SJOIN %lu %s + :%s",
288     me.name, (unsigned long)chptr->channelts,
289     chptr->chname, source_p->name);
290    
291     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
292     source_p->name, source_p->username,
293     source_p->host, chptr->chname);
294     }
295    
296     del_invite(chptr, source_p);
297    
298     if (chptr->topic != NULL)
299     {
300     sendto_one(source_p, form_str(RPL_TOPIC), me.name,
301     source_p->name, chptr->chname, chptr->topic);
302    
303     sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
304     me.name, source_p->name, chptr->chname,
305     chptr->topic_info, chptr->topic_time);
306     }
307    
308     channel_member_names(source_p, chptr, 1);
309    
310 michael 487 source_p->localClient->last_join_time = CurrentTime;
311 adx 30 }
312     }
313    
314     /* ms_join()
315     *
316     * inputs - parv[0] = uid
317     * parv[1] = ts
318     * parv[2] = channel name
319     * parv[3] = modes
320     * output - none
321     * side effects - handles remote JOIN's sent by servers. In TSora
322     * remote clients are joined using SJOIN, hence a
323     * JOIN sent by a server on behalf of a client is an error.
324     * here, the initial code is in to take an extra parameter
325     * and use it for the TimeStamp on a new channel.
326     */
327     static void
328     ms_join(struct Client *client_p, struct Client *source_p,
329     int parc, char *parv[])
330     {
331     struct Channel *chptr;
332     time_t newts;
333     time_t oldts;
334     static struct Mode mode, *oldmode;
335     int args = 0;
336     int keep_our_modes = 1;
337     int keep_new_modes = 1;
338     int isnew;
339     char *s;
340     const char *servername;
341    
342     if ((parv[1][0] == '0') && (parv[1][1] == '\0') && parc == 2)
343     {
344     do_join_0(client_p, source_p);
345     return;
346     }
347    
348     if (parc < 4)
349     return;
350    
351     if (*parv[2] == '&')
352     return;
353    
354     if (!check_channel_name(parv[2]))
355     return;
356    
357     mbuf = modebuf;
358     mode.mode = mode.limit = 0;
359     mode.key[0] = '\0';
360    
361     s = parv[3];
362     while (*s)
363     {
364     switch (*(s++))
365     {
366     case 't':
367     mode.mode |= MODE_TOPICLIMIT;
368     break;
369     case 'n':
370     mode.mode |= MODE_NOPRIVMSGS;
371     break;
372     case 's':
373     mode.mode |= MODE_SECRET;
374     break;
375     case 'm':
376     mode.mode |= MODE_MODERATED;
377     break;
378     case 'i':
379     mode.mode |= MODE_INVITEONLY;
380     break;
381     case 'p':
382     mode.mode |= MODE_PRIVATE;
383     break;
384     case 'k':
385     if (parc < 5+args)
386     return;
387    
388     strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
389     args++;
390     break;
391     case 'l':
392     if (parc < 5+args)
393     return;
394    
395     mode.limit = atoi(parv[4 + args]);
396     args++;
397     break;
398     }
399     }
400    
401     if ((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
402     return; /* channel name too long? */
403    
404     newts = atol(parv[1]);
405     oldts = chptr->channelts;
406     oldmode = &chptr->mode;
407    
408     if (ConfigFileEntry.ignore_bogus_ts)
409     {
410     if (newts < 800000000)
411     {
412     sendto_realops_flags(UMODE_DEBUG, L_ALL,
413     "*** Bogus TS %lu on %s ignored from %s",
414     (unsigned long)newts, chptr->chname,
415     client_p->name);
416    
417     newts = (oldts == 0) ? 0 : 800000000;
418     }
419     }
420     else
421     {
422     if (!newts && !isnew && oldts)
423     {
424     sendto_channel_local(ALL_MEMBERS, NO, chptr,
425     ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to 0",
426     me.name, chptr->chname, chptr->chname, (unsigned long)oldts);
427     sendto_realops_flags(UMODE_ALL, L_ALL,
428     "Server %s changing TS on %s from %lu to 0",
429     source_p->name, chptr->chname, (unsigned long)oldts);
430     }
431     }
432    
433     if (isnew)
434     chptr->channelts = newts;
435     else if (newts == 0 || oldts == 0)
436     chptr->channelts = 0;
437     else if (newts == oldts)
438     ;
439     else if (newts < oldts)
440     {
441     keep_our_modes = NO;
442     chptr->channelts = newts;
443     }
444     else
445     keep_new_modes = NO;
446    
447     if (!keep_new_modes)
448     mode = *oldmode;
449     else if (keep_our_modes)
450     {
451     mode.mode |= oldmode->mode;
452     if (oldmode->limit > mode.limit)
453     mode.limit = oldmode->limit;
454     if (strcmp(mode.key, oldmode->key) < 0)
455     strcpy(mode.key, oldmode->key);
456     }
457    
458     set_final_mode(&mode, oldmode);
459     chptr->mode = mode;
460    
461     /* Lost the TS, other side wins, so remove modes on this side */
462     if (!keep_our_modes)
463     {
464     remove_our_modes(chptr, source_p);
465     sendto_channel_local(ALL_MEMBERS, NO, chptr,
466     ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to %lu",
467     me.name, chptr->chname, chptr->chname,
468     (unsigned long)oldts, (unsigned long)newts);
469     }
470    
471     if (*modebuf != '\0')
472     {
473     servername = (ConfigServerHide.hide_servers || IsHidden(source_p)) ?
474     me.name : source_p->name;
475    
476     /* This _SHOULD_ be to ALL_MEMBERS
477     * It contains only +imnpstlk, etc */
478     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s %s",
479     servername, chptr->chname, modebuf, parabuf);
480     }
481    
482     if (!IsMember(source_p, chptr))
483     {
484     add_user_to_channel(chptr, source_p, 0, YES);
485     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
486     source_p->name, source_p->username,
487     source_p->host, chptr->chname);
488     }
489    
490     sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS, NOFLAGS,
491     ":%s JOIN %lu %s +",
492     ID(source_p), (unsigned long)chptr->channelts, chptr->chname);
493     sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6, NOFLAGS,
494     ":%s SJOIN %lu %s + :%s",
495     source_p->servptr->name, (unsigned long)chptr->channelts,
496     chptr->chname, source_p->name);
497     }
498    
499     /* do_join_0()
500     *
501     * inputs - pointer to client doing join 0
502     * output - NONE
503     * side effects - Use has decided to join 0. This is legacy
504     * from the days when channels were numbers not names. *sigh*
505     * There is a bunch of evilness necessary here due to
506     * anti spambot code.
507     */
508     static void
509     do_join_0(struct Client *client_p, struct Client *source_p)
510     {
511     struct Channel *chptr = NULL;
512 michael 488 dlink_node *ptr = NULL, *ptr_next = NULL;
513 adx 30
514 michael 488 if (source_p->channel.head && MyConnect(source_p) && !IsOper(source_p))
515 adx 30 check_spambot_warning(source_p, NULL);
516    
517     DLINK_FOREACH_SAFE(ptr, ptr_next, source_p->channel.head)
518     {
519     chptr = ((struct Membership *)ptr->data)->chptr;
520    
521 michael 488 sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS, NOFLAGS,
522     ":%s PART %s", ID(source_p), chptr->chname);
523     sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6, NOFLAGS,
524     ":%s PART %s", source_p->name, chptr->chname);
525     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s",
526     source_p->name, source_p->username,
527     source_p->host, chptr->chname);
528 adx 30
529 michael 488 remove_user_from_channel(ptr->data);
530 adx 30 }
531     }
532    
533     /* set_final_mode()
534     *
535     * inputs - pointer to mode to setup
536     * - pointer to old mode
537     * output - NONE
538     * side effects -
539     */
540     static const struct mode_letter
541     {
542     unsigned int mode;
543     unsigned char letter;
544     } flags[] = {
545     { MODE_NOPRIVMSGS, 'n' },
546     { MODE_TOPICLIMIT, 't' },
547     { MODE_SECRET, 's' },
548     { MODE_MODERATED, 'm' },
549     { MODE_INVITEONLY, 'i' },
550     { MODE_PRIVATE, 'p' },
551     { 0, '\0' }
552     };
553    
554     static void
555     set_final_mode(struct Mode *mode, struct Mode *oldmode)
556     {
557     char *pbuf = parabuf;
558     int what = 0;
559     int len;
560     int i;
561    
562     for (i = 0; flags[i].letter; i++)
563     {
564     if ((flags[i].mode & mode->mode) &&
565     !(flags[i].mode & oldmode->mode))
566     {
567     if (what != 1)
568     {
569     *mbuf++ = '+';
570     what = 1;
571     }
572     *mbuf++ = flags[i].letter;
573     }
574     }
575    
576     for (i = 0; flags[i].letter; i++)
577     {
578     if ((flags[i].mode & oldmode->mode) &&
579     !(flags[i].mode & mode->mode))
580     {
581     if (what != -1)
582     {
583     *mbuf++ = '-';
584     what = -1;
585     }
586     *mbuf++ = flags[i].letter;
587     }
588     }
589    
590     if (oldmode->limit != 0 && mode->limit == 0)
591     {
592     if (what != -1)
593     {
594     *mbuf++ = '-';
595     what = -1;
596     }
597     *mbuf++ = 'l';
598     }
599    
600     if (oldmode->key[0] && !mode->key[0])
601     {
602     if (what != -1)
603     {
604     *mbuf++ = '-';
605     what = -1;
606     }
607     *mbuf++ = 'k';
608     len = ircsprintf(pbuf, "%s ", oldmode->key);
609     pbuf += len;
610     }
611    
612     if (mode->limit != 0 && oldmode->limit != mode->limit)
613     {
614     if (what != 1)
615     {
616     *mbuf++ = '+';
617     what = 1;
618     }
619     *mbuf++ = 'l';
620     len = ircsprintf(pbuf, "%d ", mode->limit);
621     pbuf += len;
622     }
623    
624     if (mode->key[0] && strcmp(oldmode->key, mode->key))
625     {
626     if (what != 1)
627     {
628     *mbuf++ = '+';
629     what = 1;
630     }
631     *mbuf++ = 'k';
632     len = ircsprintf(pbuf, "%s ", mode->key);
633     pbuf += len;
634     }
635     *mbuf = '\0';
636     }
637    
638     /* remove_our_modes()
639     *
640     * inputs - pointer to channel to remove modes from
641     * - client pointer
642     * output - NONE
643     * side effects - Go through the local members, remove all their
644     * chanop modes etc., this side lost the TS.
645     */
646     static void
647     remove_our_modes(struct Channel *chptr, struct Client *source_p)
648     {
649     remove_a_mode(chptr, source_p, CHFL_CHANOP, 'o');
650     #ifdef HALFOPS
651     remove_a_mode(chptr, source_p, CHFL_HALFOP, 'h');
652     #endif
653     remove_a_mode(chptr, source_p, CHFL_VOICE, 'v');
654     }
655    
656     /* remove_a_mode()
657     *
658     * inputs -
659     * output - NONE
660     * side effects - remove ONE mode from a channel
661     */
662     static void
663     remove_a_mode(struct Channel *chptr, struct Client *source_p,
664     int mask, char flag)
665     {
666     dlink_node *ptr;
667     struct Membership *ms;
668     char lmodebuf[MODEBUFLEN];
669     const char *lpara[MAXMODEPARAMS];
670     int count = 0;
671     int lcount;
672    
673     mbuf = lmodebuf;
674     *mbuf++ = '-';
675    
676     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
677     lpara[lcount] = "";
678     sendbuf[0] = '\0';
679    
680     DLINK_FOREACH(ptr, chptr->members.head)
681     {
682     ms = ptr->data;
683    
684     if ((ms->flags & mask) == 0)
685     continue;
686    
687     ms->flags &= ~mask;
688    
689     lpara[count++] = ms->client_p->name;
690    
691     *mbuf++ = flag;
692    
693     if (count >= MAXMODEPARAMS)
694     {
695     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
696     {
697     if (*lpara[lcount] == '\0')
698     break;
699    
700     strlcat(sendbuf, " ", sizeof(sendbuf));
701     strlcat(sendbuf, lpara[lcount], sizeof(sendbuf));
702     lpara[lcount] = "";
703     }
704    
705     *mbuf = '\0';
706     sendto_channel_local(ALL_MEMBERS, NO, chptr,
707     ":%s MODE %s %s%s",
708     (IsHidden(source_p) ||
709     ConfigServerHide.hide_servers) ?
710     me.name : source_p->name,
711     chptr->chname, lmodebuf, sendbuf);
712     mbuf = lmodebuf;
713     *mbuf++ = '-';
714     count = 0;
715     sendbuf[0] = '\0';
716     }
717     }
718    
719     if (count != 0)
720     {
721     *mbuf = '\0';
722     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
723     {
724     if (*lpara[lcount] == '\0')
725     break;
726    
727     strlcat(sendbuf, " ", sizeof(sendbuf));
728     strlcat(sendbuf, lpara[lcount], sizeof(sendbuf));
729     }
730     sendto_channel_local(ALL_MEMBERS, NO, chptr,
731     ":%s MODE %s %s%s",
732     (IsHidden(source_p) || ConfigServerHide.hide_servers) ?
733     me.name : source_p->name,
734     chptr->chname, lmodebuf, sendbuf);
735     }
736     }
737    

Properties

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