]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/chancmds/chanmode.c
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / chanserv / chancmds / chanmode.c
CommitLineData
1dd6d55d 1/* Automatically generated by refactor.pl.
2 *
3 *
4 * CMDNAME: chanmode
5 * CMDLEVEL: QCMD_AUTHED
6 * CMDARGS: 4
7 * CMDDESC: Shows which modes are forced or denied on a channel.
8 * CMDFUNC: csc_dochanmode
9 * CMDPROTO: int csc_dochanmode(void *source, int cargc, char **cargv);
1e32d528 10 * CMDHELP: Usage: CHANMODE <channel> [<modes>]
11 * CMDHELP: Shows or changes the list of channel modes being enforced on the channel, where:
12 * CMDHELP: channel - the channel to use
13 * CMDHELP: modes - the list of modes to allow or deny. Modes specified with + will be
14 * CMDHELP: enforced on the channel at all times, those specified with - will not
15 * CMDHELP: be allowed on the channel. If modes are not specified the current
16 * CMDHELP: setting will be displayed. If +k or +l modes are included, the actual
17 * CMDHELP: key or limit to be enforced must also be specified, for example
18 * CMDHELP: \"-il+ntk mykey\", or \"+nstl-Cc 20\". If you do not want any modes
95fcde14 19 * CMDHELP: enforced, \"CHANMODE <channel> none\" will clear the list.
1e32d528 20 * CMDHELP: Viewing the enforced modes requires operator (+o) access on the named channel.
21 * CMDHELP: Updating the enforced modes requires master (+m) access on the named channel.
22 * CMDHELP: Note: unlike similar commands that work on flags, specifying modes REPLACES
23 * CMDHELP: the list of modes to be enforced rather than changing the existing list. This
24 * CMDHELP: is because - modes are valid as well as + modes. Thus whenever you specify
25 * CMDHELP: the modes argument you must provide the complete list of desired modes each
26 * CMDHELP: time.
27 * CMDHELP: Note: if autolimit is enabled (see CHANFLAGS) it will cause a +l limit mode
28 * CMDHELP: to be enforced, with the value updating periodically as users join and leave.
29 * CMDHELP: This +l forcing cannot be changed or overridden without disabling the autolimit
30 * CMDHELP: function using the CHANFLAGS command.
1dd6d55d 31 */
32
33#include "../chanserv.h"
34#include "../../nick/nick.h"
35#include "../../lib/flags.h"
36#include "../../lib/irc_string.h"
37#include "../../channel/channel.h"
38#include "../../parser/parser.h"
39#include "../../irc/irc.h"
40#include "../../localuser/localuserchannel.h"
41#include <string.h>
42#include <stdio.h>
43
44char *getchanmode(regchan *rcp) {
45 static char buf1[50];
46 char buf2[30];
47
48 if (rcp->forcemodes) {
49 strcpy(buf1,printflags(rcp->forcemodes, cmodeflags));
50 } else {
51 buf1[0]='\0';
52 }
53
54 strcpy(buf2,printflagdiff(CHANMODE_ALL, ~(rcp->denymodes), cmodeflags));
55 strcat(buf1, buf2);
56
57 if (rcp->forcemodes & CHANMODE_LIMIT) {
58 sprintf(buf2, " %d",rcp->limit);
59 strcat(buf1, buf2);
60 }
61
62 if (rcp->forcemodes & CHANMODE_KEY) {
63 sprintf(buf2, " %s",rcp->key->content);
64 strcat(buf1, buf2);
65 }
66
67 if (*buf1=='\0') {
68 strcpy(buf1,"(none)");
69 }
70
71 return buf1;
72}
73
74int csc_dochanmode(void *source, int cargc, char **cargv) {
75 regchan *rcp;
76 nick *sender=source;
77 chanindex *cip;
78 flag_t forceflags,denyflags;
79 char buf1[60];
80 int carg=2,limdone=0;
81 sstring *newkey=NULL;
eee34485 82 int newlim=0;
1dd6d55d 83
84 if (cargc<1) {
85 chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
86 return CMD_ERROR;
87 }
88
89 if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV,
90 NULL, "chanmode", QPRIV_VIEWCHANMODES, 0)))
91 return CMD_ERROR;
92
93 rcp=cip->exts[chanservext];
94
95 if (cargc>1) {
96 if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV,
97 cip, "chanmode", QPRIV_CHANGECHANMODES, 0))
98 return CMD_ERROR;
99
100 /* Save the current modes.. */
101 strcpy(buf1,getchanmode(rcp));
102
95fcde14 103 /* Allow "none" as a magic word for simplicity. */
104 if (!ircd_strcmp(cargv[1],"none")) {
0dda73b3 105 forceflags=0;
106 denyflags=0;
95fcde14 107 } else {
108 /* Pick out the + flags: start from 0 */
109 forceflags=0;
110 setflags(&forceflags, CHANMODE_ALL, cargv[1], cmodeflags, REJECT_NONE);
111
112 /* Pick out the - flags: start from everything and invert afterwards.. */
113 denyflags=CHANMODE_ALL;
114 setflags(&denyflags, CHANMODE_ALL, cargv[1], cmodeflags, REJECT_NONE);
115 denyflags = (~denyflags) & CHANMODE_ALL;
116
117 forceflags &= ~denyflags; /* Can't force and deny the same mode (shouldn't be possible anyway) */
118
119 /* Don't allow +ps. Set the appropriate denyflag as well so that we will revert this properly if needed. */
120 if (forceflags & CHANMODE_SECRET) {
121 forceflags &= ~CHANMODE_PRIVATE;
122 denyflags |= CHANMODE_PRIVATE;
123 }
124 if (forceflags & CHANMODE_PRIVATE) {
125 forceflags &= ~CHANMODE_SECRET;
126 denyflags |= CHANMODE_SECRET;
1dd6d55d 127 }
1dd6d55d 128
95fcde14 129 /* Cope with +kl in either order. This will actually trip up if someone does something like "-l+kl"
130 * but that would be their own fault... */
131 if ((forceflags & CHANMODE_LIMIT) &&
132 (!(forceflags & CHANMODE_KEY) || strrchr(cargv[1],'l') < strrchr(cargv[1],'k'))) {
133 if (cargc<=carg) {
134 chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
135 return CMD_ERROR;
136 }
137 newlim=strtol(cargv[carg++],NULL,10);
138 limdone=1;
1dd6d55d 139 }
95fcde14 140
141 if (forceflags & CHANMODE_KEY) {
142 if (cargc<=carg) {
143 chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
144 return CMD_ERROR;
145 }
146 /* Sanitise the key. If this eliminates it then drop the +k altogether. */
147 clean_key(cargv[carg]);
148 if (!*cargv[carg]) {
149 carg++;
150 forceflags &= ~CHANMODE_KEY;
151 } else {
152 newkey=getsstring(cargv[carg++], KEYLEN);
153 }
9b43123d 154 }
1dd6d55d 155
95fcde14 156 if ((forceflags & CHANMODE_LIMIT) && !limdone) {
157 if (cargc<=carg) {
158 chanservstdmessage(sender,QM_NOTENOUGHPARAMS,"chanmode");
159 return CMD_ERROR;
160 }
161 newlim=strtol(cargv[carg++],NULL,10);
1dd6d55d 162 }
1dd6d55d 163 }
164
95fcde14 165 /* Check if chanflag +c is set and if so preserve the limit */
1dd6d55d 166 if (CIsAutoLimit(rcp)) {
167 forceflags |= CHANMODE_LIMIT;
168 denyflags &= ~CHANMODE_LIMIT;
169 newlim=rcp->limit;
eee34485 170 } else if ((forceflags & CHANMODE_LIMIT) && (newlim <= 0 || newlim >= 65535)) {
171 newlim=0;
172 forceflags &= ~CHANMODE_LIMIT;
1dd6d55d 173 }
174
175 /* It parsed OK, so update the structure.. */
176 rcp->forcemodes=forceflags;
177 rcp->denymodes=denyflags;
178 if (rcp->key)
179 freesstring(rcp->key);
180 rcp->key=newkey;
181 rcp->limit=newlim;
182
183 chanservstdmessage(sender, QM_DONE);
184 cs_log(sender,"CHANMODE %s %s (%s -> %s)",cip->name->content,cargv[1],buf1,getchanmode(rcp));
185 csdb_updatechannel(rcp);
186 cs_checkchanmodes(cip->channel);
187 }
188
189 chanservstdmessage(sender,QM_CURFORCEMODES,cip->name->content,getchanmode(rcp));
190
191 return CMD_OK;
192}