]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chancmds/rollbackchan.c
Clearup some uninitialised variables.
[irc/quakenet/newserv.git] / chanserv / chancmds / rollbackchan.c
1 /* Automatically generated by refactor.pl.
2 *
3 *
4 * CMDNAME: rollbackchan
5 * CMDLEVEL: QCMD_OPER
6 * CMDARGS: 3
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.
13 */
14
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"
24
25 #include <libpq-fe.h>
26 #include <string.h>
27 #include <stdio.h>
28
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;
33 regchan *rcp=NULL;
34 regchanuser *rcup;
35 unsigned int userID, channelID, targetID;
36 time_t changetime, authtime;
37 flag_t oldflags, newflags;
38 PGresult *pgres;
39 int i, j, num, newuser;
40 char fbuf[18];
41
42 if(!dbconn)
43 return;
44
45 pgres=PQgetResult(dbconn);
46
47 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
48 Error("chanserv", ERR_ERROR, "Error loading chanlev history data.");
49 return;
50 }
51
52 if (PQnfields(pgres) != 7) {
53 Error("chanserv", ERR_ERROR, "Chanlev history data format error.");
54 PQclear(pgres);
55 return;
56 }
57
58 num=PQntuples(pgres);
59
60 if (!np) {
61 Error("chanserv", ERR_ERROR, "No nick pointer in rollback.");
62 PQclear(pgres);
63 return;
64 }
65 if (!(rup=getreguserfromnick(np)) || !UHasOperPriv(rup)) {
66 Error("chanserv", ERR_ERROR, "No reguser pointer or oper privs in rollback.");
67 PQclear(pgres);
68 return;
69 }
70
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);
74
75 if (!rcp) {
76 for (j=0; j<CHANNELHASHSIZE && !rcp; j++) {
77 for (cip=chantable[j]; cip && !rcp; cip=cip->next) {
78 if (!cip->exts[chanservext])
79 continue;
80
81 if (((regchan*)cip->exts[chanservext])->ID == channelID)
82 rcp=(regchan*)cip->exts[chanservext];
83 }
84 }
85
86 if (!rcp) {
87 Error("chanserv", ERR_ERROR, "No regchan pointer or oper privs in rollback.");
88 PQclear(pgres);
89 return;
90 }
91
92 cip=rcp->index;
93
94 chanservsendmessage(np, "Attempting to roll back %s:", cip->name->content);
95 }
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);
102 fbuf[17]='\0';
103 crup1=findreguserbyID(userID);
104 crup2=findreguserbyID(targetID);
105
106 if (!crup2) {
107 chanservsendmessage(np, "Affected user (ID: %d) is no longer in database, continuing...", targetID);
108 continue;
109 }
110
111 if (!(rcup=findreguseronchannel(rcp, crup2))) {
112 rcup=getregchanuser();
113 rcup->user=crup2;
114 rcup->chan=rcp;
115 rcup->flags=0;
116 rcup->changetime=time(NULL);
117 rcup->usetime=0;
118 rcup->info=NULL;
119 newuser=1;
120 }
121 else
122 newuser=0;
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));
127
128 if (rcup->flags) {
129 if (newuser) {
130 addregusertochannel(rcup);
131 csdb_createchanuser(rcup);
132 }
133 else
134 csdb_updatechanuser(rcup);
135 }
136 else {
137 if (!newuser) {
138 csdb_deletechanuser(rcup);
139 delreguserfromchannel(rcp, crup2);
140 }
141
142 freesstring(rcup->info);
143 freeregchanuser(rcup);
144 rcup=NULL;
145
146 for (j=0; j<REGCHANUSERHASHSIZE; j++)
147 if (rcp->regusers[j])
148 break;
149
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.");
153 rcp=NULL;
154 }
155 }
156 }
157 chanservstdmessage(np, QM_DONE);
158
159 PQclear(pgres);
160 }
161
162 void csdb_rollbackchanlevhistory(nick *np, regchan *rcp, reguser* rup, time_t starttime) {
163 if (rup)
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);
167 else
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);
171 }
172
173 int csc_dorollbackchan(void *source, int cargc, char **cargv) {
174 nick *sender=source;
175 chanindex *cip;
176 reguser *rup, *trup=NULL;
177 regchan *rcp;
178 time_t starttime=getnettime();
179 long duration;
180
181 if (!(rup=getreguserfromnick(sender)))
182 return CMD_ERROR;
183
184 if (cargc < 2) {
185 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "rollbackchan");
186 return CMD_ERROR;
187 }
188
189 if (!(cip=cs_checkaccess(sender, cargv[0], 0, NULL, NULL, 0, 0)))
190 return CMD_ERROR;
191
192 rcp=(regchan*)cip->exts[chanservext];
193
194 if (cargc > 2) {
195 duration=durationtolong(cargv[2]);
196 if (!(trup=findreguser(sender, cargv[1])))
197 return CMD_ERROR;
198 }
199 else
200 duration=durationtolong(cargv[1]);
201
202 if (!duration) {
203 chanservsendmessage(sender, "Invalid duration.");
204 return CMD_ERROR;
205 }
206 starttime-=duration;
207
208 cs_log(sender,"ROLLBACKCHAN %s #%s %s", cip->name->content, rup->username, cargv[1]);
209
210 csdb_rollbackchanlevhistory(sender, rcp, trup, starttime);
211
212 return CMD_OK;
213 }