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))
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);
{"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}
};
//#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"
//#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"
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);
--- /dev/null
+
+#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);
+}
--- /dev/null
+
+/*
+* 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);
+}