00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "tools.h"
00027 #include "handlers.h"
00028 #include "channel.h"
00029 #include "channel_mode.h"
00030 #include "client.h"
00031 #include "hash.h"
00032 #include "irc_string.h"
00033 #include "sprintf_irc.h"
00034 #include "ircd.h"
00035 #include "numeric.h"
00036 #include "s_user.h"
00037 #include "s_conf.h"
00038 #include "s_serv.h"
00039 #include "send.h"
00040 #include "msg.h"
00041 #include "parse.h"
00042 #include "modules.h"
00043 #include "packet.h"
00044 #include "common.h"
00045
00046 static void m_mode(struct Client *, struct Client *, int, char *[]);
00047 static void ms_tmode(struct Client *, struct Client *, int, char *[]);
00048 static void ms_bmask(struct Client *, struct Client *, int, char *[]);
00049
00050 struct Message mode_msgtab = {
00051 "MODE", 0, 0, 2, 0, MFLG_SLOW, 0,
00052 {m_unregistered, m_mode, m_mode, m_ignore, m_mode, m_ignore}
00053 };
00054
00055 struct Message tmode_msgtab = {
00056 "TMODE", 0, 0, 4, 0, MFLG_SLOW, 0,
00057 {m_ignore, m_ignore, ms_tmode, m_ignore, m_ignore, m_ignore}
00058 };
00059
00060 struct Message bmask_msgtab = {
00061 "BMASK", 0, 0, 5, 0, MFLG_SLOW, 0,
00062 {m_ignore, m_ignore, ms_bmask, m_ignore, m_ignore, m_ignore}
00063 };
00064
00065 #ifndef STATIC_MODULES
00066 void
00067 _modinit(void)
00068 {
00069 mod_add_cmd(&mode_msgtab);
00070 mod_add_cmd(&tmode_msgtab);
00071 mod_add_cmd(&bmask_msgtab);
00072 }
00073
00074 void
00075 _moddeinit(void)
00076 {
00077 mod_del_cmd(&mode_msgtab);
00078 mod_del_cmd(&tmode_msgtab);
00079 mod_del_cmd(&bmask_msgtab);
00080 }
00081
00082 const char *_version = "$Revision: 848 $";
00083 #endif
00084
00085
00086
00087
00088
00089
00090 static void
00091 m_mode(struct Client *client_p, struct Client *source_p,
00092 int parc, char *parv[])
00093 {
00094 struct Channel *chptr = NULL;
00095 struct Membership *member;
00096 static char modebuf[MODEBUFLEN];
00097 static char parabuf[MODEBUFLEN];
00098
00099 if (*parv[1] == '\0')
00100 {
00101 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
00102 me.name, source_p->name, "MODE");
00103 return;
00104 }
00105
00106
00107 if (!IsChanPrefix(*parv[1]))
00108 {
00109
00110 set_user_mode(client_p, source_p, parc, parv);
00111 return;
00112 }
00113
00114 if (!check_channel_name(parv[1], !!MyConnect(source_p)))
00115 {
00116 sendto_one(source_p, form_str(ERR_BADCHANNAME),
00117 me.name, source_p->name, parv[1]);
00118 return;
00119 }
00120
00121 chptr = hash_find_channel(parv[1]);
00122
00123 if (chptr == NULL)
00124 {
00125 sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
00126 ID_or_name(&me, source_p->from),
00127 ID_or_name(source_p, source_p->from),
00128 parv[1]);
00129 return;
00130 }
00131
00132
00133 if (parc < 3)
00134 {
00135 channel_modes(chptr, source_p, modebuf, parabuf);
00136 sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
00137 me.name, source_p->name, chptr->chname, modebuf, parabuf);
00138 sendto_one(source_p, form_str(RPL_CREATIONTIME),
00139 me.name, source_p->name, chptr->chname, chptr->channelts);
00140 }
00141
00142
00143
00144
00145
00146
00147 else if (IsServer(source_p))
00148 {
00149 set_channel_mode(client_p, source_p, chptr, NULL, parc - 2, parv + 2,
00150 chptr->chname);
00151 }
00152 else
00153 {
00154 member = find_channel_link(source_p, chptr);
00155
00156 if (!has_member_flags(member, CHFL_DEOPPED))
00157 {
00158
00159 if (MyClient(source_p) && !IsFloodDone(source_p))
00160 {
00161 if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
00162 flood_endgrace(source_p);
00163 }
00164
00165 set_channel_mode(client_p, source_p, chptr, member, parc - 2, parv + 2,
00166 chptr->chname);
00167 }
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 static void
00180 ms_tmode(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
00181 {
00182 struct Channel *chptr = NULL;
00183 struct Membership *member = NULL;
00184
00185 if ((chptr = hash_find_channel(parv[2])) == NULL)
00186 {
00187 sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
00188 ID_or_name(&me, client_p), ID_or_name(source_p, client_p), parv[2]);
00189 return;
00190 }
00191
00192 if (atol(parv[1]) > chptr->channelts)
00193 return;
00194
00195 if (IsServer(source_p))
00196 set_channel_mode(client_p, source_p, chptr, NULL, parc - 3, parv + 3, chptr->chname);
00197 else
00198 {
00199 member = find_channel_link(source_p, chptr);
00200
00201
00202 if (has_member_flags(member, CHFL_DEOPPED))
00203 return;
00204
00205 set_channel_mode(client_p, source_p, chptr, member, parc - 3, parv + 3, chptr->chname);
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 static void
00223 ms_bmask(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
00224 {
00225 static char modebuf[IRCD_BUFSIZE];
00226 static char parabuf[IRCD_BUFSIZE];
00227 static char banbuf[IRCD_BUFSIZE];
00228 struct Channel *chptr;
00229 char *s, *t, *mbuf, *pbuf;
00230 long mode_type;
00231 int mlen, tlen;
00232 int modecount = 0;
00233 int needcap = NOCAPS;
00234
00235 if ((chptr = hash_find_channel(parv[2])) == NULL)
00236 return;
00237
00238
00239 if (atol(parv[1]) > chptr->channelts)
00240 return;
00241
00242 switch (*parv[3])
00243 {
00244 case 'b':
00245 mode_type = CHFL_BAN;
00246 break;
00247
00248 case 'e':
00249 mode_type = CHFL_EXCEPTION;
00250 needcap = CAP_EX;
00251 break;
00252
00253 case 'I':
00254 mode_type = CHFL_INVEX;
00255 needcap = CAP_IE;
00256 break;
00257
00258
00259 default:
00260 return;
00261 }
00262
00263 parabuf[0] = '\0';
00264 s = banbuf;
00265 strlcpy(s, parv[4], sizeof(banbuf));
00266
00267
00268 mlen = ircsprintf(modebuf, ":%s MODE %s +",
00269 source_p->name, chptr->chname);
00270 mbuf = modebuf + mlen;
00271 pbuf = parabuf;
00272
00273 do {
00274 if ((t = strchr(s, ' ')) != NULL)
00275 *t++ = '\0';
00276 tlen = strlen(s);
00277
00278
00279 if (tlen > MODEBUFLEN)
00280 break;
00281
00282 if (tlen && *s != ':' && add_id(source_p, chptr, s, mode_type))
00283 {
00284
00285 if (mbuf - modebuf + 2 + pbuf - parabuf + tlen > IRCD_BUFSIZE - 2 ||
00286 modecount >= MAXMODEPARAMS)
00287 {
00288 *mbuf = '\0';
00289 *(pbuf - 1) = '\0';
00290
00291 sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s",
00292 modebuf, parabuf);
00293 sendto_server(client_p, NULL, chptr, needcap, CAP_TS6, NOFLAGS,
00294 "%s %s", modebuf, parabuf);
00295
00296 mbuf = modebuf + mlen;
00297 pbuf = parabuf;
00298 modecount = 0;
00299 }
00300
00301 *mbuf++ = parv[3][0];
00302 pbuf += ircsprintf(pbuf, "%s ", s);
00303 modecount++;
00304 }
00305
00306 s = t;
00307 } while (s != NULL);
00308
00309 if (modecount)
00310 {
00311 *mbuf = *(pbuf - 1) = '\0';
00312 sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", modebuf, parabuf);
00313 sendto_server(client_p, NULL, chptr, needcap, CAP_TS6, NOFLAGS,
00314 "%s %s", modebuf, parabuf);
00315 }
00316
00317
00318 sendto_server(client_p, NULL, chptr, CAP_TS6|needcap, NOCAPS, NOFLAGS,
00319 ":%s BMASK %lu %s %s :%s",
00320 source_p->id, (unsigned long)chptr->channelts, chptr->chname,
00321 parv[3], parv[4]);
00322 }