コード例 #1
0
ファイル: nph_mysql.cpp プロジェクト: dxli/XR-Fit
int updateRunning(int id, int running)
{
    Connection con(use_exceptions);
    try
    {
        ostringstream strbuf;
        unsigned int i = 0;
        con.connect(DATABASE, HOST, USER, PASSWORD);
        Query query = con.query();
        strbuf << "UPDATE tasks SET running="<<running<<" WHERE id=" << id;
        query.exec(strbuf.str());
    }
    catch (const BadQuery& er)
    {
    // Handle any query errors
        cerr << "updateDone - Query error: " << er.what() << endl;
        return -1;
    }
    catch (const BadConversion& er)
    {
    // Handle bad conversions
        cerr << "updateDone - Conversion error: " << er.what() << endl <<
                "\tretrieved data size: " << er.retrieved <<
                ", actual size: " << er.actual_size << endl;
        return -1;
    }
    catch (const Exception& er)
    {
    // Catch-all for any other MySQL++ exceptions
        cerr << "updateDone - Error: " << er.what() << endl;
        return -1;
    }

    return 0;
}        
コード例 #2
0
ファイル: nph_mysql.cpp プロジェクト: dxli/XR-Fit
int updateProgress(int id, int progress,double sigma0, double bestfitbulk)
{
    Connection con(use_exceptions);
    try
    {
        ostringstream strbuf;
        unsigned int i = 0;
        con.connect(DATABASE, HOST, USER, PASSWORD);
        Query query = con.query();
        strbuf << "UPDATE tasks SET progress=" << progress << ",sigma0="<<sigma0<<",bestfitbulk="<<bestfitbulk<<" WHERE id=" << id;
        query.exec(strbuf.str());
    }
    catch (const BadQuery& er)
    {
    // Handle any query errors
        cerr << "updateProgress - Query error: " << er.what() << endl;
        return -1;
    }
    catch (const BadConversion& er)
    {
    // Handle bad conversions
        cerr << "updateProgress - Conversion error: " << er.what() << endl <<
                "\tretrieved data size: " << er.retrieved <<
                ", actual size: " << er.actual_size << endl;
        return -1;
    }
    catch (const Exception& er)
    {
    // Catch-all for any other MySQL++ exceptions
        cerr << "updateProgress - Error: " << er.what() << endl;
        return -1;
    }

    return 0;
}
コード例 #3
0
ファイル: MasterServer.cpp プロジェクト: xmulyj/sfs
//保存到数据库
bool MasterServer::save_fileinfo_to_db(FileInfo &fileinfo)
{
	if(m_db_connection == NULL)
		return false;
	char sql_str[1024];
	ChunkPath &chunk_path = fileinfo.get_chunkpath(0);
	snprintf(sql_str, 1024, "insert into SFS.fileinfo_%s (fid, name, size, chunkid, chunkip, chunkport, findex, foffset) "
			"values('%s', '%s', %d, '%s', '%s', %d, %d, %d);"
			,fileinfo.fid.substr(0,2).c_str(), fileinfo.fid.c_str(), fileinfo.name.c_str(), fileinfo.size
			,chunk_path.id.c_str() ,chunk_path.ip.c_str(), chunk_path.port
			,chunk_path.index, chunk_path.offset);
	Query query = m_db_connection->query(sql_str);
	return query.exec();
}
コード例 #4
0
ファイル: Order.cpp プロジェクト: unixo/SENG
/**
   @brief Create a new order
 
   @param[in] anUid    ID of user that places the order
   @param[in] bsk User basket containing products
 
   @return A pointer to an instance of Order if successful
 */
