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.
30 * $Id: m_monitor.c 312 2005-11-07 10:47:33Z jilles $
43 static int m_monitor(struct Client
*, struct Client
*, int, const char **);
45 struct Message monitor_msgtab
= {
46 "MONITOR", 0, 0, 0, MFLG_SLOW
,
47 {mg_unreg
, {m_monitor
, 2}, mg_ignore
, mg_ignore
, mg_ignore
, {m_monitor
, 2}}
50 mapi_clist_av1 monitor_clist
[] = { &monitor_msgtab
, NULL
};
51 DECLARE_MODULE_AV1(monitor
, NULL
, NULL
, monitor_clist
, NULL
, NULL
, "$Revision: 312 $");
54 add_monitor(struct Client
*client_p
, const char *nicks
)
56 char onbuf
[BUFSIZE
], offbuf
[BUFSIZE
];
57 struct Client
*target_p
;
58 struct monitor
*monptr
;
64 int cur_onlen
, cur_offlen
;
66 /* these two are same length, just diff numeric */
67 cur_offlen
= cur_onlen
= mlen
= sprintf(onbuf
, form_str(RPL_MONONLINE
),
68 me
.name
, client_p
->name
, "");
69 sprintf(offbuf
, form_str(RPL_MONOFFLINE
),
70 me
.name
, client_p
->name
, "");
73 offptr
= offbuf
+ mlen
;
75 tmp
= LOCAL_COPY(nicks
);
77 for(name
= strtoken(&p
, tmp
, ","); name
; name
= strtoken(&p
, NULL
, ","))
79 if(EmptyString(name
) || strlen(name
) > NICKLEN
-1)
82 if(dlink_list_length(&client_p
->localClient
->monitor_list
) >=
83 ConfigFileEntry
.max_monitor
)
88 sendto_one(client_p
, "%s", onbuf
);
89 if(cur_offlen
!= mlen
)
90 sendto_one(client_p
, "%s", offbuf
);
93 snprintf(buf
, sizeof(buf
), "%s,%s", name
, p
);
95 snprintf(buf
, sizeof(buf
), "%s", name
);
97 sendto_one(client_p
, form_str(ERR_MONLISTFULL
),
98 me
.name
, client_p
->name
,
99 ConfigFileEntry
.max_monitor
, buf
);
103 monptr
= find_monitor(name
, 1);
105 /* already monitoring this nick */
106 if(dlinkFind(client_p
, &monptr
->users
))
109 dlinkAddAlloc(client_p
, &monptr
->users
);
110 dlinkAddAlloc(monptr
, &client_p
->localClient
->monitor_list
);
112 if((target_p
= find_named_person(name
)) != NULL
)
114 if(cur_onlen
+ strlen(target_p
->name
) +
115 strlen(target_p
->username
) + strlen(target_p
->host
) + 3 >= BUFSIZE
-3)
117 sendto_one(client_p
, "%s", onbuf
);
119 onptr
= onbuf
+ mlen
;
122 if(cur_onlen
!= mlen
)
128 arglen
= sprintf(onptr
, "%s!%s@%s",
129 target_p
->name
, target_p
->username
,
136 if(cur_offlen
+ strlen(name
) + 1 >= BUFSIZE
-3)
138 sendto_one(client_p
, "%s", offbuf
);
140 offptr
= offbuf
+ mlen
;
143 if(cur_offlen
!= mlen
)
149 arglen
= sprintf(offptr
, "%s", name
);
151 cur_offlen
+= arglen
;
155 if(cur_onlen
!= mlen
)
156 sendto_one(client_p
, "%s", onbuf
);
157 if(cur_offlen
!= mlen
)
158 sendto_one(client_p
, "%s", offbuf
);
162 del_monitor(struct Client
*client_p
, const char *nicks
)
164 struct monitor
*monptr
;
169 if(!dlink_list_length(&client_p
->localClient
->monitor_list
))
172 tmp
= LOCAL_COPY(nicks
);
174 for(name
= strtoken(&p
, tmp
, ","); name
; name
= strtoken(&p
, NULL
, ","))
176 if(EmptyString(name
))
180 if((monptr
= find_monitor(name
, 0)) == NULL
)
183 dlinkFindDestroy(client_p
, &monptr
->users
);
184 dlinkFindDestroy(monptr
, &client_p
->localClient
->monitor_list
);
189 list_monitor(struct Client
*client_p
)
192 struct monitor
*monptr
;
195 int mlen
, arglen
, cur_len
;
197 if(!dlink_list_length(&client_p
->localClient
->monitor_list
))
199 sendto_one(client_p
, form_str(RPL_ENDOFMONLIST
),
200 me
.name
, client_p
->name
);
204 cur_len
= mlen
= sprintf(buf
, form_str(RPL_MONLIST
),
205 me
.name
, client_p
->name
, "");
208 DLINK_FOREACH(ptr
, client_p
->localClient
->monitor_list
.head
)
212 if(cur_len
+ strlen(monptr
->name
) + 1 >= BUFSIZE
-3)
214 sendto_one(client_p
, "%s", buf
);
225 arglen
= sprintf(nbuf
, "%s", monptr
->name
);
230 sendto_one(client_p
, "%s", buf
);
231 sendto_one(client_p
, form_str(RPL_ENDOFMONLIST
),
232 me
.name
, client_p
->name
);
236 show_monitor_status(struct Client
*client_p
)
238 char onbuf
[BUFSIZE
], offbuf
[BUFSIZE
];
239 struct Client
*target_p
;
240 struct monitor
*monptr
;
241 char *onptr
, *offptr
;
242 int cur_onlen
, cur_offlen
;
246 mlen
= cur_onlen
= sprintf(onbuf
, form_str(RPL_MONONLINE
),
247 me
.name
, client_p
->name
, "");
248 cur_offlen
= sprintf(offbuf
, form_str(RPL_MONOFFLINE
),
249 me
.name
, client_p
->name
, "");
251 onptr
= onbuf
+ mlen
;
252 offptr
= offbuf
+ mlen
;
254 DLINK_FOREACH(ptr
, client_p
->localClient
->monitor_list
.head
)
258 if((target_p
= find_named_person(monptr
->name
)) != NULL
)
260 if(cur_onlen
+ strlen(target_p
->name
) +
261 strlen(target_p
->username
) + strlen(target_p
->host
) + 3 >= BUFSIZE
-3)
263 sendto_one(client_p
, "%s", onbuf
);
265 onptr
= onbuf
+ mlen
;
268 if(cur_onlen
!= mlen
)
274 arglen
= sprintf(onptr
, "%s!%s@%s",
275 target_p
->name
, target_p
->username
,
282 if(cur_offlen
+ strlen(monptr
->name
) + 1 >= BUFSIZE
-3)
284 sendto_one(client_p
, "%s", offbuf
);
286 offptr
= offbuf
+ mlen
;
289 if(cur_offlen
!= mlen
)
295 arglen
= sprintf(offptr
, "%s", monptr
->name
);
297 cur_offlen
+= arglen
;
301 if(cur_onlen
!= mlen
)
302 sendto_one(client_p
, "%s", onbuf
);
303 if(cur_offlen
!= mlen
)
304 sendto_one(client_p
, "%s", offbuf
);
308 m_monitor(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
313 if(parc
< 3 || EmptyString(parv
[2]))
315 sendto_one(client_p
, form_str(ERR_NEEDMOREPARAMS
),
316 me
.name
, source_p
->name
, "MONITOR");
320 add_monitor(source_p
, parv
[2]);
323 if(parc
< 3 || EmptyString(parv
[2]))
325 sendto_one(client_p
, form_str(ERR_NEEDMOREPARAMS
),
326 me
.name
, source_p
->name
, "MONITOR");
330 del_monitor(source_p
, parv
[2]);
335 clear_monitor(source_p
);
340 list_monitor(source_p
);
345 show_monitor_status(source_p
);