]>
jfr.im git - irc/quakenet/newserv.git/blob - fakeusers/fakeusers.c
2 * NOperserv Fakeuser module
4 * Allows fakeusers to be added so as to block nicks, for example.
6 * Copyright (c) Tim Gordon 2006.
9 #include "../core/schedule.h"
10 #include "../localuser/localuser.h"
11 #include "../localuser/localuserchannel.h"
12 #include "../irc/irc_config.h"
13 #include "../lib/irc_string.h"
14 #include "../control/control.h"
15 #include "../channel/channel.h"
16 #include "../dbapi2/dbapi2.h"
17 #include "../lib/strlfunc.h"
18 #include "../lib/version.h"
27 typedef struct fakeuser
{
28 char nick
[NICKLEN
+ 1];
29 char ident
[USERLEN
+ 1];
30 char host
[HOSTLEN
+ 1];
31 char realname
[REALLEN
+ 1];
34 struct fakeuser
*next
;
37 fakeuser
*fakeuserlist
= NULL
;
39 void fakeuser_cleanup();
40 int fakeuser_loaddb();
41 void fakeusers_load(const DBAPIResult
*res
, void *arg
);
42 void fakeuser_handler(nick
*user
, int command
, void **params
);
43 int fakeadd(void *sender
, int cargc
, char **cargv
);
44 int fakelist(void *sender
, int cargc
, char **cargv
);
45 int fakekill(void *sender
, int cargc
, char **cargv
);
46 void schedulefakeuser(void *arg
);
47 fakeuser
*findfakeuserbynick(char *nick
);
48 void fake_remove(char *nickname
);
49 fakeuser
*fake_add(fakeuser
*details
);
51 static DBAPIConn
*nofudb
;
54 if (!fakeuser_loaddb()) {
55 Error("fakeuser", ERR_FATAL
, "Cannot load database");
59 registercontrolhelpcmd("fakeuser", NO_OPER
, 4, &fakeadd
, "Usage: FAKEUSER nick <ident> <host> <realname>\nCreates a fake user.");
60 registercontrolhelpcmd("fakelist", NO_OPER
, 0, &fakelist
, "Usage: FAKELIST\nLists all fake users.");
61 registercontrolhelpcmd("fakekill", NO_OPER
, 2, &fakekill
, "Usage: FAKEKILL nick <reason>\nRemoves a fake user");
67 deleteallschedules(schedulefakeuser
);
68 deregistercontrolcmd("fakeuser", &fakeadd
);
69 deregistercontrolcmd("fakelist", &fakelist
);
70 deregistercontrolcmd("fakekill", &fakekill
);
73 void fakeuser_cleanup() {
77 for (fake
= fakeuserlist
; fake
; fake
= next
) {
78 deregisterlocaluser(fake
->user
, "Signing off");
86 int fakeuser_loaddb() {
88 nofudb
= dbapi2open(DBAPI2_DEFAULT
, "fakeusers");
91 Error("fakeuser", ERR_STOP
, "Could not connect to database.");
96 nofudb
->createtable(nofudb
, NULL
, NULL
,
98 "nick VARCHAR(?) NOT NULL,"
99 "ident VARCHAR(?) NOT NULL,"
100 "host VARCHAR(?) NOT NULL,"
101 "realname VARCHAR(?) NOT NULL,"
102 "PRIMARY KEY (nick))", "Tdddd", "fakeusers", NICKLEN
, USERLEN
, HOSTLEN
, REALLEN
);
104 nofudb
->query(nofudb
, fakeusers_load
, NULL
,
105 "SELECT nick, ident, host, realname FROM ?", "T", "fakeusers");
110 void fakeusers_load(const DBAPIResult
*res
, void *arg
) {
117 Error("fakeuser", ERR_ERROR
, "Error loading fakeuser list.");
122 while (res
->next(res
)) {
123 strlcpy(fakeuser
.nick
, res
->get(res
, 0), NICKLEN
+ 1);
124 strlcpy(fakeuser
.ident
, res
->get(res
, 1), USERLEN
+ 1);
125 strlcpy(fakeuser
.host
, res
->get(res
, 2), HOSTLEN
+ 1);
126 strlcpy(fakeuser
.realname
, res
->get(res
, 3), REALLEN
+ 1);
130 scheduleoneshot(time(NULL
) + 1, schedulefakeuser
, NULL
);
134 fakeuser
*getdetails(nick
*user
) {
136 details
= malloc(sizeof(fakeuser
));
141 strlcpy(details
->nick
, user
->nick
, NICKLEN
+ 1);
142 strlcpy(details
->ident
, user
->ident
, USERLEN
+ 1);
143 strlcpy(details
->host
, user
->host
->name
->content
, HOSTLEN
+ 1);
144 strlcpy(details
->realname
, user
->realname
->name
->content
, REALLEN
+ 1);
145 details
->lastkill
= 0;
149 nick
*register_fakeuseronnet(fakeuser
*details
) {
152 if ((user
= getnickbynick(details
->nick
)) && (IsOper(user
) || IsService(user
) || IsXOper(user
))) {
156 return registerlocaluser(details
->nick
, details
->ident
, details
->host
, details
->realname
,
157 NULL
, UMODE_INV
| UMODE_DEAF
, &fakeuser_handler
);
160 fakeuser
*fake_add(fakeuser
*details
) {
163 newfake
= malloc(sizeof(fakeuser
));
169 memcpy(newfake
, details
, sizeof(fakeuser
));
171 newfake
->user
= NULL
;
172 newfake
->lastkill
= 0;
174 newfake
->next
= fakeuserlist
;
175 fakeuserlist
= newfake
;
179 void fake_remove(char *nickname
) {
180 fakeuser
*fake
, *prev
;
182 for (fake
= fakeuserlist
; fake
; fake
= fake
->next
) {
183 if (!ircd_strcmp(nickname
, fake
->nick
)) {
184 if (fake
== fakeuserlist
)
185 fakeuserlist
= fake
->next
;
187 prev
->next
= fake
->next
;
197 void fakeuser_handler(nick
*user
, int command
, void **params
) {
198 if (command
== LU_KILLED
) {
200 time_t timenow
= time(NULL
);
202 item
= findfakeuserbynick(user
->nick
);
205 controlwall(NO_OPER
, NL_FAKEUSERS
, "Error: A fakeuser was killed, but wasn't found in the list");
206 Error("fakeuser", ERR_ERROR
, "A fakeuser was killed, but wasn't found in the list");
212 if (timenow
- item
->lastkill
< KILL_TIME
) {
213 controlwall(NO_OPER
, NL_FAKEUSERS
, "Fake user %s!%s@%s (%s) KILL'ed twice under in %d seconds. Removing.", item
->nick
, item
->ident
, item
->host
, item
->realname
, KILL_TIME
);
214 nofudb
->squery(nofudb
, "DELETE FROM ? WHERE nick = ?", "Ts", "fakeusers", item
->nick
);
215 fake_remove(item
->nick
);
219 item
->lastkill
= timenow
;
221 scheduleoneshot(time(NULL
) + KILL_WAIT
, schedulefakeuser
, item
);
225 int fakeadd(void *sender
, int cargc
, char **cargv
) {
232 fake
= findfakeuserbynick(cargv
[0]);
235 controlreply(sender
, "Fake User with nick %s already found", cargv
[0]);
239 strlcpy(newfake
.nick
, cargv
[0], NICKLEN
+ 1);
242 strlcpy(newfake
.realname
, cargv
[0], REALLEN
+ 1);
244 strlcpy(newfake
.realname
, cargv
[3], REALLEN
+ 1);
247 strlcpy(newfake
.host
, cargv
[0], NICKLEN
+ 1);
248 strlcat(newfake
.host
, ".fakeusers.quakenet.org", HOSTLEN
+ 1);
250 strlcpy(newfake
.host
, cargv
[2], HOSTLEN
+ 1);
253 strlcpy(newfake
.ident
, cargv
[0], USERLEN
+ 1);
255 strlcpy(newfake
.ident
, cargv
[1], USERLEN
+ 1);
257 fake
= fake_add(&newfake
);
263 nofudb
->squery(nofudb
, "INSERT INTO ? (nick, ident, host, realname) VALUES (?,?,?,?)", "Tssss", "fakeusers", fake
->nick
, fake
->ident
, fake
->host
, fake
->realname
);
264 controlreply(sender
, "Added fake user %s", fake
->nick
);
265 controlwall(NO_OPER
, NL_FAKEUSERS
, "Fake user %s!%s@%s (%s) added by %s/%s", fake
->nick
, fake
->ident
,
266 fake
->host
, fake
->realname
, ((nick
*)sender
)->nick
, ((nick
*)sender
)->authname
);
268 scheduleoneshot(time(NULL
) + 1, schedulefakeuser
, fake
);
272 int fakelist(void *sender
, int cargc
, char **cargv
) {
274 int fakeusercount
= 0;
276 for (fake
= fakeuserlist
; fake
; fake
= fake
->next
) {
278 controlreply(sender
, "%s!%s@%s (%s) %s - RECONNECTING", fake
->nick
, fake
->ident
,
279 fake
->host
, fake
->realname
);
281 controlreply(sender
, "%s!%s@%s (%s)", fake
->nick
, fake
->ident
,
282 fake
->host
, fake
->realname
);
287 controlreply(sender
, "%d fakeusers are currently connected", fakeusercount
);
291 int fakekill(void *sender
, int cargc
, char **cargv
) {
297 fake
= findfakeuserbynick(cargv
[0]);
300 controlreply(sender
, "No Fake User with nick %s found", cargv
[0]);
304 nofudb
->squery(nofudb
, "DELETE FROM ? WHERE nick = ?", "Ts", "fakeusers", fake
->nick
);
305 controlreply(sender
, "Killed fake user %s", fake
->nick
);
306 controlwall(NO_OPER
, NL_FAKEUSERS
, "Fake user %s!%s@%s (%s) removed by %s/%s", fake
->nick
, fake
->ident
,
307 fake
->host
, fake
->realname
, ((nick
*)sender
)->nick
, ((nick
*)sender
)->authname
);
311 deregisterlocaluser(fake
->user
, cargv
[1]);
313 deregisterlocaluser(fake
->user
, "Signing off");
316 fake_remove(cargv
[0]);
320 void schedulefakeuser(void *arg
) {
323 for (fake
= fakeuserlist
; fake
; fake
= fake
->next
) {
325 fake
->user
= register_fakeuseronnet(fake
);
330 fakeuser
*findfakeuserbynick(char *nick
) {
333 for (fake
= fakeuserlist
; fake
; fake
= fake
->next
) {
334 if (!ircd_strcmp(nick
, fake
->nick
)) {