2 * ircd-ratbox: A slightly useful ircd.
3 * m_list.c: Shows what servers are currently connected.
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
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.
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.
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
24 * $Id: m_list_ratbox.c 722 2006-02-08 21:51:28Z nenolod $
32 #include "irc_string.h"
43 static int m_list(struct Client
*, struct Client
*, int, const char **);
44 static int mo_list(struct Client
*, struct Client
*, int, const char **);
46 struct Message list_msgtab
= {
47 "LIST", 0, 0, 0, MFLG_SLOW
,
48 {mg_unreg
, {m_list
, 0}, mg_ignore
, mg_ignore
, mg_ignore
, {mo_list
, 0}}
51 mapi_clist_av1 list_clist
[] = { &list_msgtab
, NULL
};
52 DECLARE_MODULE_AV1(list
, NULL
, NULL
, list_clist
, NULL
, NULL
, "$Revision: 722 $");
54 static void list_all_channels(struct Client
*source_p
);
55 static void list_limit_channels(struct Client
*source_p
, const char *param
);
56 static void list_named_channel(struct Client
*source_p
, const char *name
);
59 * parv[0] = sender prefix
63 m_list(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
65 static time_t last_used
= 0L;
67 /* pace this due to the sheer traffic involved */
68 if(((last_used
+ ConfigFileEntry
.pace_wait
) > CurrentTime
))
70 sendto_one(source_p
, form_str(RPL_LOAD2HI
),
71 me
.name
, source_p
->name
, "LIST");
72 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
76 last_used
= CurrentTime
;
78 /* If no arg, do all channels *whee*, else just one channel */
79 if(parc
< 2 || EmptyString(parv
[1]))
80 list_all_channels(source_p
);
81 else if(IsChannelName(parv
[1]))
82 list_named_channel(source_p
, parv
[1]);
84 list_limit_channels(source_p
, parv
[1]);
90 * parv[0] = sender prefix
94 mo_list(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
96 /* If no arg, do all channels *whee*, else just one channel */
97 if(parc
< 2 || EmptyString(parv
[1]))
98 list_all_channels(source_p
);
99 else if(IsChannelName(parv
[1]))
100 list_named_channel(source_p
, parv
[1]);
102 list_limit_channels(source_p
, parv
[1]);
107 /* list_all_channels()
109 * inputs - pointer to client requesting list
111 * side effects - list all channels to source_p
114 list_all_channels(struct Client
*source_p
)
116 struct Channel
*chptr
;
120 /* give them an output limit of 90% of their sendq. --fl */
121 sendq_limit
= (int) get_sendq(source_p
);
125 sendto_one(source_p
, form_str(RPL_LISTSTART
), me
.name
, source_p
->name
);
127 DLINK_FOREACH(ptr
, global_channel_list
.head
)
131 /* if theyre overflowing their sendq, stop. --fl */
132 if(linebuf_len(&source_p
->localClient
->buf_sendq
) > sendq_limit
)
134 sendto_one(source_p
, form_str(ERR_TOOMANYMATCHES
),
135 me
.name
, source_p
->name
, "LIST");
139 if(SecretChannel(chptr
) && !IsMember(source_p
, chptr
))
142 sendto_one(source_p
, form_str(RPL_LIST
),
143 me
.name
, source_p
->name
, chptr
->chname
,
144 dlink_list_length(&chptr
->members
),
145 chptr
->topic
== NULL
? "" : chptr
->topic
);
148 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
153 list_limit_channels(struct Client
*source_p
, const char *param
)
155 struct Channel
*chptr
;
159 unsigned int sendq_limit
;
164 args
= LOCAL_COPY(param
);
166 for(i
= 0; i
< 2; i
++)
168 if((p
= strchr(args
, ',')) != NULL
)
174 if((max
= atoi(args
)) <= 0)
177 else if(*args
== '>')
180 if((min
= atoi(args
)) < 0)
190 /* give them an output limit of 90% of their sendq. --fl */
191 sendq_limit
= (unsigned int) get_sendq(source_p
);
195 sendto_one(source_p
, form_str(RPL_LISTSTART
), me
.name
, source_p
->name
);
197 DLINK_FOREACH(ptr
, global_channel_list
.head
)
201 /* if theyre overflowing their sendq, stop. --fl */
202 if(linebuf_len(&source_p
->localClient
->buf_sendq
) > sendq_limit
)
204 sendto_one(source_p
, form_str(ERR_TOOMANYMATCHES
),
205 me
.name
, source_p
->name
, "LIST");
209 if(dlink_list_length(&chptr
->members
) >= max
||
210 dlink_list_length(&chptr
->members
) <= min
)
213 if(SecretChannel(chptr
) && !IsMember(source_p
, chptr
))
216 sendto_one(source_p
, form_str(RPL_LIST
),
217 me
.name
, source_p
->name
, chptr
->chname
,
218 dlink_list_length(&chptr
->members
),
219 chptr
->topic
== NULL
? "" : chptr
->topic
);
222 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
227 /* list_named_channel()
229 * inputs - pointer to client requesting list
231 * side effects - list single channel to source
234 list_named_channel(struct Client
*source_p
, const char *name
)
236 struct Channel
*chptr
;
238 char *n
= LOCAL_COPY(name
);
240 sendto_one(source_p
, form_str(RPL_LISTSTART
), me
.name
, source_p
->name
);
242 if((p
= strchr(n
, ',')))
247 sendto_one_numeric(source_p
, ERR_NOSUCHNICK
,
248 form_str(ERR_NOSUCHNICK
), name
);
249 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
253 chptr
= find_channel(n
);
257 sendto_one_numeric(source_p
, ERR_NOSUCHNICK
,
258 form_str(ERR_NOSUCHNICK
), n
);
259 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
263 if(ShowChannel(source_p
, chptr
))
264 sendto_one(source_p
, form_str(RPL_LIST
),
265 me
.name
, source_p
->name
, chptr
->chname
,
266 dlink_list_length(&chptr
->members
),
267 chptr
->topic
== NULL
? "" : chptr
->topic
);
269 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);