]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/chancmds/tempban.c
CHANSERV: HACK: tempban/permban limits are now 20x normal if founder is an IRC operator
[irc/quakenet/newserv.git] / chanserv / chancmds / tempban.c
CommitLineData
1dd6d55d 1/* Automatically generated by refactor.pl.
2 *
3 *
4 * CMDNAME: tempban
5 * CMDLEVEL: QCMD_AUTHED
6 * CMDARGS: 4
7 * CMDDESC: Bans a hostmask on a channel for a specified time period.
8 * CMDFUNC: csc_dotempban
9 * CMDPROTO: int csc_dotempban(void *source, int cargc, char **cargv);
1e32d528 10 * CMDHELP: Usage: TEMPBAN <channel> <hostmask> <duration> [<reason>]
11 * CMDHELP: Temporarily bans the provided hostmask on the channel. If the ban is
12 * CMDHELP: removed from the channel e.g. by a channel op or the BANTIMER feature, the
13 * CMDHELP: ban will be reapplied if a matching user joins the channel. When the time
dd258305 14 * CMDHELP: expires the ban will be removed automatically. Bans set with the TEMPBAN
0a53499c 15 * CMDHELP: command can be removed before they expire with BANCLEAR or BANDEL. Any users
16 * CMDHELP: matching the hostmask will be kicked from the channel.
1e32d528 17 * CMDHELP: Where:
18 * CMDHELP: channel - channel to set a ban on
3fbc2554 19 * CMDHELP: hostmask - hostmask (nick!user@host) to ban.
1e32d528 20 * CMDHELP: duration - length of time to apply the ban for. Suffixes m (minutes), h (hours),
21 * CMDHELP: d (days), w (weeks), M (months) and y (years) can be used to specify
22 * CMDHELP: the duration, for example 3d, 5h, 1h30m, 1M.
23 * CMDHELP: reason - reason for the ban. This will be used in kick messages when kicking
24 * CMDHELP: users matching the ban. If this is not provided the generic message
25 * CMDHELP: \"Banned.\" will be used.
26 * CMDHELP: TEMPBAN requires master (+m) access on the named channel.
1dd6d55d 27 */
28
29#include "../chanserv.h"
30#include "../../nick/nick.h"
31#include "../../lib/flags.h"
32#include "../../lib/irc_string.h"
33#include "../../channel/channel.h"
34#include "../../parser/parser.h"
35#include "../../irc/irc.h"
36#include "../../localuser/localuserchannel.h"
37#include <string.h>
38#include <stdio.h>
39
40int csc_dotempban(void *source, int cargc, char **cargv) {
41 nick *sender=source;
42 chanindex *cip;
189772f2 43 regban *rbp, *toreplace = NULL;
1dd6d55d 44 regchan *rcp;
45 reguser *rup=getreguserfromnick(sender);
46 unsigned int duration;
3fbc2554 47 struct chanban *b;
bccd3d6a 48 char banbuf[1024];
705542fa 49 unsigned int count = 0;
1dd6d55d 50
51 if (cargc<3) {
52 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "tempban");
53 return CMD_ERROR;
54 }
55
56 if (!(cip=cs_checkaccess(sender, cargv[0], CA_MASTERPRIV, NULL, "tempban",0, 0)))
57 return CMD_ERROR;
58
59 rcp=cip->exts[chanservext];
60
61 duration=durationtolong(cargv[2]);
fdedb559
CP
62 if(!duration || duration > 400000000) {
63 chanservstdmessage(sender, QM_INVALIDDURATION2, cargv[2]);
cabd7271 64 return CMD_ERROR;
65 }
189772f2
CP
66 duration+=time(NULL);
67
bccd3d6a 68 /* saves us having to do repeat a LOT more sanity checking *wink* *wink* */
3fbc2554 69 b=makeban(cargv[1]);
bccd3d6a
CP
70 snprintf(banbuf,sizeof(banbuf),"%s",bantostring(b));
71 freechanban(b);
72 b=makeban(banbuf);
73
3fbc2554 74 for(rbp=rcp->bans;rbp;rbp=rbp->next) {
705542fa 75 count++;
3fbc2554 76 if(banequal(b,rbp->cbp)) {
189772f2
CP
77 if(rbp->expiry && (duration > rbp->expiry)) {
78 if(toreplace) { /* shouldn't happen */
79 chanservsendmessage(sender, "Internal error, duplicate bans found on banlist.");
80 } else {
81 toreplace=rbp;
82 continue;
83 }
84 } else {
85 chanservstdmessage(sender, QM_NOTREPLACINGBANLDURATION);
86 }
3fbc2554
CP
87 } else if(banoverlap(rbp->cbp,b)) {
88 chanservstdmessage(sender, QM_NEWBANALREADYBANNED, bantostring(rbp->cbp));
89 } else if(banoverlap(b,rbp->cbp)) {
bccd3d6a 90 chanservstdmessage(sender, QM_NEWBANOVERLAPS, bantostring(rbp->cbp), banbuf);
3fbc2554
CP
91 } else {
92 continue;
93 }
94
95 freechanban(b);
96 return CMD_ERROR;
97 }
705542fa
CP
98
99 if(count >= MAXBANS) {
72e2ae23
CP
100 /* HACK: oper founder channels have 20x the ban limit */
101 reguser *founder=findreguserbyID(rcp->founder);
102 if(!founder || !UHasOperPriv(founder) || count >= MAXBANS * 20) {
103 freechanban(b);
104 chanservstdmessage(sender, QM_TOOMANYBANS);
105 return CMD_ERROR;
106 }
705542fa
CP
107 }
108
189772f2
CP
109 if(toreplace) {
110 freechanban(b);
111 chanservstdmessage(sender, QM_REPLACINGBANSDURATION);
112 rbp=toreplace;
113 if(rbp->reason)
114 freesstring(toreplace->reason);
115 } else {
116 rbp=getregban();
117 rbp->ID=++lastbanID;
118 rbp->cbp=b;
119
120 rbp->next=rcp->bans;
121 rcp->bans=rbp;
122 }
123
1dd6d55d 124 rbp->setby=rup->ID;
189772f2 125 rbp->expiry=duration;
1dd6d55d 126 if (cargc>3)
127 rbp->reason=getsstring(cargv[3],200);
128 else
129 rbp->reason=NULL;
1dd6d55d 130
131 cs_setregban(cip, rbp);
189772f2
CP
132 if(toreplace) {
133 csdb_updateban(rcp, rbp);
134 } else {
135 csdb_createban(rcp, rbp);
136 }
1dd6d55d 137
138 chanservstdmessage(sender, QM_DONE);
139 return CMD_OK;
140}