ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/core/m_join.c
Revision: 2663
Committed: Thu Dec 12 19:42:22 2013 UTC (10 years, 4 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/core/m_join.c
File size: 19300 byte(s)
Log Message:
- m_join.c:m_join(): actually test conf->reason for being a NULL pointer

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

Properties

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