ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_watch.c
Revision: 4588
Committed: Tue Aug 26 15:59:07 2014 UTC (11 years ago) by michael
Content type: text/x-csrc
File size: 7548 byte(s)
Log Message:
- Renamed 'localClient' Client structure member to just 'connection'

File Contents

# User Rev Content
1 michael 876 /*
2 michael 2820 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 michael 876 *
4 michael 2820 * Copyright (c) 1997 Jukka Santala (Donwulff)
5     * Copyright (c) 2000-2014 ircd-hybrid development team
6 michael 876 *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20 michael 876 * USA
21     */
22    
23 michael 2820 /*! \file m_watch.c
24     * \brief Includes required functions for processing the WATCH command.
25     * \version $Id$
26     */
27    
28 michael 876 #include "stdinc.h"
29     #include "client.h"
30     #include "irc_string.h"
31     #include "ircd.h"
32     #include "numeric.h"
33 michael 1309 #include "conf.h"
34 michael 876 #include "send.h"
35     #include "parse.h"
36     #include "modules.h"
37 michael 3347 #include "user.h"
38 michael 876 #include "watch.h"
39    
40    
41     /*
42     * RPL_NOWON - Online at the moment (Succesfully added to WATCH-list)
43     * RPL_NOWOFF - Offline at the moment (Succesfully added to WATCH-list)
44     * RPL_WATCHOFF - Succesfully removed from WATCH-list.
45     * ERR_TOOMANYWATCH - Take a guess :> Too many WATCH entries.
46     */
47     static void
48 michael 3156 show_watch(struct Client *source_p, const char *name,
49 michael 3109 enum irc_numerics rpl1, enum irc_numerics rpl2)
50 michael 876 {
51     const struct Client *target_p = NULL;
52    
53 michael 3156 if ((target_p = find_person(source_p, name)))
54     sendto_one_numeric(source_p, &me, rpl1,
55 michael 3109 target_p->name, target_p->username,
56     target_p->host, target_p->tsinfo);
57 michael 876 else
58 michael 3156 sendto_one_numeric(source_p, &me, rpl2, name, "*", "*", 0);
59 michael 876 }
60    
61 michael 3294 /*! \brief WATCH command handler
62 michael 876 *
63 michael 3294 * \param source_p Pointer to allocated Client struct from which the message
64     * originally comes from. This can be a local or remote client.
65     * \param parc Integer holding the number of supplied arguments.
66     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
67     * pointers.
68     * \note Valid arguments for this command are:
69     * - parv[0] = command
70     * - parv[1] = watch options
71 michael 876 */
72 michael 2820 static int
73 michael 3156 m_watch(struct Client *source_p, int parc, char *parv[])
74 michael 876 {
75     dlink_node *ptr = NULL;
76     char *s = NULL;
77     char *p = NULL;
78     char *user;
79     char def[2] = "l";
80     unsigned int list_requested = 0;
81    
82     /*
83     * Default to 'l' - list who's currently online
84     */
85     if (parc < 2)
86     parv[1] = def;
87    
88     for (s = strtoken(&p, parv[1], ", "); s;
89     s = strtoken(&p, NULL, ", "))
90     {
91     if ((user = strchr(s, '!')))
92     *user++ = '\0'; /* Not used */
93    
94     /*
95     * Prefix of "+", they want to add a name to their WATCH
96     * list.
97     */
98     if (*s == '+')
99     {
100 michael 3368 if (*(s + 1))
101 michael 876 {
102 michael 4588 if (dlink_list_length(&source_p->connection->watches) >=
103 michael 4340 ConfigGeneral.max_watch)
104 michael 876 {
105 michael 4340 sendto_one_numeric(source_p, &me, ERR_TOOMANYWATCH, s + 1, ConfigGeneral.max_watch);
106 michael 876 continue;
107     }
108    
109 michael 3424 if (valid_nickname(s + 1, 1))
110     watch_add_to_hash_table(s + 1, source_p);
111 michael 876 }
112    
113     show_watch(source_p, s + 1, RPL_NOWON, RPL_NOWOFF);
114     continue;
115     }
116    
117     /*
118     * Prefix of "-", coward wants to remove somebody from their
119     * WATCH list. So do it. :-)
120     */
121     if (*s == '-')
122     {
123     watch_del_from_hash_table(s + 1, source_p);
124     show_watch(source_p, s + 1, RPL_WATCHOFF, RPL_WATCHOFF);
125     continue;
126     }
127    
128     /*
129     * Fancy "C" or "c", they want to nuke their WATCH list and start
130     * over, so be it.
131     */
132     if (*s == 'C' || *s == 'c')
133     {
134     watch_del_watch_list(source_p);
135     continue;
136     }
137    
138     /*
139     * Now comes the fun stuff, "S" or "s" returns a status report of
140 michael 3294 * their WATCH list. I imagine this could be CPU intensive if
141 michael 876 * it's done alot, perhaps an auto-lag on this?
142     */
143     if (*s == 'S' || *s == 's')
144     {
145 michael 3213 char buf[IRCD_BUFSIZE] = "";
146 michael 876 const struct Watch *anptr = NULL;
147     unsigned int count = 0;
148    
149     if (list_requested & 0x1)
150     continue;
151    
152     list_requested |= 0x1;
153    
154     /*
155     * Send a list of how many users they have on their WATCH list
156     * and how many WATCH lists they are on.
157     */
158     if ((anptr = watch_find_hash(source_p->name)))
159     count = dlink_list_length(&anptr->watched_by);
160    
161 michael 3109 sendto_one_numeric(source_p, &me, RPL_WATCHSTAT,
162 michael 4588 dlink_list_length(&source_p->connection->watches), count);
163 michael 876
164     /*
165 michael 3294 * Send a list of everybody in their WATCH list. Be careful
166 michael 876 * not to buffer overflow.
167     */
168 michael 4588 if ((ptr = source_p->connection->watches.head) == NULL)
169 michael 876 {
170 michael 3109 sendto_one_numeric(source_p, &me, RPL_ENDOFWATCHLIST, *s);
171 michael 876 continue;
172     }
173    
174     anptr = ptr->data;
175     strlcpy(buf, anptr->nick, sizeof(buf));
176    
177     count = strlen(source_p->name) + strlen(me.name) + 10 +
178     strlen(buf);
179    
180     while ((ptr = ptr->next))
181     {
182     anptr = ptr->data;
183    
184     if (count + strlen(anptr->nick) + 1 > IRCD_BUFSIZE - 2)
185     {
186 michael 3109 sendto_one_numeric(source_p, &me, RPL_WATCHLIST, buf);
187 michael 876 buf[0] = '\0';
188     count = strlen(source_p->name) + strlen(me.name) + 10;
189     }
190    
191 michael 3213 strlcat(buf, " ", sizeof(buf));
192     strlcat(buf, anptr->nick, sizeof(buf));
193 michael 876 count += (strlen(anptr->nick) + 1);
194     }
195    
196 michael 3109 sendto_one_numeric(source_p, &me, RPL_WATCHLIST, buf);
197     sendto_one_numeric(source_p, &me, RPL_ENDOFWATCHLIST, *s);
198 michael 876 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 michael 4588 DLINK_FOREACH(ptr, source_p->connection->watches.head)
216 michael 876 {
217     const struct Watch *anptr = ptr->data;
218    
219     if ((target_p = find_person(source_p, anptr->nick)))
220 michael 3109 sendto_one_numeric(source_p, &me, RPL_NOWON,
221     target_p->name, target_p->username,
222     target_p->host, target_p->tsinfo);
223    
224 michael 876 /*
225     * But actually, only show them offline if it's a capital
226     * 'L' (full list wanted).
227     */
228     else if (*s == 'L')
229 michael 3109 sendto_one_numeric(source_p, &me, RPL_NOWOFF, anptr->nick,
230     "*", "*", anptr->lasttime);
231 michael 876 }
232    
233 michael 3109 sendto_one_numeric(source_p, &me, RPL_ENDOFWATCHLIST, *s);
234 michael 876 continue;
235     }
236    
237     /* Hmm.. unknown prefix character.. Ignore it. :-) */
238     }
239 michael 2820
240     return 0;
241 michael 876 }
242 michael 1230
243 michael 2820 static struct Message watch_msgtab =
244     {
245 michael 4545 "WATCH", NULL, 0, 0, 0, 1, MFLG_SLOW, 0,
246 michael 1230 { m_unregistered, m_watch, m_ignore, m_ignore, m_watch, m_ignore }
247     };
248    
249     static void
250     module_init(void)
251     {
252     mod_add_cmd(&watch_msgtab);
253 michael 4340 add_isupport("WATCH", NULL, ConfigGeneral.max_watch);
254 michael 1230 }
255    
256     static void
257     module_exit(void)
258     {
259     mod_del_cmd(&watch_msgtab);
260     delete_isupport("WATCH");
261     }
262    
263 michael 2820 struct module module_entry =
264     {
265 michael 1230 .node = { NULL, NULL, NULL },
266     .name = NULL,
267     .version = "$Revision$",
268     .handle = NULL,
269     .modinit = module_init,
270     .modexit = module_exit,
271     .flags = 0
272     };

Properties

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