ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/m_watch.c
Revision: 1230
Committed: Thu Sep 22 19:41:19 2011 UTC (14 years, 10 months ago) by michael
Content type: text/x-csrc
File size: 7449 byte(s)
Log Message:
- cleanup module loader. Make module api more flexible

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

Properties

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