/[svn]/ircd-hybrid-7.2/modules/m_watch.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/modules/m_watch.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 953 - (show annotations)
Sun Jul 26 21:22:42 2009 UTC (10 years ago) by michael
File MIME type: text/x-chdr
File size: 7400 byte(s)
- propset keywords

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_watch.c: Maintains notify list
4 *
5 * Copyright (C) 1997 Jukka Santala (Donwulff)
6 * Copyright (C) 2005 by the Hybrid Development Team.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id$
24 */
25
26 #include "stdinc.h"
27 #include "handlers.h"
28 #include "client.h"
29 #include "common.h"
30 #include "irc_string.h"
31 #include "sprintf_irc.h"
32 #include "ircd.h"
33 #include "numeric.h"
34 #include "s_conf.h"
35 #include "restart.h"
36 #include "send.h"
37 #include "msg.h"
38 #include "parse.h"
39 #include "modules.h"
40 #include "s_user.h"
41 #include "watch.h"
42
43 static void m_watch(struct Client *, struct Client *, int, char *[]);
44
45 struct Message watch_msgtab = {
46 "WATCH", 0, 0, 0, 0, MFLG_SLOW, 0,
47 { m_unregistered, m_watch, m_watch, m_ignore, m_watch, m_ignore }
48 };
49
50 #ifndef STATIC_MODULES
51 void
52 _modinit(void)
53 {
54 mod_add_cmd(&watch_msgtab);
55 add_isupport("WATCH", NULL, ConfigFileEntry.max_watch);
56 }
57
58 void
59 _moddeinit(void)
60 {
61 mod_del_cmd(&watch_msgtab);
62 delete_isupport("WATCH");
63 }
64
65 const char *_version = "$Revision$";
66 #endif
67
68 /*
69 * RPL_NOWON - Online at the moment (Succesfully added to WATCH-list)
70 * RPL_NOWOFF - Offline at the moment (Succesfully added to WATCH-list)
71 * RPL_WATCHOFF - Succesfully removed from WATCH-list.
72 * ERR_TOOMANYWATCH - Take a guess :> Too many WATCH entries.
73 */
74 static void
75 show_watch(struct Client *client_p, const char *name,
76 unsigned int rpl1, unsigned int rpl2)
77 {
78 const struct Client *target_p = NULL;
79
80 if ((target_p = find_person(client_p, name)))
81 sendto_one(client_p, form_str(rpl1), me.name, client_p->name,
82 target_p->name, target_p->username,
83 target_p->host, target_p->lasttime);
84 else
85 sendto_one(client_p, form_str(rpl2), me.name, client_p->name,
86 name, "*", "*", 0);
87 }
88
89 /*
90 * m_watch()
91 *
92 * parv[0] = sender prefix
93 * parv[1] = watch options
94 */
95 static void
96 m_watch(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
97 {
98 dlink_node *ptr = NULL;
99 char *s = NULL;
100 char *p = NULL;
101 char *user;
102 char def[2] = "l";
103 unsigned int list_requested = 0;
104
105 /*
106 * Default to 'l' - list who's currently online
107 */
108 if (parc < 2)
109 parv[1] = def;
110
111 for (s = strtoken(&p, parv[1], ", "); s;
112 s = strtoken(&p, NULL, ", "))
113 {
114 if ((user = strchr(s, '!')))
115 *user++ = '\0'; /* Not used */
116
117 /*
118 * Prefix of "+", they want to add a name to their WATCH
119 * list.
120 */
121 if (*s == '+')
122 {
123 if (*(s + 1) != '\0')
124 {
125 if (dlink_list_length(&source_p->localClient->watches) >=
126 ConfigFileEntry.max_watch)
127 {
128 sendto_one(source_p, form_str(ERR_TOOMANYWATCH), me.name,
129 source_p->name, s + 1, ConfigFileEntry.max_watch);
130 continue;
131 }
132
133 watch_add_to_hash_table(s + 1, source_p);
134 }
135
136 show_watch(source_p, s + 1, RPL_NOWON, RPL_NOWOFF);
137 continue;
138 }
139
140 /*
141 * Prefix of "-", coward wants to remove somebody from their
142 * WATCH list. So do it. :-)
143 */
144 if (*s == '-')
145 {
146 watch_del_from_hash_table(s + 1, source_p);
147 show_watch(source_p, s + 1, RPL_WATCHOFF, RPL_WATCHOFF);
148 continue;
149 }
150
151 /*
152 * Fancy "C" or "c", they want to nuke their WATCH list and start
153 * over, so be it.
154 */
155 if (*s == 'C' || *s == 'c')
156 {
157 watch_del_watch_list(source_p);
158 continue;
159 }
160
161 /*
162 * Now comes the fun stuff, "S" or "s" returns a status report of
163 * their WATCH list. I imagine this could be CPU intensive if
164 * it's done alot, perhaps an auto-lag on this?
165 */
166 if (*s == 'S' || *s == 's')
167 {
168 char buf[IRCD_BUFSIZE] = { '\0' };
169 const struct Watch *anptr = NULL;
170 unsigned int count = 0;
171
172 if (list_requested & 0x1)
173 continue;
174
175 list_requested |= 0x1;
176
177 /*
178 * Send a list of how many users they have on their WATCH list
179 * and how many WATCH lists they are on.
180 */
181 if ((anptr = watch_find_hash(source_p->name)))
182 count = dlink_list_length(&anptr->watched_by);
183
184 sendto_one(source_p, form_str(RPL_WATCHSTAT),
185 me.name, source_p->name,
186 dlink_list_length(&source_p->localClient->watches), count);
187
188 /*
189 * Send a list of everybody in their WATCH list. Be careful
190 * not to buffer overflow.
191 */
192 if ((ptr = source_p->localClient->watches.head) == NULL)
193 {
194 sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST),
195 me.name, source_p->name, *s);
196 continue;
197 }
198
199 anptr = ptr->data;
200 strlcpy(buf, anptr->nick, sizeof(buf));
201
202 count = strlen(source_p->name) + strlen(me.name) + 10 +
203 strlen(buf);
204
205 while ((ptr = ptr->next))
206 {
207 anptr = ptr->data;
208
209 if (count + strlen(anptr->nick) + 1 > IRCD_BUFSIZE - 2)
210 {
211 sendto_one(source_p, form_str(RPL_WATCHLIST),
212 me.name, source_p->name, buf);
213 buf[0] = '\0';
214 count = strlen(source_p->name) + strlen(me.name) + 10;
215 }
216
217 strcat(buf, " ");
218 strcat(buf, anptr->nick);
219 count += (strlen(anptr->nick) + 1);
220 }
221
222 sendto_one(source_p, form_str(RPL_WATCHLIST),
223 me.name, source_p->name, buf);
224 sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST),
225 me.name, source_p->name, *s);
226 continue;
227 }
228
229 /*
230 * Well that was fun, NOT. Now they want a list of everybody in
231 * their WATCH list AND if they are online or offline? Sheesh,
232 * greedy aren't we?
233 */
234 if (*s == 'L' || *s == 'l')
235 {
236 const struct Client *target_p = NULL;
237
238 if (list_requested & 0x2)
239 continue;
240
241 list_requested |= 0x2;
242
243 DLINK_FOREACH(ptr, source_p->localClient->watches.head)
244 {
245 const struct Watch *anptr = ptr->data;
246
247 if ((target_p = find_person(source_p, anptr->nick)))
248 sendto_one(source_p, form_str(RPL_NOWON), me.name, source_p->name,
249 target_p->name, target_p->username,
250 target_p->host, target_p->tsinfo);
251 /*
252 * But actually, only show them offline if it's a capital
253 * 'L' (full list wanted).
254 */
255 else if (*s == 'L')
256 sendto_one(source_p, form_str(RPL_NOWOFF), me.name,
257 source_p->name, anptr->nick,
258 "*", "*", anptr->lasttime);
259 }
260
261 sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST),
262 me.name, source_p->name, *s);
263 continue;
264 }
265
266 /* Hmm.. unknown prefix character.. Ignore it. :-) */
267 }
268 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26