ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_watch.c
Revision: 1834
Committed: Fri Apr 19 19:50:27 2013 UTC (13 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 7381 byte(s)
Log Message:
- Revert to -r1831

File Contents

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

Properties

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