]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chancmds/rollbackchan.c
1 /* Automatically generated by refactor.pl.
4 * CMDNAME: rollbackchan
7 * CMDDESC: Roll back access changes on a channel.
8 * CMDFUNC: csc_dorollbackchan
9 * CMDPROTO: int csc_dorollbackchan(void *source, int cargc, char **cargv);
10 * CMDHELP: Usage: rollbackchan <channel> [<username>] <duration>
11 * CMDHELP: Reverts a channel's user access entries to a point in the past.
12 * CMDHELP: If username is specified only changes to that user will be made.
15 #include "../chanserv.h"
16 #include "../../nick/nick.h"
17 #include "../../lib/flags.h"
18 #include "../../lib/irc_string.h"
19 #include "../../channel/channel.h"
20 #include "../../parser/parser.h"
21 #include "../../irc/irc.h"
22 #include "../../localuser/localuserchannel.h"
23 #include "../../pqsql/pqsql.h"
29 void csc_dorollbackchan_real(PGconn
*dbconn
, void *arg
) {
30 nick
*np
=getnickbynumeric((unsigned long)arg
);
31 reguser
*rup
, *crup1
, *crup2
;
32 chanindex
*cip
= NULL
;
35 unsigned int userID
, channelID
, targetID
;
36 time_t changetime
, authtime
;
37 flag_t oldflags
, newflags
;
39 int i
, j
, num
, newuser
;
45 pgres
=PQgetResult(dbconn
);
47 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
48 Error("chanserv", ERR_ERROR
, "Error loading chanlev history data.");
52 if (PQnfields(pgres
) != 7) {
53 Error("chanserv", ERR_ERROR
, "Chanlev history data format error.");
61 Error("chanserv", ERR_ERROR
, "No nick pointer in rollback.");
65 if (!(rup
=getreguserfromnick(np
)) || !UHasOperPriv(rup
)) {
66 Error("chanserv", ERR_ERROR
, "No reguser pointer or oper privs in rollback.");
71 for (i
=0; i
<num
; i
++) {
72 userID
=strtoul(PQgetvalue(pgres
, i
, 0), NULL
, 10);
73 channelID
=strtoul(PQgetvalue(pgres
, i
, 1), NULL
, 10);
76 for (j
=0; j
<CHANNELHASHSIZE
&& !rcp
; j
++) {
77 for (cip
=chantable
[j
]; cip
&& !rcp
; cip
=cip
->next
) {
78 if (!cip
->exts
[chanservext
])
81 if (((regchan
*)cip
->exts
[chanservext
])->ID
== channelID
)
82 rcp
=(regchan
*)cip
->exts
[chanservext
];
87 Error("chanserv", ERR_ERROR
, "No regchan pointer or oper privs in rollback.");
94 chanservsendmessage(np
, "Attempting to roll back %s:", cip
->name
->content
);
96 targetID
=strtoul(PQgetvalue(pgres
, i
, 2), NULL
, 10);
97 changetime
=strtoul(PQgetvalue(pgres
, i
, 3), NULL
, 10);
98 authtime
=strtoul(PQgetvalue(pgres
, i
, 4), NULL
, 10);
99 oldflags
=strtoul(PQgetvalue(pgres
, i
, 5), NULL
, 10);
100 newflags
=strtoul(PQgetvalue(pgres
, i
, 6), NULL
, 10);
101 strncpy(fbuf
, printflags(newflags
, rcuflags
), 17);
103 crup1
=findreguserbyID(userID
);
104 crup2
=findreguserbyID(targetID
);
107 chanservsendmessage(np
, "Affected user (ID: %d) is no longer in database, continuing...", targetID
);
111 if (!(rcup
=findreguseronchannel(rcp
, crup2
))) {
112 rcup
=getregchanuser();
116 rcup
->changetime
=time(NULL
);
123 csdb_chanlevhistory_insert(rcp
, np
, rcup
->user
, rcup
->flags
, oldflags
);
124 rcup
->flags
=oldflags
;
125 chanservsendmessage(np
, "%s user flags for %s (%s -> %s)", newflags
?oldflags
?"Restoring":"Deleting":"Readding",
126 crup2
->username
, fbuf
, printflags(oldflags
, rcuflags
));
130 addregusertochannel(rcup
);
131 csdb_createchanuser(rcup
);
134 csdb_updatechanuser(rcup
);
138 csdb_deletechanuser(rcup
);
139 delreguserfromchannel(rcp
, crup2
);
142 freesstring(rcup
->info
);
143 freeregchanuser(rcup
);
146 for (j
=0; j
<REGCHANUSERHASHSIZE
; j
++)
147 if (rcp
->regusers
[j
])
150 if (j
==REGCHANUSERHASHSIZE
) {
151 cs_log(np
, "DELCHAN %s (Cleared chanlev from rollback)", cip
->name
->content
);
152 chanservsendmessage(np
, "Rollback cleared chanlev list, channel deleted.");
157 chanservstdmessage(np
, QM_DONE
);
162 void csdb_rollbackchanlevhistory(nick
*np
, regchan
*rcp
, reguser
* rup
, time_t starttime
) {
164 q9c_asyncquery(csc_dorollbackchan_real
, (void *)np
->numeric
,
165 "SELECT userID, channelID, targetID, changetime, authtime, oldflags, newflags from chanserv.chanlevhistory where "
166 "userID=%u and channelID=%u and changetime>%lu order by changetime desc limit 1000", rup
->ID
, rcp
->ID
, starttime
);
168 q9c_asyncquery(csc_dorollbackchan_real
, (void *)np
->numeric
,
169 "SELECT userID, channelID, targetID, changetime, authtime, oldflags, newflags from chanserv.chanlevhistory where "
170 "channelID=%u and changetime>%lu order by changetime desc limit 1000", rcp
->ID
, starttime
);
173 int csc_dorollbackchan(void *source
, int cargc
, char **cargv
) {
176 reguser
*rup
, *trup
=NULL
;
178 time_t starttime
=getnettime();
181 if (!(rup
=getreguserfromnick(sender
)))
185 chanservstdmessage(sender
, QM_NOTENOUGHPARAMS
, "rollbackchan");
189 if (!(cip
=cs_checkaccess(sender
, cargv
[0], 0, NULL
, NULL
, 0, 0)))
192 rcp
=(regchan
*)cip
->exts
[chanservext
];
195 duration
=durationtolong(cargv
[2]);
196 if (!(trup
=findreguser(sender
, cargv
[1])))
200 duration
=durationtolong(cargv
[1]);
203 chanservsendmessage(sender
, "Invalid duration.");
208 cs_log(sender
,"ROLLBACKCHAN %s #%s %s", cip
->name
->content
, rup
->username
, cargv
[1]);
210 csdb_rollbackchanlevhistory(sender
, rcp
, trup
, starttime
);