ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_watch.c
Revision: 1121
Committed: Sun Jan 9 11:03:03 2011 UTC (15 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.3/modules/m_watch.c
File size: 7330 byte(s)
Error occurred while calculating annotation data.
Log Message:
- removed all instances of STATIC_MODULES since we don't have
  static modules anymore
- removed m_mkpasswd module from contrib

File Contents

# Content
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 "irc_string.h"
30 #include "sprintf_irc.h"
31 #include "ircd.h"
32 #include "numeric.h"
33 #include "s_conf.h"
34 #include "send.h"
35 #include "msg.h"
36 #include "parse.h"
37 #include "modules.h"
38 #include "s_user.h"
39 #include "watch.h"
40
41 static void m_watch(struct Client *, struct Client *, int, char *[]);
42
43 struct Message watch_msgtab = {
44 "WATCH", 0, 0, 0, 0, MFLG_SLOW, 0,
45 { m_unregistered, m_watch, m_ignore, m_ignore, m_watch, m_ignore }
46 };
47
48 void
49 _modinit(void)
50 {
51 mod_add_cmd(&watch_msgtab);
52 add_isupport("WATCH", NULL, ConfigFileEntry.max_watch);
53 }
54
55 void
56 _moddeinit(void)
57 {
58 mod_del_cmd(&watch_msgtab);
59 delete_isupport("WATCH");
60 }
61
62 const char *_version = "$Revision$";
63
64 /*
65 * RPL_NOWON - Online at the moment (Succesfully added to WATCH-list)
66 * RPL_NOWOFF - Offline at the moment (Succesfully added to WATCH-list)
67 * RPL_WATCHOFF - Succesfully removed from WATCH-list.
68 * ERR_TOOMANYWATCH - Take a guess :> Too many WATCH entries.
69 */
70 static void
71 show_watch(struct Client *client_p, const char *name,
72 unsigned int rpl1, unsigned int rpl2)
73 {
74 const struct Client *target_p = NULL;
75
76 if ((target_p = find_person(client_p, name)))
77 sendto_one(client_p, form_str(rpl1), me.name, client_p->name,
78 target_p->name, target_p->username,
79 target_p->host, target_p->lasttime);
80 else
81 sendto_one(client_p, form_str(rpl2), me.name, client_p->name,
82 name, "*", "*", 0);
83 }
84
85 /*
86 * m_watch()
87 *
88 * parv[0] = sender prefix
89 * parv[1] = watch options
90 */
91 static void
92 m_watch(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
93 {
94 dlink_node *ptr = NULL;
95 char *s = NULL;
96 char *p = NULL;
97 char *user;
98 char def[2] = "l";
99 unsigned int list_requested = 0;
100
101 /*
102 * Default to 'l' - list who's currently online
103 */
104 if (parc < 2)
105 parv[1] = def;
106
107 for (s = strtoken(&p, parv[1], ", "); s;
108 s = strtoken(&p, NULL, ", "))
109 {
110 if ((user = strchr(s, '!')))
111 *user++ = '\0'; /* Not used */
112
113 /*
114 * Prefix of "+", they want to add a name to their WATCH
115 * list.
116 */
117 if (*s == '+')
118 {
119 if (*(s + 1) != '\0')
120 {
121 if (dlink_list_length(&source_p->localClient->watches) >=
122 ConfigFileEntry.max_watch)
123 {
124 sendto_one(source_p, form_str(ERR_TOOMANYWATCH), me.name,
125 source_p->name, s + 1, ConfigFileEntry.max_watch);
126 continue;
127 }
128
129 watch_add_to_hash_table(s + 1, source_p);
130 }
131
132 show_watch(source_p, s + 1, RPL_NOWON, RPL_NOWOFF);
133 continue;
134 }
135
136 /*
137 * Prefix of "-", coward wants to remove somebody from their
138 * WATCH list. So do it. :-)
139 */
140 if (*s == '-')
141 {
142 watch_del_from_hash_table(s + 1, source_p);
143 show_watch(source_p, s + 1, RPL_WATCHOFF, RPL_WATCHOFF);
144 continue;
145 }
146
147 /*
148 * Fancy "C" or "c", they want to nuke their WATCH list and start
149 * over, so be it.
150 */
151 if (*s == 'C' || *s == 'c')
152 {
153 watch_del_watch_list(source_p);
154 continue;
155 }
156
157 /*
158 * Now comes the fun stuff, "S" or "s" returns a status report of
159 * their WATCH list. I imagine this could be CPU intensive if
160 * it's done alot, perhaps an auto-lag on this?
161 */
162 if (*s == 'S' || *s == 's')
163 {
164 char buf[IRCD_BUFSIZE] = { '\0' };
165 const struct Watch *anptr = NULL;
166 unsigned int count = 0;
167
168 if (list_requested & 0x1)
169 continue;
170
171 list_requested |= 0x1;
172
173 /*
174 * Send a list of how many users they have on their WATCH list
175 * and how many WATCH lists they are on.
176 */
177 if ((anptr = watch_find_hash(source_p->name)))
178 count = dlink_list_length(&anptr->watched_by);
179
180 sendto_one(source_p, form_str(RPL_WATCHSTAT),
181 me.name, source_p->name,
182 dlink_list_length(&source_p->localClient->watches), count);
183
184 /*
185 * Send a list of everybody in their WATCH list. Be careful
186 * not to buffer overflow.
187 */
188 if ((ptr = source_p->localClient->watches.head) == NULL)
189 {
190 sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST),
191 me.name, source_p->name, *s);
192 continue;
193 }
194
195 anptr = ptr->data;
196 strlcpy(buf, anptr->nick, sizeof(buf));
197
198 count = strlen(source_p->name) + strlen(me.name) + 10 +
199 strlen(buf);
200
201 while ((ptr = ptr->next))
202 {
203 anptr = ptr->data;
204
205 if (count + strlen(anptr->nick) + 1 > IRCD_BUFSIZE - 2)
206 {
207 sendto_one(source_p, form_str(RPL_WATCHLIST),
208 me.name, source_p->name, buf);
209 buf[0] = '\0';
210 count = strlen(source_p->name) + strlen(me.name) + 10;
211 }
212
213 strcat(buf, " ");
214 strcat(buf, anptr->nick);
215 count += (strlen(anptr->nick) + 1);
216 }
217
218 sendto_one(source_p, form_str(RPL_WATCHLIST),
219 me.name, source_p->name, buf);
220 sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST),
221 me.name, source_p->name, *s);
222 continue;
223 }
224
225 /*
226 * Well that was fun, NOT. Now they want a list of everybody in
227 * their WATCH list AND if they are online or offline? Sheesh,
228 * greedy aren't we?
229 */
230 if (*s == 'L' || *s == 'l')
231 {
232 const struct Client *target_p = NULL;
233
234 if (list_requested & 0x2)
235 continue;
236
237 list_requested |= 0x2;
238
239 DLINK_FOREACH(ptr, source_p->localClient->watches.head)
240 {
241 const struct Watch *anptr = ptr->data;
242
243 if ((target_p = find_person(source_p, anptr->nick)))
244 sendto_one(source_p, form_str(RPL_NOWON), me.name, source_p->name,
245 target_p->name, target_p->username,
246 target_p->host, target_p->tsinfo);
247 /*
248 * But actually, only show them offline if it's a capital
249 * 'L' (full list wanted).
250 */
251 else if (*s == 'L')
252 sendto_one(source_p, form_str(RPL_NOWOFF), me.name,
253 source_p->name, anptr->nick,
254 "*", "*", anptr->lasttime);
255 }
256
257 sendto_one(source_p, form_str(RPL_ENDOFWATCHLIST),
258 me.name, source_p->name, *s);
259 continue;
260 }
261
262 /* Hmm.. unknown prefix character.. Ignore it. :-) */
263 }
264 }

Properties

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