ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/m_watch.c
Revision: 1309
Committed: Sun Mar 25 11:24:18 2012 UTC (12 years ago) by michael
Content type: text/x-csrc
File size: 7406 byte(s)
Log Message:
- renaming files:

  ircd_parser.y -> conf_parser.y
  ircd_lexer.l  -> conf_lexer.l
  s_conf.c      -> conf.c
  s_conf.h      -> conf.h
  s_log.c       -> log.c
  s_log.h       -> log.h

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

Properties

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