]>
Commit | Line | Data |
---|---|---|
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 | ||
44 | char *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 | ||
74 | int 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 | } |