diff options
author | Adam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864> | 2010-02-28 17:33:31 +0000 |
---|---|---|
committer | Adam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864> | 2010-02-28 17:33:31 +0000 |
commit | 3f80e1cad02735f692a5a300ee3b200a21f330aa (patch) | |
tree | d7bcd3c5d1cfd54c725f4c9a0eb7984632b6be67 /src/modules/mysql/db_mysql_execute.cpp | |
parent | 393b5ab26e952f427f40a8ed6d10acfdf6ead96c (diff) |
Added in support for live updating MySQL databases and the ability to execute commands to Anope through MySQL. Currently database support only applies to NickServ, ChanServ and BotServ but will be expanded soon.
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2798 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src/modules/mysql/db_mysql_execute.cpp')
-rw-r--r-- | src/modules/mysql/db_mysql_execute.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/modules/mysql/db_mysql_execute.cpp b/src/modules/mysql/db_mysql_execute.cpp new file mode 100644 index 000000000..adeabd267 --- /dev/null +++ b/src/modules/mysql/db_mysql_execute.cpp @@ -0,0 +1,162 @@ +/* RequiredLibraries: mysqlpp */ + +#include "db_mysql.h" +#define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31)) + +class FakeNickCore : public NickCore +{ + public: + FakeNickCore() : NickCore("-SQLUser") + { + if (this->next) + this->next->prev = this->prev; + if (this->prev) + this->prev->next = this->next; + else + nclists[HASH(this->display)] = this->next; + } + + ~FakeNickCore() + { + insert_core(this); + } + + bool IsServicesOper() const { return true; } + bool HasCommand(const std::string &) const { return true; } + bool HasPriv(const std::string &) const { return true; } +} SQLCore; + +class FakeUser : public User +{ + public: + FakeUser() : User("-SQLUser", "") + { + this->SetIdent("SQL"); + this->host = sstrdup(Config.ServerName); + this->realname = sstrdup("Fake SQL User"); + this->hostip = sstrdup("255.255.255.255"); + this->vhost = NULL; + + if (this->prev) + this->prev->next = this->next; + else + userlist[HASH(this->nick)] = this->next; + if (this->next) + this->next->prev = this->prev; + --usercnt; + } + + ~FakeUser() + { + User **list = &userlist[HASH(this->nick)]; + this->next = *list; + if (*list) + (*list)->prev = this; + *list = this; + ++usercnt; + } + + void SetNewNick(const std::string &newnick) { this->nick = newnick; } + + void SendMessage(const std::string &, const char *, ...) { } + void SendMessage(const std::string &, const std::string &) { } + + NickCore *Account() const { return nc; } + const bool IsIdentified() const { return nc ? true : false; } +} SQLUser; + +class SQLTimer : public Timer +{ + public: + SQLTimer() : Timer(Me->Delay, time(NULL), true) { } + + void Tick(time_t) + { + mysqlpp::Query query(Me->Con); + mysqlpp::StoreQueryResult qres; + + query << "SELECT * FROM `anope_commands`"; + qres = StoreQuery(query); + + if (qres && qres.num_rows()) + { + for (size_t i = 0; i < qres.num_rows(); ++i) + { + User *u; + NickAlias *na = NULL; + + /* If they want -SQLUser to execute the command, use it */ + if (qres[i]["nick"] == "-SQLUser") + { + u = &SQLUser; + u->SetNewNick("-SQLUser"); + SQLCore.Users.clear(); + u->Login(&SQLCore); + } + else + { + /* See if the nick they want to execute the command is registered */ + na = findnick(SQLAssign(qres[i]["nick"])); + if (na) + { + /* If it is and someone is online using that nick, use them */ + if (!na->nc->Users.empty()) + u = na->nc->Users.front(); + /* Make a fake nick and use that logged in as the nick we want to use */ + else + { + u = &SQLUser; + u->SetNewNick(SQLAssign(qres[i]["nick"])); + u->Login(na->nc); + } + } + else + { + /* Check if someone is online using the nick now */ + u = finduser(SQLAssign(qres[i]["nick"])); + /* If they arent make a fake user, and use them */ + if (!u) + { + u = &SQLUser; + u->SetNewNick(SQLAssign(qres[i]["nick"])); + u->Logout(); + } + } + } + + BotInfo *bi = findbot(SQLAssign(qres[i]["service"])); + if (!bi) + { + Alog() << "Warning: SQL command for unknown service " << qres[i]["service"]; + continue; + } + + // XXX this whole strtok thing needs to die + char *cmdbuf = sstrdup(qres[i]["command"].c_str()); + char *cmd = strtok(cmdbuf, " "); + mod_run_cmd(bi->nick, u, bi->cmdTable, cmd); + delete [] cmdbuf; + } + + query << "TRUNCATE TABLE `anope_commands`"; + ExecuteQuery(query); + } + } +}; + +class DBMySQLExecute : public DBMySQL +{ + SQLTimer *_SQLTimer; + public: + DBMySQLExecute(const std::string &modname, const std::string &creator) : DBMySQL(modname, creator) + { + _SQLTimer = new SQLTimer(); + } + + ~DBMySQLExecute() + { + TimerManager::DelTimer(_SQLTimer); + } +}; + +MODULE_INIT(DBMySQLExecute) |