From e770f042295668b9a9043889948fdaabf47d03c6 Mon Sep 17 00:00:00 2001 From: pk910 Date: Mon, 5 Sep 2011 23:50:09 +0200 Subject: [PATCH] added cmd_trace and cmd_wipeinfo --- UserNode.c | 15 +++++++ UserNode.h | 1 + bot_NeonServ.c | 11 ++++- cmd_neonserv_trace.c | 95 +++++++++++++++++++++++++++++++++++++++++ cmd_neonserv_wipeinfo.c | 85 ++++++++++++++++++++++++++++++++++++ 5 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 cmd_neonserv_trace.c create mode 100644 cmd_neonserv_wipeinfo.c diff --git a/UserNode.c b/UserNode.c index a20fb1e..dccdad9 100644 --- a/UserNode.c +++ b/UserNode.c @@ -128,6 +128,21 @@ char *getAuthFakehost(char *auth) { return NULL; } +struct UserNode* getAllUsers(struct UserNode *last) { + if(last == NULL || last->next == NULL) { + int cindex; + if(last == NULL) + cindex = 0; + else + cindex = get_nicklist_entry(last->nick[0]) + 1; + while(userList[cindex] == NULL && cindex <= VALID_NICK_CHARS_FIRST_LEN) + cindex++; + if(cindex > VALID_NICK_CHARS_FIRST_LEN) return NULL; + return userList[cindex]; + } else + return last->next; +} + struct UserNode* addUser(const char *nick) { int userListIndex = get_nicklist_entry(*nick); if(userListIndex == -1 || !is_valid_nick(nick)) diff --git a/UserNode.h b/UserNode.h index 4aebb54..0048398 100644 --- a/UserNode.h +++ b/UserNode.h @@ -42,6 +42,7 @@ struct UserNode* getUserByMask(const char *mask); int countUsersWithHost(char *host); char *getAuthFakehost(char *auth); struct UserNode* searchUserByNick(const char *nick); +struct UserNode* getAllUsers(struct UserNode *last); struct UserNode* addUser(const char *nick); struct UserNode* addUserMask(const char *mask); struct UserNode* createTempUser(const char *mask); diff --git a/bot_NeonServ.c b/bot_NeonServ.c index 181eaa4..ec6615a 100644 --- a/bot_NeonServ.c +++ b/bot_NeonServ.c @@ -116,6 +116,9 @@ static const struct default_language_entry msgtab[] = { {"NS_SET_DEFAULTS_CODE", "To reset %s's settings to the defaults, you must use 'set defaults %s'."}, {"NS_SET_DEFAULTS_DONE", "All settings for %s have been reset to default values."}, {"NS_SET_TRIGGER_OWNER", "You must have access 500 in %s to change the channel trigger."}, + {"NS_WIPEINFO_DONE", "Removed \002%s\002's infoline in \002%s\002."}, + {"NS_TRACE_HEADER", "The following users were found:"}, + {"NS_TRACE_FOUND", "Found \002%d\002 matches."}, {NULL, NULL} }; @@ -154,7 +157,7 @@ INCLUDE ALL CMD's HERE //#include "cmd_neonserv_unbanme.c" #include "cmd_neonserv_suspend.c" #include "cmd_neonserv_unsuspend.c" -//#include "cmd_neonserv_wipeinfo.c" +#include "cmd_neonserv_wipeinfo.c" //#include "cmd_neonserv_addban.c" //#include "cmd_neonserv_addtimeban.c" //#include "cmd_neonserv_delban.c" @@ -189,7 +192,7 @@ INCLUDE ALL CMD's HERE //#include "cmd_neonserv_move.c" //#include "cmd_neonserv_dnrsearch.c" //#include "cmd_neonserv_search.c" -//#include "cmd_neonserv_trace.c" +#include "cmd_neonserv_trace.c" //#include "cmd_neonserv_say.c" //#include "cmd_neonserv_emote.c" //#include "cmd_neonserv_notice.c" @@ -296,6 +299,10 @@ void init_NeonServ() { register_command(BOTID, "kick", neonserv_cmd_kick, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_cankick", 0); register_command(BOTID, "kickban", neonserv_cmd_kickban, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_cankick,#channel_canban", 0); register_command(BOTID, "ban", neonserv_cmd_ban, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canban", 0); + register_command(BOTID, "wipeinfo", neonserv_cmd_wipeinfo, 1, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_wipeinfo", 0); + + register_command(BOTID, "trace", neonserv_cmd_trace, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, NULL, 400); + start_bots(); bind_bot_ready(neonserv_bot_ready); diff --git a/cmd_neonserv_trace.c b/cmd_neonserv_trace.c new file mode 100644 index 0000000..b1e1507 --- /dev/null +++ b/cmd_neonserv_trace.c @@ -0,0 +1,95 @@ + +#define NS_TRACE_CRITERIA_AUTHED 0x01 +#define NS_TRACE_CRITERIA_NUMCHAN 0x02 + +struct neonserv_cmd_trace_criteria { + char *mask; + char *nick; + char *ident; + char *host; + char *account; + unsigned int flags : 4; + unsigned int authed : 1; + unsigned int used_channel : 5; //32 max + char *channel[10]; + unsigned int numchannels; + unsigned int limit : 16; +}; + +static CMD_BIND(neonserv_cmd_trace) { + //ok parse the criterias + struct neonserv_cmd_trace_criteria *criteria = malloc(sizeof(*criteria)); + if (!criteria) { + perror("malloc() failed"); + return; + } + memset(criteria, 0, sizeof(*criteria)); + criteria->limit = 50; + int i, show_user = 0; + if(!stricmp(argv[0], "print")) { + show_user = 1; + } + for(i = 1; i < argc; i += 2) { + if(argc <= i+1) { + reply(getTextBot(), user, "MODCMD_LESS_PARAM_COUNT"); + return; + } + if(!stricmp(argv[i], "mask")) criteria->mask = argv[i+1]; + else if(!stricmp(argv[i], "nick")) criteria->nick = argv[i+1]; + else if(!stricmp(argv[i], "ident")) criteria->ident = argv[i+1]; + else if(!stricmp(argv[i], "host")) criteria->host = argv[i+1]; + else if(!stricmp(argv[i], "account")) criteria->account = argv[i+1]; + else if(!stricmp(argv[i], "authed")) { + if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) { + criteria->authed = 1; + } else if(!strcmp(argv[i+1], "0") || !strcmp(argv[i+1], "off") || !strcmp(argv[i+1], get_language_string(user, "NS_SET_OFF"))) { + criteria->authed = 0; + } else { + reply(getTextBot(), user, "NS_SET_INVALID_BOOLEAN", argv[i+1]); + return; + } + criteria->flags |= NS_TRACE_CRITERIA_AUTHED; + } + else if(!stricmp(argv[i], "channel")) criteria->channel[criteria->used_channel++] = argv[i+1]; + else if(!stricmp(argv[i], "numchannels")) { + criteria->numchannels = atoi(argv[i+1]); + criteria->flags |= NS_TRACE_CRITERIA_NUMCHAN; + } + else if(!stricmp(argv[i], "limit")) { + criteria->limit = atoi(argv[i+1]); + } + } + char tmp[MAXLEN]; + int matches = 0; + struct UserNode *cuser; + reply(getTextBot(), user, "NS_TRACE_HEADER"); + for(cuser = getAllUsers(NULL); cuser; cuser = getAllUsers(cuser)) { + if(show_user && matches == criteria->limit) { + //too many + break; + } + if(criteria->mask) { + sprintf(tmp, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host); + if(match(criteria->mask, tmp)) continue; + } + if(criteria->nick && match(criteria->nick, cuser->nick)) continue; + if(criteria->ident && match(criteria->ident, cuser->ident)) continue; + if(criteria->host && match(criteria->host, cuser->host)) continue; + if(criteria->account && (!(cuser->flags & USERFLAG_ISAUTHED) || match(criteria->account, cuser->auth))) continue; + if((criteria->flags & NS_TRACE_CRITERIA_AUTHED) && (criteria->authed ^ (cuser->flags & USERFLAG_ISAUTHED))) continue; + if((criteria->flags & NS_TRACE_CRITERIA_NUMCHAN)) { + int ccount = 0; + struct ChanUser *chanuser; + for(chanuser = getUserChannels(cuser, NULL); chanuser; chanuser = getUserChannels(cuser, chanuser)) + ccount++; + if(ccount < criteria->numchannels) + continue; + } + matches++; + //output + if(show_user) { + reply(getTextBot(), user, "%s!%s@%s %s", cuser->nick, cuser->ident, cuser->host, ((cuser->flags & USERFLAG_ISAUTHED) ? cuser->auth : "*")); + } + } + reply(getTextBot(), user, "NS_TRACE_FOUND", matches); +} diff --git a/cmd_neonserv_wipeinfo.c b/cmd_neonserv_wipeinfo.c new file mode 100644 index 0000000..72275ab --- /dev/null +++ b/cmd_neonserv_wipeinfo.c @@ -0,0 +1,85 @@ + +/* +* argv[0] - nick / *auth +*/ +static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup); +static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth); + +struct neonserv_cmd_wipeinfo_cache { + struct ClientSocket *client, *textclient; + struct UserNode *user; + struct ChanNode *chan; + char *nick; +}; + +static CMD_BIND(neonserv_cmd_wipeinfo) { + check_mysql(); + if(argv[0][0] == '*') { + //we've got an auth + argv[0]++; + neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, argv[0], argv[0]); + } else { + struct UserNode *cuser = getUserByNick(argv[0]); + if(!cuser) { + cuser = createTempUser(argv[0]); + cuser->flags |= USERFLAG_ISTMPUSER; + } + if(cuser->flags & USERFLAG_ISAUTHED) { + neonserv_cmd_wipeinfo_async1(client, getTextBot(), user, chan, argv[0], cuser->auth); + } else { + struct neonserv_cmd_wipeinfo_cache *cache = malloc(sizeof(*cache)); + if (!cache) { + perror("malloc() failed"); + return; + } + cache->client = client; + cache->textclient = getTextBot(); + cache->user = user; + cache->chan = chan; + cache->nick = strdup(argv[0]); + get_userauth(cuser, neonserv_cmd_wipeinfo_nick_lookup, cache); + } + } +} + +static USERAUTH_CALLBACK(neonserv_cmd_wipeinfo_nick_lookup) { + struct neonserv_cmd_wipeinfo_cache *cache = data; + if(!user) { + //USER_DOES_NOT_EXIST + reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick); + } + else if(!(user->flags & USERFLAG_ISAUTHED)) { + //USER_NOT_AUTHED + reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick); + } + else + neonserv_cmd_wipeinfo_async1(cache->client, cache->textclient, cache->user, cache->chan, user->nick, user->auth); + free(cache->nick); + free(cache); +} + +static void neonserv_cmd_wipeinfo_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nick, char *auth) { + //we've got a valid auth now... + MYSQL_RES *res; + MYSQL_ROW row; + int userid; + printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(auth)); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) != NULL) { + userid = atoi(row[0]); + //check if the user is already added + printf_mysql_query("SELECT `chanuser_access`, `chanuser_id` FROM `chanusers` WHERE `chanuser_cid` = '%d' AND `chanuser_uid` = '%d'", chan->channel_id, userid); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) != NULL) { + if(atoi(row[0]) >= getChannelAccess(user, chan, 1)) { + reply(textclient, user, "NS_USER_OUTRANKED", nick); + return; + } + //delete + printf_mysql_query("UPDATE `chanusers` SET `chanuser_infoline` = '' WHERE `chanuser_id` = '%s'", row[1]); + reply(textclient, user, "NS_WIPEINFO_DONE", nick, chan->name); + return; + } + } + reply(textclient, user, "NS_NOT_ON_USERLIST", nick, chan->name); +} -- 2.20.1