3 * Copyright (C) 2005 Lee Hardy <lee@leeh.co.uk>
4 * Copyright (C) 2005 ircd-ratbox development team
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * 1.Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2.Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3.The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
40 #include "supported.h"
42 static const char monitor_desc
[] = "Provides the MONITOR facility for tracking user signon and signoff";
44 static int monitor_init(void);
45 static void monitor_deinit(void);
46 static void m_monitor(struct MsgBuf
*, struct Client
*, struct Client
*, int, const char **);
48 struct Message monitor_msgtab
= {
49 "MONITOR", 0, 0, 0, 0,
50 {mg_unreg
, {m_monitor
, 2}, mg_ignore
, mg_ignore
, mg_ignore
, {m_monitor
, 2}}
53 mapi_clist_av1 monitor_clist
[] = { &monitor_msgtab
, NULL
};
55 DECLARE_MODULE_AV2(monitor
, monitor_init
, monitor_deinit
, monitor_clist
, NULL
, NULL
, NULL
, NULL
, monitor_desc
);
57 static int monitor_init(void)
59 add_isupport("MONITOR", isupport_intptr
, &ConfigFileEntry
.max_monitor
);
63 static void monitor_deinit(void)
65 delete_isupport("MONITOR");
69 add_monitor(struct Client
*client_p
, const char *nicks
)
71 rb_dlink_node
*prev_head
, *ptr
;
72 struct Client
*target_p
;
73 struct monitor
*monptr
;
78 prev_head
= client_p
->localClient
->monitor_list
.head
;
79 tmp
= LOCAL_COPY(nicks
);
81 for(name
= rb_strtok_r(tmp
, ",", &p
); name
; name
= rb_strtok_r(NULL
, ",", &p
))
83 if(EmptyString(name
) || strlen(name
) > NICKLEN
-1)
86 if(rb_dlink_list_length(&client_p
->localClient
->monitor_list
) >=
87 (unsigned long)ConfigFileEntry
.max_monitor
)
92 if (!clean_nick(name
, 0))
95 monptr
= find_monitor(name
, 1);
97 /* already monitoring this nick */
98 if(rb_dlinkFind(client_p
, &monptr
->users
))
101 rb_dlinkAddAlloc(client_p
, &monptr
->users
);
102 rb_dlinkAddAlloc(monptr
, &client_p
->localClient
->monitor_list
);
105 send_multiline_init(client_p
, ",", form_str(RPL_MONONLINE
),
110 if (prev_head
!= NULL
)
111 prev_head
= prev_head
->prev
;
113 prev_head
= client_p
->localClient
->monitor_list
.tail
;
115 RB_DLINK_FOREACH_PREV(ptr
, prev_head
)
118 target_p
= find_named_person(monptr
->name
);
120 if (target_p
!= NULL
)
122 send_multiline_item(client_p
, "%s!%s@%s",
129 send_multiline_fini(client_p
, NULL
);
131 send_multiline_init(client_p
, ",", form_str(RPL_MONOFFLINE
),
136 RB_DLINK_FOREACH_PREV(ptr
, prev_head
)
140 if (find_named_person(monptr
->name
) == NULL
)
142 send_multiline_item(client_p
, "%s", monptr
->name
);
146 send_multiline_fini(client_p
, NULL
);
153 snprintf(buf
, sizeof buf
, "%s,%s", name
, p
);
155 snprintf(buf
, sizeof buf
, "%s", name
);
157 sendto_one(client_p
, form_str(ERR_MONLISTFULL
),
160 ConfigFileEntry
.max_monitor
,
166 del_monitor(struct Client
*client_p
, const char *nicks
)
168 struct monitor
*monptr
;
173 if(!rb_dlink_list_length(&client_p
->localClient
->monitor_list
))
176 tmp
= LOCAL_COPY(nicks
);
178 for(name
= rb_strtok_r(tmp
, ",", &p
); name
; name
= rb_strtok_r(NULL
, ",", &p
))
180 if(EmptyString(name
))
184 if((monptr
= find_monitor(name
, 0)) == NULL
)
187 rb_dlinkFindDestroy(client_p
, &monptr
->users
);
188 rb_dlinkFindDestroy(monptr
, &client_p
->localClient
->monitor_list
);
190 free_monitor(monptr
);
195 list_monitor(struct Client
*client_p
)
197 struct monitor
*monptr
;
200 if(!rb_dlink_list_length(&client_p
->localClient
->monitor_list
))
202 sendto_one(client_p
, form_str(RPL_ENDOFMONLIST
),
203 me
.name
, client_p
->name
);
207 send_multiline_init(client_p
, ",", form_str(RPL_MONLIST
),
212 RB_DLINK_FOREACH(ptr
, client_p
->localClient
->monitor_list
.head
)
216 send_multiline_item(client_p
, "%s", monptr
->name
);
219 send_multiline_fini(client_p
, NULL
);
220 sendto_one(client_p
, form_str(RPL_ENDOFMONLIST
),
221 me
.name
, client_p
->name
);
225 show_monitor_status(struct Client
*client_p
)
227 struct Client
*target_p
;
228 struct monitor
*monptr
;
231 send_multiline_init(client_p
, ",", form_str(RPL_MONONLINE
),
236 RB_DLINK_FOREACH(ptr
, client_p
->localClient
->monitor_list
.head
)
239 target_p
= find_named_person(monptr
->name
);
241 if (target_p
!= NULL
)
243 send_multiline_item(client_p
, "%s!%s@%s",
250 send_multiline_fini(client_p
, NULL
);
252 send_multiline_init(client_p
, ",", form_str(RPL_MONOFFLINE
),
257 RB_DLINK_FOREACH(ptr
, client_p
->localClient
->monitor_list
.head
)
261 if (find_named_person(monptr
->name
) == NULL
)
263 send_multiline_item(client_p
, "%s", monptr
->name
);
267 send_multiline_fini(client_p
, NULL
);
271 m_monitor(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
276 if(parc
< 3 || EmptyString(parv
[2]))
278 sendto_one(client_p
, form_str(ERR_NEEDMOREPARAMS
),
279 me
.name
, source_p
->name
, "MONITOR");
283 add_monitor(source_p
, parv
[2]);
286 if(parc
< 3 || EmptyString(parv
[2]))
288 sendto_one(client_p
, form_str(ERR_NEEDMOREPARAMS
),
289 me
.name
, source_p
->name
, "MONITOR");
293 del_monitor(source_p
, parv
[2]);
298 clear_monitor(source_p
);
303 list_monitor(source_p
);
308 show_monitor_status(source_p
);