]> jfr.im git - irc/rqf/shadowircd.git/blob - modules/m_monitor.c
Removal of ancient SVN ID's part one
[irc/rqf/shadowircd.git] / modules / m_monitor.c
1 /* modules/m_monitor.c
2 *
3 * Copyright (C) 2005 Lee Hardy <lee@leeh.co.uk>
4 * Copyright (C) 2005 ircd-ratbox development team
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
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.
17 *
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.
29 *
30 */
31
32 #include "stdinc.h"
33 #include "client.h"
34 #include "msg.h"
35 #include "parse.h"
36 #include "modules.h"
37 #include "monitor.h"
38 #include "numeric.h"
39 #include "s_conf.h"
40
41 static int m_monitor(struct Client *, struct Client *, int, const char **);
42
43 struct Message monitor_msgtab = {
44 "MONITOR", 0, 0, 0, MFLG_SLOW,
45 {mg_unreg, {m_monitor, 2}, mg_ignore, mg_ignore, mg_ignore, {m_monitor, 2}}
46 };
47
48 mapi_clist_av1 monitor_clist[] = { &monitor_msgtab, NULL };
49 DECLARE_MODULE_AV1(monitor, NULL, NULL, monitor_clist, NULL, NULL, "$Revision: 312 $");
50
51 static void
52 add_monitor(struct Client *client_p, const char *nicks)
53 {
54 char onbuf[BUFSIZE], offbuf[BUFSIZE];
55 struct Client *target_p;
56 struct monitor *monptr;
57 const char *name;
58 char *tmp;
59 char *p;
60 char *onptr, *offptr;
61 int mlen, arglen;
62 int cur_onlen, cur_offlen;
63
64 /* these two are same length, just diff numeric */
65 cur_offlen = cur_onlen = mlen = sprintf(onbuf, form_str(RPL_MONONLINE),
66 me.name, client_p->name, "");
67 sprintf(offbuf, form_str(RPL_MONOFFLINE),
68 me.name, client_p->name, "");
69
70 onptr = onbuf + mlen;
71 offptr = offbuf + mlen;
72
73 tmp = LOCAL_COPY(nicks);
74
75 for(name = rb_strtok_r(tmp, ",", &p); name; name = rb_strtok_r(NULL, ",", &p))
76 {
77 if(EmptyString(name) || strlen(name) > NICKLEN-1)
78 continue;
79
80 if(rb_dlink_list_length(&client_p->localClient->monitor_list) >=
81 ConfigFileEntry.max_monitor)
82 {
83 char buf[100];
84
85 if(cur_onlen != mlen)
86 sendto_one(client_p, "%s", onbuf);
87 if(cur_offlen != mlen)
88 sendto_one(client_p, "%s", offbuf);
89
90 if(p)
91 rb_snprintf(buf, sizeof(buf), "%s,%s", name, p);
92 else
93 rb_snprintf(buf, sizeof(buf), "%s", name);
94
95 sendto_one(client_p, form_str(ERR_MONLISTFULL),
96 me.name, client_p->name,
97 ConfigFileEntry.max_monitor, buf);
98 return;
99 }
100
101 monptr = find_monitor(name, 1);
102
103 /* already monitoring this nick */
104 if(rb_dlinkFind(client_p, &monptr->users))
105 continue;
106
107 rb_dlinkAddAlloc(client_p, &monptr->users);
108 rb_dlinkAddAlloc(monptr, &client_p->localClient->monitor_list);
109
110 if((target_p = find_named_person(name)) != NULL)
111 {
112 if(cur_onlen + strlen(target_p->name) +
113 strlen(target_p->username) + strlen(target_p->host) + 3 >= BUFSIZE-3)
114 {
115 sendto_one(client_p, "%s", onbuf);
116 cur_onlen = mlen;
117 onptr = onbuf + mlen;
118 }
119
120 if(cur_onlen != mlen)
121 {
122 *onptr++ = ',';
123 cur_onlen++;
124 }
125
126 arglen = sprintf(onptr, "%s!%s@%s",
127 target_p->name, target_p->username,
128 target_p->host);
129 onptr += arglen;
130 cur_onlen += arglen;
131 }
132 else
133 {
134 if(cur_offlen + strlen(name) + 1 >= BUFSIZE-3)
135 {
136 sendto_one(client_p, "%s", offbuf);
137 cur_offlen = mlen;
138 offptr = offbuf + mlen;
139 }
140
141 if(cur_offlen != mlen)
142 {
143 *offptr++ = ',';
144 cur_offlen++;
145 }
146
147 arglen = sprintf(offptr, "%s", name);
148 offptr += arglen;
149 cur_offlen += arglen;
150 }
151 }
152
153 if(cur_onlen != mlen)
154 sendto_one(client_p, "%s", onbuf);
155 if(cur_offlen != mlen)
156 sendto_one(client_p, "%s", offbuf);
157 }
158
159 static void
160 del_monitor(struct Client *client_p, const char *nicks)
161 {
162 struct monitor *monptr;
163 const char *name;
164 char *tmp;
165 char *p;
166
167 if(!rb_dlink_list_length(&client_p->localClient->monitor_list))
168 return;
169
170 tmp = LOCAL_COPY(nicks);
171
172 for(name = rb_strtok_r(tmp, ",", &p); name; name = rb_strtok_r(NULL, ",", &p))
173 {
174 if(EmptyString(name))
175 continue;
176
177 /* not monitored */
178 if((monptr = find_monitor(name, 0)) == NULL)
179 continue;
180
181 rb_dlinkFindDestroy(client_p, &monptr->users);
182 rb_dlinkFindDestroy(monptr, &client_p->localClient->monitor_list);
183 }
184 }
185
186 static void
187 list_monitor(struct Client *client_p)
188 {
189 char buf[BUFSIZE];
190 struct monitor *monptr;
191 char *nbuf;
192 rb_dlink_node *ptr;
193 int mlen, arglen, cur_len;
194
195 if(!rb_dlink_list_length(&client_p->localClient->monitor_list))
196 {
197 sendto_one(client_p, form_str(RPL_ENDOFMONLIST),
198 me.name, client_p->name);
199 return;
200 }
201
202 cur_len = mlen = sprintf(buf, form_str(RPL_MONLIST),
203 me.name, client_p->name, "");
204 nbuf = buf + mlen;
205
206 RB_DLINK_FOREACH(ptr, client_p->localClient->monitor_list.head)
207 {
208 monptr = ptr->data;
209
210 if(cur_len + strlen(monptr->name) + 1 >= BUFSIZE-3)
211 {
212 sendto_one(client_p, "%s", buf);
213 nbuf = buf + mlen;
214 cur_len = mlen;
215 }
216
217 if(cur_len != mlen)
218 {
219 *nbuf++ = ',';
220 cur_len++;
221 }
222
223 arglen = sprintf(nbuf, "%s", monptr->name);
224 cur_len += arglen;
225 nbuf += arglen;
226 }
227
228 sendto_one(client_p, "%s", buf);
229 sendto_one(client_p, form_str(RPL_ENDOFMONLIST),
230 me.name, client_p->name);
231 }
232
233 static void
234 show_monitor_status(struct Client *client_p)
235 {
236 char onbuf[BUFSIZE], offbuf[BUFSIZE];
237 struct Client *target_p;
238 struct monitor *monptr;
239 char *onptr, *offptr;
240 int cur_onlen, cur_offlen;
241 int mlen, arglen;
242 rb_dlink_node *ptr;
243
244 mlen = cur_onlen = sprintf(onbuf, form_str(RPL_MONONLINE),
245 me.name, client_p->name, "");
246 cur_offlen = sprintf(offbuf, form_str(RPL_MONOFFLINE),
247 me.name, client_p->name, "");
248
249 onptr = onbuf + mlen;
250 offptr = offbuf + mlen;
251
252 RB_DLINK_FOREACH(ptr, client_p->localClient->monitor_list.head)
253 {
254 monptr = ptr->data;
255
256 if((target_p = find_named_person(monptr->name)) != NULL)
257 {
258 if(cur_onlen + strlen(target_p->name) +
259 strlen(target_p->username) + strlen(target_p->host) + 3 >= BUFSIZE-3)
260 {
261 sendto_one(client_p, "%s", onbuf);
262 cur_onlen = mlen;
263 onptr = onbuf + mlen;
264 }
265
266 if(cur_onlen != mlen)
267 {
268 *onptr++ = ',';
269 cur_onlen++;
270 }
271
272 arglen = sprintf(onptr, "%s!%s@%s",
273 target_p->name, target_p->username,
274 target_p->host);
275 onptr += arglen;
276 cur_onlen += arglen;
277 }
278 else
279 {
280 if(cur_offlen + strlen(monptr->name) + 1 >= BUFSIZE-3)
281 {
282 sendto_one(client_p, "%s", offbuf);
283 cur_offlen = mlen;
284 offptr = offbuf + mlen;
285 }
286
287 if(cur_offlen != mlen)
288 {
289 *offptr++ = ',';
290 cur_offlen++;
291 }
292
293 arglen = sprintf(offptr, "%s", monptr->name);
294 offptr += arglen;
295 cur_offlen += arglen;
296 }
297 }
298
299 if(cur_onlen != mlen)
300 sendto_one(client_p, "%s", onbuf);
301 if(cur_offlen != mlen)
302 sendto_one(client_p, "%s", offbuf);
303 }
304
305 static int
306 m_monitor(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
307 {
308 switch(parv[1][0])
309 {
310 case '+':
311 if(parc < 3 || EmptyString(parv[2]))
312 {
313 sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
314 me.name, source_p->name, "MONITOR");
315 return 0;
316 }
317
318 add_monitor(source_p, parv[2]);
319 break;
320 case '-':
321 if(parc < 3 || EmptyString(parv[2]))
322 {
323 sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
324 me.name, source_p->name, "MONITOR");
325 return 0;
326 }
327
328 del_monitor(source_p, parv[2]);
329 break;
330
331 case 'C':
332 case 'c':
333 clear_monitor(source_p);
334 break;
335
336 case 'L':
337 case 'l':
338 list_monitor(source_p);
339 break;
340
341 case 'S':
342 case 's':
343 show_monitor_status(source_p);
344 break;
345
346 default:
347 break;
348 }
349
350 return 0;
351 }
352