Order * Order::create(int anUid, Basket & bsk)
{
    Order *o = new Order();
    
    // get current date and format as expected by mySQL
    time_t now = time(NULL);
    struct tm *tmNow = gmtime((const time_t *)&now);
    
    stringstream nowStr;
    nowStr << (1900+tmNow->tm_year) << "-" << tmNow->tm_mon << "-" 
           << setfill('0') << setw(2) << tmNow->tm_mday << " " 
           << tmNow->tm_hour << ":" << tmNow->tm_min  
           << ":" << tmNow->tm_sec;
        
    // set other attributes
    o->setIntForKey(KEY_ORD_OID, 0);
    o->setFloatForKey(KEY_ORD_TOTAL, bsk.total());
    o->setValueForKey(KEY_ORD_DATE, nowStr.str());
    o->setIntForKey(KEY_ORD_UID, anUid);
    if (!o->store()) {
        delete o;
        LOG(2, "Unable to place the order.\n");
        
        return NULL;
    }
    
    ulonglong oid = o->getLastInsertID();
    
    // get an instance of the database
    Database& db = Database::instance();
    
    // ask Database for a valid connection to mySQL
    Connection *conn = db.getConnection();
    
    // obtain an instance of mysqlpp::Query and init it
    Query q = conn->query();
    
    // add to "order_details" all items present in the basket
    for (Basket::const_iterator it=bsk.begin(); it != bsk.end(); it++) {
        q << "INSERT INTO order_details VALUES (" << oid << ", " 
          << (*it).first << ", " << (*it).second << ")";
        q.exec();
        q.reset();
    }

    return o;
}
コード例 #5
0
ファイル: updel_x_.cpp プロジェクト: XeanoRRR/mmo-resourse
int  main (void) {
  Connection con(use_exceptions);
	try {
		ostrstream strbuf; unsigned int i=0; 
		con.real_connect (MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306,(int)0,60,NULL);
		Query query = con.query(); query << MY_QUERY; 
		ResUse res = query.use(); Row row; 
		strbuf << "delete from " << MY_TABLE << " where " << MY_FIELD << " in (";
//  for UPDATE just replace the above DELETE FROM with UPDATE statement
		for(;row=res.fetch_row();i++) strbuf <<	 row[0] << ",";	if (!i) return 0; 
		string output(strbuf.str()); output.erase(output.size()-1,1); output += ")";
		query.exec((const string&)output); // cout << output << endl;
		return 0;
	} catch (BadQuery er) { 
    cerr << "Error: " << er.error << " " << con.errnum() << endl;
    return -1;
	}
}
コード例 #6
0
ファイル: shadebutton.cpp プロジェクト: moceap/scribus
void ShadeButton::setShade(QAction *act)
{
	bool ok = false;
	int a;
	int c;
	int b = 100;
	for (a = 0; a < FillSh->actions().count(); ++a)
	{
		FillSh->actions()[a]->setChecked(false);
	}
	act->setChecked(true);
	QList<QAction*> actList = FillSh->actions();
	c = actList.indexOf(act);
	if (c < 0)
		return;
	if (c > 0)
		b = (c-1) * 10;

	if (b > 100)
		return; // no need for > 100%, fix needed by SM, Riku
	
	if (c == 0)
	{
		Query* dia = new Query(this, "New", 1, 0, tr("&Shade:"), tr("Shade"));
		if (dia->exec())
    	{
			c = dia->getEditText().toInt(&ok);
			if (ok)
				b = qMax(qMin(c, 100),0);
			else
				b = 100;
			delete dia;
		}
		else
		{
			delete dia;
			return;
		}
	}
	setText(QString::number(b)+" %");
	emit clicked();
}
コード例 #7
0
void JavaDocs::slotAdd()
{
	QString nam;
	Query *dia = new Query(this, "tt", 1, 0, tr("&New Script:"), tr("New Script"));
	dia->setEditText( tr("New Script"), false );
	dia->setTestList(Doc->JavaScripts.keys());
	if (dia->exec())
	{
		nam = dia->getEditText();
		nam.replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" );
		Editor* dia2 = new Editor(this, "", View);
		dia2->EditTex->setText("function "+nam+"()\n{\n}");
		if (dia2->exec())
		{
			EditScript->setEnabled(true);
			DeleteScript->setEnabled(true);
			Doc->JavaScripts[nam] = dia2->EditTex->toPlainText();
			Scripts->addItem(nam);
			emit docChanged(false);
		}
		delete dia2;
	}
	delete dia;
}
コード例 #8
0
ファイル: MySQLStorage.cpp プロジェクト: sebjameswml/dt
void
MySQLStorage::store (Event* e)
{
        try {
                this->init();
        } catch (const exception& e) {
                stringstream errss;
                errss << "Couldn't initialise MySQL database: " << e.what();
                throw runtime_error (errss.str());
        }

        try {
                // Store the event to the database.
                this->dbCheck();
                Query query (this->conn.query());

                query << "INSERT INTO `log` "
                      << "( `time`"
                      << ", `ms`"
                      << ", `eventId`"
                      << ", `dataId`"
                      << ", `message`"
#ifdef GOT_DT_ERROR_CODE
                      << ", `errorCode`"
#endif
                      << ", `datastreamId`"
                      << ", `datastreamName`"
                      << ", `hostname`"
#ifdef GOT_DT_LOG_LEVEL
                      << ", `logLevel`"
#endif
                      << ", `pid`"
                      << ")"
                      << " VALUES "
                      << " ( FROM_UNIXTIME(" << e->getTime().tv_sec << ")"
                      << " , '" << e->getTime().tv_usec/1000
                      << "', '" << e->getId() // SQL safe? (uuid)
                      << "', '" << e->getDataId() // SQL safe? (uuid)
                      << "', '" << e->getMessage() // Need to escape
#ifdef GOT_DT_ERROR_CODE
                      << "', '" << e->getErrorCode() // SQL safe (int)
#endif
                      << "', '" << e->getDatastreamId() // SQL safe? (uuid)
                      << "', '" << e->getDatastreamName() // SQL safe? (datastreamNames can't contain '; etc)
                      << "', '" << e->getHostname() // SQL safe?
#ifdef GOT_DT_LOG_LEVEL
                      << "', '" << e->getLogLevel() // SQL safe (int)
#endif
                      << "', '" << e->getPid() // SQL safe (int)
                      << "');";

                //DBG ("INSERT Query string: " << query.str());

                if (query.exec() == false) {
                        stringstream ee;
                        ee << "Query failed, error: '" << query.error() << "'";
                        throw runtime_error (ee.str());
                }
        }
        catch (mysqlpp::BadQuery e) { this->handleBadQuery (e); }
        catch (mysqlpp::Exception e) { this->handleException (e); }
}
コード例 #9
0
ファイル: MySQLStorage.cpp プロジェクト: sebjameswml/dt
void
MySQLStorage::init (void)
{
        vector<pair<string, string> > fields;
        fields.push_back (make_pair ("id",             "int(10) unsigned NOT NULL auto_increment"));
        fields.push_back (make_pair ("eventId",        "varchar(255) collate latin1_bin NOT NULL default ''"));
        fields.push_back (make_pair ("dataId",         "varchar(255) collate latin1_bin NOT NULL default ''"));
        fields.push_back (make_pair ("message",        "varchar(255) collate latin1_bin NOT NULL default ''"));
        fields.push_back (make_pair ("errorCode",      "int(10) unsigned NOT NULL default 0"));
        fields.push_back (make_pair ("datastreamId",   "varchar(255) collate latin1_bin NOT NULL default ''"));
        fields.push_back (make_pair ("datastreamName", "varchar(255) collate latin1_bin NOT NULL default ''"));
        fields.push_back (make_pair ("hostname",       "varchar(255) collate latin1_bin NOT NULL default ''"));
        fields.push_back (make_pair ("logLevel",       "int(10) unsigned NOT NULL default 0")); // could be enum?
        fields.push_back (make_pair ("pid",            "int(10) unsigned NOT NULL default 0"));
        fields.push_back (make_pair ("time",           "DATETIME NOT NULL"));
        fields.push_back (make_pair ("ms",             "int(10) unsigned NOT NULL default 0"));

        string table (MySQLStorage::defaultDbTable);
        try {
                this->dbCheck();

                Query query (this->conn.query());

                // Create the database if necessary
                query << "CREATE TABLE IF NOT EXISTS `" << table <<  "` "
                      << "(";

                bool first (true);
                auto iField (fields.begin()), fEnd (fields.end());
                while (iField != fEnd) {
                        if (!first) {
                                query << ", ";
                        } else {
                                first = false;
                        }
                        query << "`" << iField->first << "` " << iField->second;
                        ++iField;
                }
                query << ", PRIMARY KEY (`id`)"
                      << ") "
                      << "ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin; ";

                if (query.exec() == false) {
                        stringstream ee;
                        ee << "Query failed, error: '" << query.error() << "'";
                        throw runtime_error (ee.str());
                }

                // Check that all of the columns exist
                iField = fields.begin();
                while (iField != fEnd) {
                        query.reset();
                        query << "SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'dt'"
                              << " AND TABLE_NAME = '" << table << "' AND COLUMN_NAME = '" << iField->first << "';";

                        UseQueryResult res (query.use());
                        if (!res) {
                                stringstream ee;
                                ee << "Query failed, error: '" << query.error() << "'";
                                throw runtime_error (ee.str());
                        }

                        if (Row row = res.fetch_row()) {
                        } else {
                                // Need to add the column
                                //DBG ("Couldn't find the column '" << iField->first << "'");
                                query.reset();
                                query << "ALTER TABLE `" << table << "` ADD `" << iField->first << "` " << iField->second << ";";
                                //DBG (name << " ALTER query string: " << query.str());
                                if (query.exec() == false) {
                                        stringstream ee;
                                        ee << "Query failed, error: '" << query.error() << "'";
                                        throw runtime_error (ee.str());
                                }
                        }

                        ++iField;
                }
        }
        catch (mysqlpp::BadQuery e) { this->handleBadQuery (e); }
        catch (mysqlpp::Exception e) { this->handleException (e); }
}
コード例 #10
0
ファイル: Mysql.cpp プロジェクト: minamotoshi/web
int Mysql::query(std::string sql){
	Query query = _con.query(sql.c_str());
	query.exec();
	unsigned long long id = query.insert_id();
	return (int)id;
}
コード例 #11
0
ファイル: nph_mysql.cpp プロジェクト: dxli/XR-Fit
int getNextTaskId()
//searching for a task to start
{
    int id = -1,progress;
    ostringstream strbuf;
    strbuf << "SELECT id,progress FROM tasks WHERE started=0 and running=0 ORDER BY date ASC LIMIT 1";
    
    Connection con(use_exceptions);
    
    try
    {
	Query query = con.query();
	con.connect(DATABASE, HOST, USER, PASSWORD);
	query << strbuf.str();
 StoreQueryResult res = query.store();
	cout<<strbuf.str()<<endl;
	
        if (res && res.num_rows() > 0)
	{
		mysqlpp::Row row;
		row = res.at(0);
		id = row["id"];
		progress = row["progress"];
	}

    }
    catch (const BadQuery& er)
    {    
    // Handle any query errors
        cerr << "getNextTaskId - Query error: " << er.what() << endl;
	    id = -1;
    }
    catch (const BadConversion& er)
    {
    // Handle bad conversions
        cerr << "getNextTaskId - Conversion error: " << er.what() << endl <<
			    "\tretrieved data size: " << er.retrieved <<
			    ", actual size: " << er.actual_size << endl;
	    id = -1;
    }
    catch (const Exception& er)
    {
    // Catch-all for any other MySQL++ exceptions
        cerr << "getNextTaskId - Error: " << er.what() << endl;
	    id = -1;
    }
    if(id>=1 && ! (progress >=1)) { //first time run, convert formula/density
    try{
    	strbuf.str("");
    strbuf << "SELECT energy,formula0,formula1,formula12,rhoin0,rhoin1,rhoin12 FROM tasks WHERE id="<<id;
    	Query query = con.query();
	con.connect(DATABASE, HOST, USER, PASSWORD);
	query << strbuf.str();
 StoreQueryResult res = query.store();
	cout<<strbuf.str()<<endl;
	mysqlpp::Row row;
		row = res.at(0);
		string formula0(row["formula0"]), formula1(row["formula1"]), formula12(row["formula12"]);
		double energy=row["energy"];
		double rhoin0=row["rhoin0"];
		double rhoin1=row["rhoin1"];
		double rhoin12=row["rhoin12"];
		double rho0=0.,rho1=0.,rho12=0.;
		double beta0=0.,beta1=0.,beta12=0.;
		cout<<formula0.size()<<endl;
		cout<<"formula0= "<<formula0<<endl;
		cout<<"formula1= "<<formula1<<endl;
		cout<<"formula12= "<<formula12<<endl;
		cout<<"rhoin0= "<<rhoin0<<endl;
		cout<<"rhoin1= "<<rhoin1<<endl;
		cout<<"rhoin12= "<<rhoin12<<endl;
		compound cmpd0(formula0,energy,rhoin0), cmpd1(formula1,energy,rhoin1), cmpd12(formula12,energy,rhoin12);
		strbuf.str("");
        strbuf << "UPDATE tasks SET rho0="<<cmpd0.rho_el<<",rho1="<<cmpd1.rho_el<<",rho12="<<cmpd12.rho_el<<",beta0="<<cmpd0.beta<<",beta1="<<cmpd1.beta<<",beta12="<<cmpd12.beta<<" WHERE id="<< id;
        //cout<<strbuf.str()<<endl;
        query.exec(strbuf.str());
	cout<<"rho0="<<cmpd0.rho_el<<"\tbeta="<<cmpd0.beta<<endl;
	cout<<"rho1="<<cmpd1.rho_el<<"\tbeta="<<cmpd1.beta<<endl;
	cout<<"rho12(Maximum)="<<cmpd12.rho_el<<"\tbeta="<<cmpd12.beta<<endl;
    }
    
       catch (const BadQuery& er)
    {
    // Handle any query errors
        cerr << "updateDone - Query error: " << er.what() << endl;
        return -1;
    }
    catch (const BadConversion& er)
    {
    // Handle bad conversions
        cerr << "updateDone - Conversion error: " << er.what() << endl <<
                "\tretrieved data size: " << er.retrieved <<
                ", actual size: " << er.actual_size << endl;
        return -1;
    }
    catch (const Exception& er)
    {
    // Catch-all for any other MySQL++ exceptions
        cerr << "updateDone - Error: " << er.what() << endl;
        return -1;
    }
}
 
    return id;
}
コード例 #12
0
ファイル: netconf.cpp プロジェクト: Tania188/ZeroTierOne
int main(int argc,char **argv)
{
	{
		char *ee = getenv("ZT_NETCONF_MYSQL_HOST");
		if (!ee) {
			fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_HOST\n");
			return -1;
		}
		strcpy(mysqlHost,ee);
		ee = getenv("ZT_NETCONF_MYSQL_PORT");
		if (!ee)
			strcpy(mysqlPort,"3306");
		else strcpy(mysqlPort,ee);
		ee = getenv("ZT_NETCONF_MYSQL_DATABASE");
		if (!ee) {
			fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_DATABASE\n");
			return -1;
		}
		strcpy(mysqlDatabase,ee);
		ee = getenv("ZT_NETCONF_MYSQL_USER");
		if (!ee) {
			fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_USER\n");
			return -1;
		}
		strcpy(mysqlUser,ee);
		ee = getenv("ZT_NETCONF_MYSQL_PASSWORD");
		if (!ee) {
			fprintf(stderr,"missing environment variable: ZT_NETCONF_MYSQL_PASSWORD\n");
			return -1;
		}
		strcpy(mysqlPassword,ee);
	}

	char buf[131072],buf2[131072];
	Identity signingIdentity;
	std::string dictBuf;

	try {
		dbCon = new Connection(mysqlDatabase,mysqlHost,mysqlUser,mysqlPassword,(unsigned int)strtol(mysqlPort,(char **)0,10));
		if (dbCon->connected()) {
			fprintf(stderr,"connected to mysql server successfully\n");
		} else {
			fprintf(stderr,"unable to connect to database server\n");
			return -1;
		}
	} catch (std::exception &exc) {
		fprintf(stderr,"unable to connect to database server: %s\n",exc.what());
		return -1;
	}

	// Send ready message to tell parent that the service is up, and to
	// solicit netconf-init.
	{
		Dictionary response;
		response["type"] = "ready";
		std::string respm = response.toString();
		uint32_t respml = (uint32_t)htonl((uint32_t)respm.length());
		stdoutWriteLock.lock();
		write(STDOUT_FILENO,&respml,4);
		write(STDOUT_FILENO,respm.data(),respm.length());
		stdoutWriteLock.unlock();
	}

	for(;;) {
		for(int l=0;l<4;) {
			int n = (int)read(STDIN_FILENO,buf + l,4 - l);
			if (n < 0) {
				fprintf(stderr,"error reading frame size from stdin: %s\n",strerror(errno));
				return -1;
			}
			l += n;
		}
		unsigned int fsize = (unsigned int)ntohl(*((const uint32_t *)buf));

		while (dictBuf.length() < fsize) {
			int n = (int)read(STDIN_FILENO,buf,std::min((int)sizeof(buf),(int)(fsize - dictBuf.length())));
			if (n < 0) {
				fprintf(stderr,"error reading frame from stdin: %s\n",strerror(errno));
				return -1;
			}
			for(int i=0;i<n;++i)
				dictBuf.push_back(buf[i]);
		}
		Dictionary request(dictBuf);
		dictBuf = "";

		if (!dbCon->connected()) {
			fprintf(stderr,"connection to database server lost\n");
			return -1;
		}

		// Check QNetworkConfigRefresh (MEMORY table) and push network
		// config refreshes to queued peer/network pairs.
		try {
			Dictionary to;
			{
				Query q = dbCon->query();
				q << "SELECT DISTINCT LOWER(HEX(Node_id)) AS Node_id,LOWER(HEX(Network_id)) AS Network_id FROM QNetworkConfigRefresh";
				StoreQueryResult rs = q.store();
				for(unsigned long i=0;i<rs.num_rows();++i) {
					std::string &nwids = to[rs[i]["Node_id"].c_str()];
					if (nwids.length())
						nwids.push_back(',');
					nwids.append(rs[i]["Network_id"]);
				}
			}

			{
				Query q = dbCon->query();
				q << "DELETE FROM QNetworkConfigRefresh";
				q.exec();
			}

			Dictionary response;
			response["type"] = "netconf-push";
			response["to"] = to.toString();
			std::string respm = response.toString();
			uint32_t respml = (uint32_t)htonl((uint32_t)respm.length());

			stdoutWriteLock.lock();
			write(STDOUT_FILENO,&respml,4);
			write(STDOUT_FILENO,respm.data(),respm.length());
			stdoutWriteLock.unlock();
		} catch ( ... ) {}

		try {
			const std::string &reqType = request.get("type");
			if (reqType == "netconf-init") { // initialization to set things like netconf's identity
				Identity netconfId(request.get("netconfId"));
				if ((netconfId)&&(netconfId.hasPrivate())) {
					signingIdentity = netconfId;
					fprintf(stderr,"got netconf signing identity: %s\n",signingIdentity.toString(false).c_str());
				} else {
					fprintf(stderr,"netconfId invalid or lacks private key\n");
					return -1;
				}
			} else if (reqType == "netconf-request") { // NETWORK_CONFIG_REQUEST packet
				if (!signingIdentity) {
					fprintf(stderr,"no signing identity; missing netconf-init?\n");
					return -1;
				}

				// Deserialize querying peer identity and network ID
				Identity peerIdentity(request.get("peerId"));
				uint64_t nwid = strtoull(request.get("nwid").c_str(),(char **)0,16);
				std::string fromAddr(request.get("from",""));

				// Meta-information from node, such as (future) geo-location stuff
				Dictionary meta;
				if (request.contains("meta"))
					meta.fromString(request.get("meta"));

				// Check validity of node's identity, ignore request on failure
				if (!peerIdentity.locallyValidate()) {
					fprintf(stderr,"identity failed validity check: %s\n",peerIdentity.toString(false).c_str());
					continue;
				}

				// Save node's identity if unknown
				{
					Query q = dbCon->query();
					q << "SELECT identity FROM Node WHERE id = " << peerIdentity.address().toInt();
					StoreQueryResult rs = q.store();
					if (rs.num_rows() > 0) {
						if (rs[0]["identity"] != peerIdentity.toString(false)) {
							// TODO: handle collisions...
							continue;
						}
					} else {
						q = dbCon->query();
						q << "INSERT INTO Node (id,creationTime,identity) VALUES (" << peerIdentity.address().toInt() << "," << Utils::now() << "," << quote << peerIdentity.toString(false) << ")";
						if (!q.exec()) {
							fprintf(stderr,"error inserting Node row for peer %s, aborting netconf request\n",peerIdentity.address().toString().c_str());
							continue;
						}
						// TODO: launch background validation
					}
				}

				// Look up core network information
				bool isOpen = false;
				unsigned int multicastPrefixBits = 0;
				unsigned int multicastDepth = 0;
				bool emulateArp = false;
				bool emulateNdp = false;
				unsigned int arpCacheTtl = 0;
				unsigned int ndpCacheTtl = 0;
				std::string name;
				std::string desc;
				{
					Query q = dbCon->query();
					q << "SELECT name,`desc`,isOpen,multicastPrefixBits,multicastDepth,emulateArp,emulateNdp,arpCacheTtl,ndpCacheTtl FROM Network WHERE id = " << nwid;
					StoreQueryResult rs = q.store();
					if (rs.num_rows() > 0) {
						name = rs[0]["name"].c_str();
						desc = rs[0]["desc"].c_str();
						isOpen = ((int)rs[0]["isOpen"] > 0);
						emulateArp = ((int)rs[0]["emulateArp"] > 0);
						emulateNdp = ((int)rs[0]["emulateNdp"] > 0);
						arpCacheTtl = (unsigned int)rs[0]["arpCacheTtl"];
						ndpCacheTtl = (unsigned int)rs[0]["ndpCacheTtl"];
						multicastPrefixBits = (unsigned int)rs[0]["multicastPrefixBits"];
						multicastDepth = (unsigned int)rs[0]["multicastDepth"];
					} else {
						Dictionary response;
						response["peer"] = peerIdentity.address().toString();
						response["nwid"] = request.get("nwid");
						response["type"] = "netconf-response";
						response["requestId"] = request.get("requestId");
						response["error"] = "OBJ_NOT_FOUND";
						std::string respm = response.toString();
						uint32_t respml = (uint32_t)htonl((uint32_t)respm.length());

						stdoutWriteLock.lock();
						write(STDOUT_FILENO,&respml,4);
						write(STDOUT_FILENO,respm.data(),respm.length());
						stdoutWriteLock.unlock();

						continue; // ABORT, wait for next request
					}
				}

				// Check membership if this is a closed network
				bool authenticated = true;
				if (!isOpen) {
					Query q = dbCon->query();
					q << "SELECT Node_id FROM NetworkNodes WHERE Network_id = " << nwid << " AND Node_id = " << peerIdentity.address().toInt();
					StoreQueryResult rs = q.store();
					if (!rs.num_rows()) {
						Dictionary response;
						response["peer"] = peerIdentity.address().toString();
						response["nwid"] = request.get("nwid");
						response["type"] = "netconf-response";
						response["requestId"] = request.get("requestId");
						response["error"] = "ACCESS_DENIED";
						std::string respm = response.toString();
						uint32_t respml = (uint32_t)htonl((uint32_t)respm.length());

						stdoutWriteLock.lock();
						write(STDOUT_FILENO,&respml,4);
						write(STDOUT_FILENO,respm.data(),respm.length());
						stdoutWriteLock.unlock();

						authenticated = false;
					}
				}

				// Update most recent activity entry for this peer, also indicating
				// whether authentication was successful.
				{
					if (fromAddr.length()) {
						Query q = dbCon->query();
						q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime,authenticated,lastActivityFrom) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << "," << (authenticated ? 1 : 0) << "," << quote << fromAddr << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime),authenticated = VALUES(authenticated),lastActivityFrom = VALUES(lastActivityFrom)";
						q.exec();
					} else {
						Query q = dbCon->query();
						q << "INSERT INTO NetworkActivity (Network_id,Node_id,lastActivityTime,authenticated) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << Utils::now() << "," << (authenticated ? 1 : 0) << ") ON DUPLICATE KEY UPDATE lastActivityTime = VALUES(lastActivityTime),authenticated = VALUES(authenticated)";
						q.exec();
					}
				}

				if (!authenticated)
					continue; // ABORT, wait for next request

				// Get list of etherTypes in comma-delimited hex format
				std::string etherTypeWhitelist;
				{
					Query q = dbCon->query();
					q << "SELECT DISTINCT LOWER(HEX(etherType)) AS etherType FROM NetworkEthertypes WHERE Network_id = " << nwid;
					StoreQueryResult rs = q.store();
					for(unsigned long i=0;i<rs.num_rows();++i) {
						if (etherTypeWhitelist.length() > 0)
							etherTypeWhitelist.push_back(',');
						etherTypeWhitelist.append(rs[i]["etherType"].c_str());
					}
				}

				// Get multicast group rates in dictionary format
				Dictionary multicastRates;
				{
					Query q = dbCon->query();
					q << "SELECT DISTINCT multicastGroupMac,multicastGroupAdi,preload,maxBalance,accrual FROM NetworkMulticastRates WHERE Network_id = " << nwid;
					StoreQueryResult rs = q.store();
					for(unsigned long i=0;i<rs.num_rows();++i) {
						unsigned long preload = (unsigned long)rs[i]["preload"];
						unsigned long maxBalance = (unsigned long)rs[i]["maxBalance"];
						unsigned long accrual = (unsigned long)rs[i]["accrual"];
						unsigned long long mac = (unsigned long long)rs[i]["multicastGroupMac"];
						sprintf(buf,"%.12llx/%lx",(mac & 0xffffffffffffULL),(unsigned long)rs[i]["multicastGroupAdi"]);
						sprintf(buf2,"%lx,%lx,%lx",preload,maxBalance,accrual);
						multicastRates[buf] = buf2;
					}
				}

				// Check for (or assign?) static IP address assignments
				std::string ipv4Static;
				std::string ipv6Static;
				{
					Query q = dbCon->query();
					q << "SELECT INET_NTOA(ip) AS ip,netmaskBits FROM IPv4Static WHERE Node_id = " << peerIdentity.address().toInt() << " AND Network_id = " << nwid;
					StoreQueryResult rs = q.store();
					if (rs.num_rows() > 0) {
						for(int i=0;i<rs.num_rows();++i) {
							if (ipv4Static.length())
								ipv4Static.push_back(',');
							ipv4Static.append(rs[i]["ip"].c_str());
							ipv4Static.push_back('/');
							ipv4Static.append(rs[i]["netmaskBits"].c_str());
						}
					}

					// Try to auto-assign if there's any auto-assign networks with space
					// available.
					if (!ipv4Static.length()) {
						unsigned char addressBytes[5];
						peerIdentity.address().copyTo(addressBytes,5);

						q = dbCon->query();
						q << "SELECT ipNet,netmaskBits FROM IPv4AutoAssign WHERE Network_id = " << nwid;
						rs = q.store();
						if (rs.num_rows() > 0) {
							for(int aaRow=0;aaRow<rs.num_rows();++aaRow) {
								uint32_t ipNet = (uint32_t)((unsigned long)rs[aaRow]["ipNet"]);
								unsigned int netmaskBits = (unsigned int)rs[aaRow]["netmaskBits"];

								uint32_t tryIp = (((uint32_t)addressBytes[1]) << 24) |
								                 (((uint32_t)addressBytes[2]) << 16) |
								                 (((uint32_t)addressBytes[3]) << 8) |
								                 ((((uint32_t)addressBytes[4]) % 254) + 1);
								tryIp &= (0xffffffff >> netmaskBits);
								tryIp |= ipNet;

								for(int k=0;k<100000;++k) {
									Query q2 = dbCon->query();
									q2 << "INSERT INTO IPv4Static (Network_id,Node_id,ip,netmaskBits) VALUES (" << nwid << "," << peerIdentity.address().toInt() << "," << tryIp << "," << netmaskBits << ")";
									if (q2.exec()) {
										sprintf(buf,"%u.%u.%u.%u",(unsigned int)((tryIp >> 24) & 0xff),(unsigned int)((tryIp >> 16) & 0xff),(unsigned int)((tryIp >> 8) & 0xff),(unsigned int)(tryIp & 0xff));
										if (ipv4Static.length())
											ipv4Static.push_back(',');
										ipv4Static.append(buf);
										ipv4Static.push_back('/');
										sprintf(buf,"%u",netmaskBits);
										ipv4Static.append(buf);
										break;
									} else { // insert will fail if IP is in use due to uniqueness constraints in DB
										++tryIp;
										if ((tryIp & 0xff) == 0)
											tryIp |= 1;
										tryIp &= (0xffffffff >> netmaskBits);
										tryIp |= ipNet;
									}
								}

								if (ipv4Static.length())
									break;
							}
						}
					}
				}

				// Assemble response dictionary to send to peer
				Dictionary netconf;
				sprintf(buf,"%.16llx",(unsigned long long)nwid);
				netconf[ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID] = buf;
				netconf[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO] = peerIdentity.address().toString();
				netconf[ZT_NETWORKCONFIG_DICT_KEY_NAME] = name;
				netconf[ZT_NETWORKCONFIG_DICT_KEY_DESC] = desc;
				netconf[ZT_NETWORKCONFIG_DICT_KEY_IS_OPEN] = (isOpen ? "1" : "0");
				netconf[ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES] = etherTypeWhitelist;
				netconf[ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_RATES] = multicastRates.toString();
				sprintf(buf,"%llx",(unsigned long long)Utils::now());
				netconf[ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP] = buf;
				netconf[ZT_NETWORKCONFIG_DICT_KEY_EMULATE_ARP] = (emulateArp ? "1" : "0");
				netconf[ZT_NETWORKCONFIG_DICT_KEY_EMULATE_NDP] = (emulateNdp ? "1" : "0");
				if (arpCacheTtl) {
					sprintf(buf,"%x",arpCacheTtl);
					netconf[ZT_NETWORKCONFIG_DICT_KEY_ARP_CACHE_TTL] = buf;
				}
				if (ndpCacheTtl) {
					sprintf(buf,"%x",ndpCacheTtl);
					netconf[ZT_NETWORKCONFIG_DICT_KEY_NDP_CACHE_TTL] = buf;
				}
				if (multicastPrefixBits) {
					sprintf(buf,"%x",multicastPrefixBits);
					netconf[ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_PREFIX_BITS] = buf;
				}
				if (multicastDepth) {
					sprintf(buf,"%x",multicastDepth);
					netconf[ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_DEPTH] = buf;
				}
				if (ipv4Static.length())
					netconf[ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC] = ipv4Static;
				if (ipv6Static.length())
					netconf[ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC] = ipv6Static;
				if ((!isOpen)&&(authenticated)) {
					CertificateOfMembership com(Utils::now(),ZT_NETWORK_AUTOCONF_DELAY * 3,nwid,peerIdentity.address());
					com.sign(signingIdentity);
					netconf[ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP] = com.toString();
				}

				// Send netconf as service bus response
				{
					Dictionary response;
					response["peer"] = peerIdentity.address().toString();
					response["nwid"] = request.get("nwid");
					response["type"] = "netconf-response";
					response["requestId"] = request.get("requestId");
					response["netconf"] = netconf.toString();
					std::string respm = response.toString();
					uint32_t respml = (uint32_t)htonl((uint32_t)respm.length());

					stdoutWriteLock.lock();
					write(STDOUT_FILENO,&respml,4);
					write(STDOUT_FILENO,respm.data(),respm.length());
					stdoutWriteLock.unlock();

					// LOOP, wait for next request
				}
			}