ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_join.c
Revision: 1832
Committed: Fri Apr 19 19:16:09 2013 UTC (13 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 19199 byte(s)
Log Message:
- Made all numeric defines use the actual string instead of the numeric value
  which allows to use gcc's printf format attribute
- Remove current message locale implementation

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

Properties

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