ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.1.x/modules/m_watch.c
Revision: 1592
Committed: Sat Oct 27 21:02:32 2012 UTC (13 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/m_watch.c
File size: 7406 byte(s)
Log Message:
- Second time's the charm? Moving svnroot/ircd-hybrid-8 to
  svnroot/ircd-hybrid/trunk

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 "sprintf_irc.h"
30     #include "ircd.h"
31     #include "numeric.h"
32 michael 1309 #include "conf.h"
33 michael 876 #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 michael 1241 target_p->host, target_p->tsinfo);
56 michael 876 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 michael 1230
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