X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Fmodules%2Fextra%2Fm_mysql.cpp;h=7f2b96227177b4786cacc98337e6ddd8ea94b23a;hb=4488e477136ea3daa60a744bac272cc37a604136;hp=a5953762843d96c687a6e7aab52152b8467a8e2e;hpb=8ceb4ed16c147d6f6075a8920981bd37528ba5e7;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index a59537628..7f2b96227 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -30,7 +30,7 @@ using namespace std; /* $ModDesc: SQL Service Provider module for all other m_sql* modules */ /* $CompileFlags: `mysql_config --include` */ -/* $LinkerFlags: `mysql_config --libs_r` `perl ../mysql_rpath.pl` */ +/* $LinkerFlags: `mysql_config --libs_r` `perl extra/mysql_rpath.pl` */ /* THE NONBLOCKING MYSQL API! * @@ -206,11 +206,12 @@ class MySQLresult : public SQLresult std::vector colnames; std::vector fieldlists; SQLfieldMap* fieldmap; + SQLfieldMap fieldmap2; + SQLfieldList emptyfieldlist; int rows; - int cols; public: - MySQLresult(Module* self, Module* to, MYSQL_RES* res, int affected_rows) : SQLresult(self, to), currentrow(0), fieldmap(NULL) + MySQLresult(Module* self, Module* to, MYSQL_RES* res, int affected_rows, unsigned int id) : SQLresult(self, to, id), currentrow(0), fieldmap(NULL) { /* A number of affected rows from from mysql_affected_rows. */ @@ -222,7 +223,7 @@ class MySQLresult : public SQLresult rows = affected_rows; fieldlists.resize(rows); } - unsigned int field_count; + unsigned int field_count = 0; if (res) { MYSQL_ROW row; @@ -247,23 +248,21 @@ class MySQLresult : public SQLresult SQLfield sqlf(b, !row[field_count]); colnames.push_back(a); fieldlists[n].push_back(sqlf); + log(DEBUG,"Inc field count to %d",field_count+1); field_count++; } n++; } rows++; } - cols = mysql_num_fields(res); mysql_free_result(res); } - cols = field_count; - log(DEBUG, "Created new MySQL result; %d rows, %d columns", rows, cols); + log(DEBUG, "Created new MySQL result; %d rows, %d columns", rows, colnames.size()); } - MySQLresult(Module* self, Module* to, SQLerror e) : SQLresult(self, to), currentrow(0) + MySQLresult(Module* self, Module* to, SQLerror e, unsigned int id) : SQLresult(self, to, id), currentrow(0) { rows = 0; - cols = 0; error = e; log(DEBUG,"Created new MySQLresult of error type"); } @@ -279,7 +278,7 @@ class MySQLresult : public SQLresult virtual int Cols() { - return cols; + return colnames.size(); } virtual std::string ColName(int column) @@ -308,7 +307,7 @@ class MySQLresult : public SQLresult virtual SQLfield GetValue(int row, int column) { - if ((row >= 0) && (row < rows) && (column >= 0) && (column < cols)) + if ((row >= 0) && (row < rows) && (column >= 0) && (column < Cols())) { return fieldlists[row][column]; } @@ -322,36 +321,55 @@ class MySQLresult : public SQLresult virtual SQLfieldList& GetRow() { - return fieldlists[currentrow]; + if (currentrow < rows) + return fieldlists[currentrow]; + else + return emptyfieldlist; } virtual SQLfieldMap& GetRowMap() { - fieldmap = new SQLfieldMap(); - - for (int i = 0; i < cols; i++) + fieldmap2.clear(); + + if (currentrow < rows) { - fieldmap->insert(std::make_pair(colnames[cols],GetValue(currentrow, i))); + for (int i = 0; i < Cols(); i++) + { + fieldmap2.insert(std::make_pair(colnames[i],GetValue(currentrow, i))); + } + currentrow++; } - currentrow++; - return *fieldmap; + return fieldmap2; } virtual SQLfieldList* GetRowPtr() { - return &fieldlists[currentrow++]; + SQLfieldList* fieldlist = new SQLfieldList(); + + if (currentrow < rows) + { + for (int i = 0; i < Rows(); i++) + { + fieldlist->push_back(fieldlists[currentrow][i]); + } + currentrow++; + } + return fieldlist; } virtual SQLfieldMap* GetRowMapPtr() { fieldmap = new SQLfieldMap(); - - for (int i = 0; i < cols; i++) + + if (currentrow < rows) { - fieldmap->insert(std::make_pair(colnames[cols],GetValue(currentrow, i))); + for (int i = 0; i < Cols(); i++) + { + fieldmap->insert(std::make_pair(colnames[i],GetValue(currentrow, i))); + } + currentrow++; } - currentrow++; return fieldmap; } @@ -363,11 +381,7 @@ class MySQLresult : public SQLresult virtual void Free(SQLfieldList* fl) { - /* XXX: Yes, this is SUPPOSED to do nothing, we - * dont want to free our fieldlist until we - * destruct the object. Unlike the pgsql module, - * we only have the one. - */ + delete fl; } }; @@ -497,12 +511,14 @@ class SQLConnection : public classbase req.query.q = query; pthread_mutex_unlock(&queue_mutex); + log(DEBUG,"REQUEST ID: %d",req.id); + if (!mysql_real_query(&connection, req.query.q.data(), req.query.q.length())) { /* Successfull query */ res = mysql_use_result(&connection); unsigned long rows = mysql_affected_rows(&connection); - MySQLresult* r = new MySQLresult(SQLModule, req.GetSource(), res, rows); + MySQLresult* r = new MySQLresult(SQLModule, req.GetSource(), res, rows, req.id); r->dbid = this->GetID(); r->query = req.query.q; /* Put this new result onto the results queue. @@ -517,8 +533,8 @@ class SQLConnection : public classbase /* XXX: See /usr/include/mysql/mysqld_error.h for a list of * possible error numbers and error messages */ log(DEBUG,"SQL ERROR: %s",mysql_error(&connection)); - SQLerror e((SQLerrorNum)mysql_errno(&connection), mysql_error(&connection)); - MySQLresult* r = new MySQLresult(SQLModule, req.GetSource(), e); + SQLerror e(QREPLY_FAIL, ConvToStr(mysql_errno(&connection)) + std::string(": ") + mysql_error(&connection)); + MySQLresult* r = new MySQLresult(SQLModule, req.GetSource(), e, req.id); r->dbid = this->GetID(); r->query = req.query.q; @@ -644,14 +660,18 @@ void* DispatcherThread(void* arg); class Notifier : public InspSocket { - sockaddr_in sock_us; + insp_sockaddr sock_us; socklen_t uslen; Server* Srv; public: /* Create a socket on a random port. Let the tcp stack allocate us an available port */ +#ifdef IPV6 + Notifier(Server* S) : InspSocket("::1", 0, true, 3000), Srv(S) +#else Notifier(Server* S) : InspSocket("127.0.0.1", 0, true, 3000), Srv(S) +#endif { uslen = sizeof(sock_us); if (getsockname(this->fd,(sockaddr*)&sock_us,&uslen)) @@ -668,7 +688,11 @@ class Notifier : public InspSocket /* Using getsockname and ntohs, we can determine which port number we were allocated */ int GetPort() { +#ifdef IPV6 + return ntohs(sock_us.sin6_port); +#else return ntohs(sock_us.sin_port); +#endif } virtual int OnIncomingConnection(int newsock, char* ip) @@ -729,7 +753,7 @@ class ModuleSQL : public Module char* OnRequest(Request* request) { - if(strcmp(SQLREQID, request->GetData()) == 0) + if(strcmp(SQLREQID, request->GetId()) == 0) { SQLrequest* req = (SQLrequest*)request; @@ -744,8 +768,8 @@ class ModuleSQL : public Module if((iter = Connections.find(req->dbid)) != Connections.end()) { - iter->second->queue.push(*req); req->id = NewID(); + iter->second->queue.push(*req); returnval = SQLSUCCESS; } else @@ -759,7 +783,7 @@ class ModuleSQL : public Module return returnval; } - log(DEBUG, "Got unsupported API version string: %s", request->GetData()); + log(DEBUG, "Got unsupported API version string: %s", request->GetId()); return NULL; } @@ -783,8 +807,12 @@ class ModuleSQL : public Module { throw ModuleException("m_mysql: Failed to create dispatcher thread: " + std::string(strerror(errno))); } - Srv->PublishFeature("SQL", this); - Srv->PublishFeature("MySQL", this); + if (!Srv->PublishFeature("SQL", this)) + { + /* Tell worker thread to exit NOW */ + giveup = true; + throw ModuleException("m_mysql: Unable to publish feature 'SQL'"); + } } virtual ~ModuleSQL() @@ -812,7 +840,7 @@ void* DispatcherThread(void* arg) /* Connect back to the Notifier */ - if ((QueueFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) + if ((QueueFD = socket(AF_FAMILY, SOCK_STREAM, 0)) == -1) { /* crap, we're out of sockets... */ log(DEBUG,"QueueFD cant be created"); @@ -821,12 +849,19 @@ void* DispatcherThread(void* arg) log(DEBUG,"Initialize QueueFD to %d",QueueFD); - sockaddr_in addr; - in_addr ia; - inet_aton("127.0.0.1", &ia); - addr.sin_family = AF_INET; + insp_sockaddr addr; + +#ifdef IPV6 + insp_aton("::1", &addr.sin6_addr); + addr.sin6_family = AF_FAMILY; + addr.sin6_port = htons(MessagePipe->GetPort()); +#else + insp_inaddr ia; + insp_aton("127.0.0.1", &ia); + addr.sin_family = AF_FAMILY; addr.sin_addr = ia; addr.sin_port = htons(MessagePipe->GetPort()); +#endif if (connect(QueueFD, (sockaddr*)&addr,sizeof(addr)) == -1) { @@ -898,4 +933,3 @@ extern "C" void * init_module( void ) { return new ModuleSQLFactory; } -