ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/ircservices-5.1.24/modules/protocol/banexcept.c
Revision: 3389
Committed: Fri Apr 25 14:12:15 2014 UTC (12 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 5386 byte(s)
Log Message:
- Imported ircservices-5.1.24

File Contents

# User Rev Content
1 michael 3389 /* Ban exception related functions.
2     *
3     * IRC Services is copyright (c) 1996-2009 Andrew Church.
4     * E-mail: <achurch@achurch.org>
5     * Parts written by Andrew Kempe and others.
6     * This program is free but copyrighted software; see the file GPL.txt for
7     * details.
8     */
9    
10     #include "services.h"
11     #include "modules.h"
12     #include "language.h"
13     #include "modules/chanserv/chanserv.h"
14    
15     #include "banexcept.h"
16    
17     /*************************************************************************/
18    
19     static Module *banexcept_module_chanserv;
20    
21     static const char **banexcept_p_s_ChanServ = NULL; /* never used if NULL */
22     #define s_ChanServ (*banexcept_p_s_ChanServ)
23    
24     /*************************************************************************/
25     /*************************************************************************/
26    
27     /* Callback to handle MODE +/-e. */
28    
29     static int banexcept_channel_mode(const char *source, Channel *chan,
30     int modechar, int add, char **av)
31     {
32     if (modechar == 'e') {
33     if (add) {
34     ARRAY_EXTEND(chan->excepts);
35     chan->excepts[chan->excepts_count-1] = sstrdup(av[0]);
36     } else {
37     int i;
38     ARRAY_SEARCH_PLAIN(chan->excepts, av[0], irc_stricmp, i);
39     if (i < chan->excepts_count) {
40     free(chan->excepts[i]);
41     ARRAY_REMOVE(chan->excepts, i);
42     } else {
43     module_log("banexcept: MODE %s -e %s: exception not found",
44     chan->name, *av);
45     }
46     }
47     return 0;
48     }
49     return 0;
50     }
51    
52     /*************************************************************************/
53    
54     /* Callback to handle clearing exceptions for clear_channel(). */
55    
56     static void clear_excepts(const char *sender, Channel *chan, const User *u);
57    
58     static int banexcept_clear_channel(const char *sender, Channel *chan, int what,
59     const void *param)
60     {
61     if (what & (CLEAR_USERS | CLEAR_EXCEPTS))
62     clear_excepts(sender, chan, (what & CLEAR_EXCEPTS) ? param : NULL);
63     return 0;
64     }
65    
66    
67     static void clear_excepts(const char *sender, Channel *chan, const User *u)
68     {
69     int i, count;
70     char **excepts;
71    
72     if (!chan->excepts_count)
73     return;
74     count = chan->excepts_count;
75     excepts = smalloc(sizeof(char *) * count);
76     memcpy(excepts, chan->excepts, sizeof(char *) * count);
77     for (i = 0; i < count; i++) {
78     if (!u || match_usermask(excepts[i], u))
79     set_cmode(sender, chan, "-e", excepts[i]);
80     }
81     free(excepts);
82     }
83    
84     /*************************************************************************/
85    
86     /* Callback to handle ChanServ CLEAR EXCEPTIONS. */
87    
88     static int banexcept_cs_clear(User *u, Channel *c, const char *what)
89     {
90     if (stricmp(what, "EXCEPTIONS") == 0) {
91     clear_excepts(s_ChanServ, c, NULL);
92     set_cmode(NULL, c);
93     notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTIONS, c->name);
94     return 1;
95     }
96     return 0;
97     }
98    
99     /*************************************************************************/
100     /*************************************************************************/
101    
102     /* Callback to watch for modules being loaded. */
103    
104     static int banexcept_load_module(Module *mod, const char *name)
105     {
106     if (strcmp(name, "chanserv/main") == 0) {
107     banexcept_module_chanserv = mod;
108     banexcept_p_s_ChanServ = get_module_symbol(mod, "s_ChanServ");
109     if (banexcept_p_s_ChanServ) {
110     if (!(add_callback(mod, "CLEAR", banexcept_cs_clear)))
111     module_log("banexcept: Unable to add ChanServ CLEAR callback");
112     } else {
113     module_log("banexcept: Symbol `s_ChanServ' not found, CLEAR"
114     " EXCEPTIONS will not be available");
115     }
116     }
117     return 0;
118     }
119    
120     /*************************************************************************/
121    
122     /* Callback to watch for modules being unloaded. */
123    
124     static int banexcept_unload_module(Module *mod)
125     {
126     if (mod == banexcept_module_chanserv) {
127     banexcept_p_s_ChanServ = NULL;
128     banexcept_module_chanserv = NULL;
129     }
130     return 0;
131     }
132    
133     /*************************************************************************/
134     /*************************************************************************/
135    
136     int init_banexcept(void)
137     {
138     if (!add_callback(NULL, "channel MODE", banexcept_channel_mode)
139     || !add_callback(NULL, "clear channel", banexcept_clear_channel)
140     || !add_callback(NULL, "load module", banexcept_load_module)
141     || !add_callback(NULL, "unload module", banexcept_unload_module)
142     ) {
143     module_log("banexcept: Unable to add callbacks");
144     exit_banexcept();
145     return 0;
146     }
147     protocol_features |= PF_BANEXCEPT;
148     return 1;
149     }
150    
151     /*************************************************************************/
152    
153     void exit_banexcept(void)
154     {
155     remove_callback(NULL, "unload module", banexcept_unload_module);
156     remove_callback(NULL, "load module", banexcept_load_module);
157     remove_callback(NULL, "clear channel", banexcept_clear_channel);
158     remove_callback(NULL, "channel MODE", banexcept_channel_mode);
159     }
160    
161     /*************************************************************************/
162    
163     #undef s_ChanServ
164    
165     /*
166     * Local variables:
167     * c-file-style: "stroustrup"
168     * c-file-offsets: ((case-label . *) (statement-case-intro . *))
169     * indent-tabs-mode: nil
170     * End:
171     *
172     * vim: expandtab shiftwidth=4:
173     */