ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_watch.c
Revision: 3109
Committed: Thu Mar 6 19:25:12 2014 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 7111 byte(s)
Log Message:
- Applied Adam's sendto_one_numeric() changes

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     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * 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     #include "s_user.h"
38     #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     show_watch(struct Client *client_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     if ((target_p = find_person(client_p, name)))
54 michael 3109 sendto_one_numeric(client_p, &me, rpl1,
55     target_p->name, target_p->username,
56     target_p->host, target_p->tsinfo);
57 michael 876 else
58 michael 3109 sendto_one_numeric(client_p, &me, rpl2, name, "*", "*", 0);
59 michael 876 }
60    
61     /*
62     * m_watch()
63     *
64 michael 3096 * parv[0] = command
65 michael 876 * parv[1] = watch options
66     */
67 michael 2820 static int
68 michael 876 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 michael 3109 sendto_one_numeric(source_p, &me, ERR_TOOMANYWATCH, s + 1, ConfigFileEntry.max_watch);
101 michael 876 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 3109 sendto_one_numeric(source_p, &me, RPL_WATCHSTAT,
156 michael 876 dlink_list_length(&source_p->localClient->watches), count);
157    
158     /*
159     * Send a list of everybody in their WATCH list. Be careful
160     * not to buffer overflow.
161     */
162     if ((ptr = source_p->localClient->watches.head) == NULL)
163     {
164 michael 3109 sendto_one_numeric(source_p, &me, RPL_ENDOFWATCHLIST, *s);
165 michael 876 continue;
166     }
167    
168     anptr = ptr->data;
169     strlcpy(buf, anptr->nick, sizeof(buf));
170    
171     count = strlen(source_p->name) + strlen(me.name) + 10 +
172     strlen(buf);
173    
174     while ((ptr = ptr->next))
175     {
176     anptr = ptr->data;
177    
178     if (count + strlen(anptr->nick) + 1 > IRCD_BUFSIZE - 2)
179     {
180 michael 3109 sendto_one_numeric(source_p, &me, RPL_WATCHLIST, buf);
181 michael 876 buf[0] = '\0';
182     count = strlen(source_p->name) + strlen(me.name) + 10;
183     }
184    
185     strcat(buf, " ");
186     strcat(buf, anptr->nick);
187     count += (strlen(anptr->nick) + 1);
188     }
189    
190 michael 3109 sendto_one_numeric(source_p, &me, RPL_WATCHLIST, buf);
191     sendto_one_numeric(source_p, &me, RPL_ENDOFWATCHLIST, *s);
192 michael 876 continue;
193     }
194    
195     /*
196     * Well that was fun, NOT. Now they want a list of everybody in
197     * their WATCH list AND if they are online or offline? Sheesh,
198     * greedy aren't we?
199     */
200     if (*s == 'L' || *s == 'l')
201     {
202     const struct Client *target_p = NULL;
203    
204     if (list_requested & 0x2)
205     continue;
206    
207     list_requested |= 0x2;
208    
209     DLINK_FOREACH(ptr, source_p->localClient->watches.head)
210     {
211     const struct Watch *anptr = ptr->data;
212    
213     if ((target_p = find_person(source_p, anptr->nick)))
214 michael 3109 sendto_one_numeric(source_p, &me, RPL_NOWON,
215     target_p->name, target_p->username,
216     target_p->host, target_p->tsinfo);
217    
218 michael 876 /*
219     * But actually, only show them offline if it's a capital
220     * 'L' (full list wanted).
221     */
222     else if (*s == 'L')
223 michael 3109 sendto_one_numeric(source_p, &me, RPL_NOWOFF, anptr->nick,
224     "*", "*", anptr->lasttime);
225 michael 876 }
226    
227 michael 3109 sendto_one_numeric(source_p, &me, RPL_ENDOFWATCHLIST, *s);
228 michael 876 continue;
229     }
230    
231     /* Hmm.. unknown prefix character.. Ignore it. :-) */
232     }
233 michael 2820
234     return 0;
235 michael 876 }
236 michael 1230
237 michael 2820 static struct Message watch_msgtab =
238     {
239 michael 1230 "WATCH", 0, 0, 0, 1, MFLG_SLOW, 0,
240     { m_unregistered, m_watch, m_ignore, m_ignore, m_watch, m_ignore }
241     };
242    
243     static void
244     module_init(void)
245     {
246     mod_add_cmd(&watch_msgtab);
247     add_isupport("WATCH", NULL, ConfigFileEntry.max_watch);
248     }
249    
250     static void
251     module_exit(void)
252     {
253     mod_del_cmd(&watch_msgtab);
254     delete_isupport("WATCH");
255     }
256    
257 michael 2820 struct module module_entry =
258     {
259 michael 1230 .node = { NULL, NULL, NULL },
260     .name = NULL,
261     .version = "$Revision$",
262     .handle = NULL,
263     .modinit = module_init,
264     .modexit = module_exit,
265     .flags = 0
266     };

Properties

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