ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_mode.c
Revision: 4545
Committed: Fri Aug 22 08:46:13 2014 UTC (11 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 6973 byte(s)
Log Message:
- Implemented pseudo {} blocks (service aliases)
- Fixed compile warnings with -Wmissing-field-initializers

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2820 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 2820 * Copyright (c) 1997-2014 ircd-hybrid development team
5 adx 30 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19     * USA
20     */
21    
22 michael 2820 /*! \file m_mode.c
23 michael 3356 * \brief Includes required functions for processing the MODE command.
24 michael 2820 * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "channel.h"
30     #include "channel_mode.h"
31     #include "client.h"
32     #include "hash.h"
33     #include "irc_string.h"
34     #include "ircd.h"
35     #include "numeric.h"
36 michael 3347 #include "user.h"
37 michael 1309 #include "conf.h"
38 michael 3347 #include "server.h"
39 adx 30 #include "send.h"
40     #include "parse.h"
41     #include "modules.h"
42     #include "packet.h"
43    
44    
45 michael 3313 /* set_user_mode()
46     *
47     * added 15/10/91 By Darren Reed.
48     * parv[0] - command
49     * parv[1] - username to change mode for
50     * parv[2] - modes to change
51     */
52     static void
53     set_user_mode(struct Client *source_p, const int parc, char *parv[])
54     {
55 michael 3539 unsigned int mode = 0, setmodes = 0;
56 michael 3314 struct Client *target_p = NULL;
57 michael 3539 int what = MODE_ADD, badmode = 0;
58 michael 3313
59     if ((target_p = find_person(source_p, parv[1])) == NULL)
60     {
61     if (MyConnect(source_p))
62     sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
63     return;
64     }
65    
66     if (source_p != target_p)
67     {
68     sendto_one_numeric(source_p, &me, ERR_USERSDONTMATCH);
69     return;
70     }
71    
72     if (parc < 3)
73     {
74 michael 3664 char buf[IRCD_BUFSIZE] = "";
75 michael 3314 char *m = buf;
76 michael 3313 *m++ = '+';
77    
78 michael 3314 for (unsigned int i = 0; i < 128; ++i)
79 michael 3313 if (HasUMode(source_p, user_modes[i]))
80     *m++ = (char)i;
81     *m = '\0';
82    
83     sendto_one_numeric(source_p, &me, RPL_UMODEIS, buf);
84     return;
85     }
86    
87 michael 3539 /* Find modes already set for user */
88     setmodes = source_p->umodes;
89 michael 3313
90     /* parse mode change string(s) */
91 michael 3314 for (char **p = &parv[2]; p && *p; ++p)
92 michael 3313 {
93 michael 3314 for (const char *m = *p; *m; ++m)
94 michael 3313 {
95     switch (*m)
96     {
97     case '+':
98     what = MODE_ADD;
99     break;
100     case '-':
101     what = MODE_DEL;
102     break;
103     case 'o':
104     if (what == MODE_ADD)
105     {
106     if (!MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER))
107     {
108     ++Count.oper;
109     SetOper(source_p);
110     }
111     }
112     else
113     {
114     if (!HasUMode(source_p, UMODE_OPER))
115     break;
116    
117     ClearOper(source_p);
118 michael 3477 --Count.oper;
119 michael 3313
120     if (MyConnect(source_p))
121     {
122     dlink_node *ptr = NULL;
123    
124     detach_conf(source_p, CONF_OPER);
125     ClrOFlag(source_p);
126 michael 4340 DelUMode(source_p, ConfigGeneral.oper_only_umodes);
127 michael 3313
128     if ((ptr = dlinkFindDelete(&oper_list, source_p)))
129     free_dlink_node(ptr);
130     }
131     }
132    
133     break;
134    
135     case 'S': /* Only servers may set +S in a burst */
136     case 'W': /* Only servers may set +W in a burst */
137     case 'r': /* Only services may set +r */
138     case 'x': /* Only services may set +x */
139     break;
140    
141     default:
142 michael 3539 if ((mode = user_modes[(unsigned char)*m]))
143 michael 3313 {
144     if (MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER) &&
145 michael 4340 (ConfigGeneral.oper_only_umodes & mode))
146 michael 3539 badmode = 1;
147 michael 3313 else
148     {
149     if (what == MODE_ADD)
150 michael 3539 AddUMode(source_p, mode);
151 michael 3313 else
152 michael 3539 DelUMode(source_p, mode);
153 michael 3313 }
154     }
155     else if (MyConnect(source_p))
156 michael 3539 badmode = 1;
157 michael 3313
158     break;
159     }
160     }
161     }
162    
163 michael 3539 if (badmode)
164 michael 3313 sendto_one_numeric(source_p, &me, ERR_UMODEUNKNOWNFLAG);
165    
166     if (MyConnect(source_p) && HasUMode(source_p, UMODE_ADMIN) &&
167     !HasOFlag(source_p, OPER_FLAG_ADMIN))
168     {
169     sendto_one_notice(source_p, &me, ":*** You have no admin flag;");
170     DelUMode(source_p, UMODE_ADMIN);
171     }
172    
173 michael 3539 if (!(setmodes & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE))
174 michael 3313 ++Count.invisi;
175 michael 3539 if ((setmodes & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
176 michael 3313 --Count.invisi;
177    
178     /*
179 michael 3539 * Compare new modes with old modes and send string which
180 michael 3313 * will cause servers to update correctly.
181     */
182 michael 3539 send_umode_out(source_p, source_p, setmodes);
183 michael 3313 }
184    
185 adx 30 /*
186     * m_mode - MODE command handler
187 michael 3096 * parv[0] - command
188 adx 30 * parv[1] - channel
189     */
190 michael 2820 static int
191 michael 3156 m_mode(struct Client *source_p, int parc, char *parv[])
192 adx 30 {
193     struct Channel *chptr = NULL;
194    
195 michael 885 if (EmptyString(parv[1]))
196 adx 30 {
197 michael 3109 sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODE");
198 michael 2820 return 0;
199 adx 30 }
200    
201     /* Now, try to find the channel in question */
202     if (!IsChanPrefix(*parv[1]))
203     {
204     /* if here, it has to be a non-channel name */
205 michael 3156 set_user_mode(source_p, parc, parv);
206 michael 2820 return 0;
207 adx 30 }
208    
209 michael 885 if ((chptr = hash_find_channel(parv[1])) == NULL)
210 adx 30 {
211 michael 3109 sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
212 michael 2820 return 0;
213 db 848 }
214 adx 30
215     /* Now known the channel exists */
216     if (parc < 3)
217     {
218 michael 3667 char modebuf[MODEBUFLEN] = "";
219     char parabuf[MODEBUFLEN] = "";
220    
221 adx 30 channel_modes(chptr, source_p, modebuf, parabuf);
222 michael 3109 sendto_one_numeric(source_p, &me, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
223     sendto_one_numeric(source_p, &me, RPL_CREATIONTIME, chptr->chname, chptr->channelts);
224 michael 2820 return 0;
225 adx 30 }
226 michael 1895
227     /*
228     * bounce all modes from people we deop on sjoin
229 adx 30 * servers have always gotten away with murder,
230     * including telnet servers *g* - Dianora
231     */
232 michael 2644 if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE))
233 michael 3150 set_channel_mode(source_p, chptr, NULL, parc - 2, parv + 2);
234 adx 30 else
235     {
236 michael 3695 struct Membership *member = find_channel_link(source_p, chptr);
237 adx 30
238 michael 3695 /* Finish the flood grace period... */
239     if (MyClient(source_p) && !IsFloodDone(source_p))
240     if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
241     flood_endgrace(source_p);
242 adx 30
243 michael 3695 set_channel_mode(source_p, chptr, member, parc - 2, parv + 2);
244 adx 30 }
245 michael 2820
246     return 0;
247 adx 30 }
248    
249 michael 2820 static struct Message mode_msgtab =
250     {
251 michael 4545 "MODE", NULL, 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
252 michael 2820 { m_unregistered, m_mode, m_mode, m_ignore, m_mode, m_ignore }
253 michael 1230 };
254    
255     static void
256     module_init(void)
257     {
258     mod_add_cmd(&mode_msgtab);
259     }
260    
261     static void
262     module_exit(void)
263     {
264     mod_del_cmd(&mode_msgtab);
265     }
266    
267 michael 2820 struct module module_entry =
268     {
269 michael 1230 .node = { NULL, NULL, NULL },
270     .name = NULL,
271     .version = "$Revision$",
272     .handle = NULL,
273     .modinit = module_init,
274     .modexit = module_exit,
275     .flags = MODULE_FLAG_CORE
276     };

Properties

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