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
30 #include "irc_string.h"
41 static int m_list(struct Client
*, struct Client
*, int, const char **);
42 static int mo_list(struct Client
*, struct Client
*, int, const char **);
44 struct Message list_msgtab
= {
45 "LIST", 0, 0, 0, MFLG_SLOW
,
46 {mg_unreg
, {m_list
, 0}, mg_ignore
, mg_ignore
, mg_ignore
, {mo_list
, 0}}
49 mapi_clist_av1 list_clist
[] = { &list_msgtab
, NULL
};
50 DECLARE_MODULE_AV1(list
, NULL
, NULL
, list_clist
, NULL
, NULL
, "$Revision: 26 $");
52 static void list_all_channels(struct Client
*source_p
);
53 static void list_limit_channels(struct Client
*source_p
, const char *param
);
54 static void list_named_channel(struct Client
*source_p
, const char *name
);
57 * parv[0] = sender prefix
61 m_list(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
63 static time_t last_used
= 0L;
65 /* pace this due to the sheer traffic involved */
66 if(((last_used
+ ConfigFileEntry
.pace_wait
) > CurrentTime
))
68 sendto_one(source_p
, form_str(RPL_LOAD2HI
),
69 me
.name
, source_p
->name
, "LIST");
70 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
74 last_used
= CurrentTime
;
76 /* If no arg, do all channels *whee*, else just one channel */
77 if(parc
< 2 || EmptyString(parv
[1]))
78 list_all_channels(source_p
);
79 else if(IsChannelName(parv
[1]))
80 list_named_channel(source_p
, parv
[1]);
82 list_limit_channels(source_p
, parv
[1]);
88 * parv[0] = sender prefix
92 mo_list(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
94 /* If no arg, do all channels *whee*, else just one channel */
95 if(parc
< 2 || EmptyString(parv
[1]))
96 list_all_channels(source_p
);
97 else if(IsChannelName(parv
[1]))
98 list_named_channel(source_p
, parv
[1]);
100 list_limit_channels(source_p
, parv
[1]);
105 /* list_all_channels()
107 * inputs - pointer to client requesting list
109 * side effects - list all channels to source_p
112 list_all_channels(struct Client
*source_p
)
114 struct Channel
*chptr
;
118 /* give them an output limit of 90% of their sendq. --fl */
119 sendq_limit
= (int) get_sendq(source_p
);
123 sendto_one(source_p
, form_str(RPL_LISTSTART
), me
.name
, source_p
->name
);
125 DLINK_FOREACH(ptr
, global_channel_list
.head
)
129 /* if theyre overflowing their sendq, stop. --fl */
130 if(linebuf_len(&source_p
->localClient
->buf_sendq
) > sendq_limit
)
132 sendto_one(source_p
, form_str(ERR_TOOMANYMATCHES
),
133 me
.name
, source_p
->name
, "LIST");
137 if(SecretChannel(chptr
) && !IsMember(source_p
, chptr
))
140 sendto_one(source_p
, form_str(RPL_LIST
),
141 me
.name
, source_p
->name
, chptr
->chname
,
142 dlink_list_length(&chptr
->members
),
143 chptr
->topic
== NULL
? "" : chptr
->topic
);
146 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
151 list_limit_channels(struct Client
*source_p
, const char *param
)
153 struct Channel
*chptr
;
157 unsigned int sendq_limit
;
162 args
= LOCAL_COPY(param
);
164 for(i
= 0; i
< 2; i
++)
166 if((p
= strchr(args
, ',')) != NULL
)
172 if((max
= atoi(args
)) <= 0)
175 else if(*args
== '>')
178 if((min
= atoi(args
)) < 0)
188 /* give them an output limit of 90% of their sendq. --fl */
189 sendq_limit
= (unsigned int) get_sendq(source_p
);
193 sendto_one(source_p
, form_str(RPL_LISTSTART
), me
.name
, source_p
->name
);
195 DLINK_FOREACH(ptr
, global_channel_list
.head
)
199 /* if theyre overflowing their sendq, stop. --fl */
200 if(linebuf_len(&source_p
->localClient
->buf_sendq
) > sendq_limit
)
202 sendto_one(source_p
, form_str(ERR_TOOMANYMATCHES
),
203 me
.name
, source_p
->name
, "LIST");
207 if(dlink_list_length(&chptr
->members
) >= max
||
208 dlink_list_length(&chptr
->members
) <= min
)
211 if(SecretChannel(chptr
) && !IsMember(source_p
, chptr
))
214 sendto_one(source_p
, form_str(RPL_LIST
),
215 me
.name
, source_p
->name
, chptr
->chname
,
216 dlink_list_length(&chptr
->members
),
217 chptr
->topic
== NULL
? "" : chptr
->topic
);
220 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
225 /* list_named_channel()
227 * inputs - pointer to client requesting list
229 * side effects - list single channel to source
232 list_named_channel(struct Client
*source_p
, const char *name
)
234 struct Channel
*chptr
;
236 char *n
= LOCAL_COPY(name
);
238 sendto_one(source_p
, form_str(RPL_LISTSTART
), me
.name
, source_p
->name
);
240 if((p
= strchr(n
, ',')))
245 sendto_one_numeric(source_p
, ERR_NOSUCHNICK
,
246 form_str(ERR_NOSUCHNICK
), name
);
247 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
251 chptr
= find_channel(n
);
255 sendto_one_numeric(source_p
, ERR_NOSUCHNICK
,
256 form_str(ERR_NOSUCHNICK
), n
);
257 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);
261 if(ShowChannel(source_p
, chptr
))
262 sendto_one(source_p
, form_str(RPL_LIST
),
263 me
.name
, source_p
->name
, chptr
->chname
,
264 dlink_list_length(&chptr
->members
),
265 chptr
->topic
== NULL
? "" : chptr
->topic
);
267 sendto_one(source_p
, form_str(RPL_LISTEND
), me
.name
, source_p
->name
);