static Variant HHVM_FUNCTION(mysql_num_fields, const Resource& result) { MySQLResult *res = php_mysql_extract_result(result); if (res) { return res->getFieldCount(); } return false; }
static Variant HHVM_FUNCTION(mysql_async_query_result, const Variant& link_identifier) { MySQL* mySQL = MySQL::Get(link_identifier); if (!mySQL) { raise_warning("supplied argument is not a valid MySQL-Link resource"); return Variant(Variant::NullInit()); } MYSQL* conn = mySQL->get(); if (!conn || (conn->async_op_status != ASYNC_OP_QUERY && conn->async_op_status != ASYNC_OP_UNSET)) { raise_warning("runtime/ext_mysql: attempt to check query result when query " "not executing"); return Variant(Variant::NullInit()); } int error = 0; auto status = mysql_real_query_nonblocking( conn, mySQL->m_async_query.data(), mySQL->m_async_query.size(), &error); if (status != NET_ASYNC_COMPLETE) { return Variant(Variant::NullInit()); } if (error) { return Variant(Variant::NullInit()); } mySQL->m_async_query.reset(); MYSQL_RES* mysql_result = mysql_use_result(conn); MySQLResult *r = newres<MySQLResult>(mysql_result); r->setAsyncConnection(mySQL); Resource ret(r); return ret; }
static void daemon_change_password(std::string &user, std::string &base64_rsa_md5saltsum_old_password, std::string &base64_rsa_md5saltsum_new_password) { std::vector<unsigned char> v; base64_decode(base64_rsa_md5saltsum_old_password, v); std::vector<unsigned char> v2; rsa_decrypt(v, v2, RSA_Public_Key_d, RSA_Public_Key_n); std::string old_passwd; vector_to_string(v2, old_passwd); base64_decode(base64_rsa_md5saltsum_new_password, v); rsa_decrypt(v, v2, RSA_Public_Key_d, RSA_Public_Key_n); std::string new_passwd; vector_to_string(v2, new_passwd); if (new_passwd.length()!=32) { daemon_printf( "%d wrong new password\n", CODE_DENIED ); return; } if (init_database()) { daemon_printf( "%d Connect to MySQL failed!\n", CODE_DENIED ); return; } std::string sql; if (auth_user != "root") { sql = "SELECT user_md5saltpassword FROM stardict_users WHERE username="******"%d Query failed!\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d Get result failed!\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (!row) { res->destroy(); daemon_printf( "%d user doesn't exist\n", CODE_DENIED ); return; } if (old_passwd != row[0]) { res->destroy(); daemon_printf( "%d old password is wrong\n", CODE_DENIED ); return; } res->destroy(); } sql = "UPDATE stardict_users SET user_md5saltpassword="******" WHERE username="******"%d Query failed!\n", CODE_DENIED ); return; } daemon_printf( "%d\n", CODE_OK ); }
static bool HHVM_FUNCTION(mysql_free_result, const Resource& result) { MySQLResult *res = php_mysql_extract_result(result); if (res) { res->close(); return true; } return false; }
Variant f_mysql_free_result(CVarRef result) { MySQLResult *res = php_mysql_extract_result(result); if (res) { res->close(); return true; } return false; }
static Variant HHVM_FUNCTION(mysql_async_fetch_array, const Resource& result, int result_type /* = 1 */) { if ((result_type & PHP_MYSQL_BOTH) == 0) { throw_invalid_argument("result_type: %d", result_type); return false; } MySQLResult* res = php_mysql_extract_result(result); if (!res) { return false; } MYSQL_RES* mysql_result = res->get(); if (!mysql_result) { raise_warning("invalid parameter to mysql_async_fetch_array"); return false; } MYSQL_ROW mysql_row = NULL; int status = mysql_fetch_row_nonblocking(mysql_result, &mysql_row); // Last row, or no row yet available. if (status != NET_ASYNC_COMPLETE) { return false; } if (mysql_row == NULL) { res->close(); return false; } unsigned long *mysql_row_lengths = mysql_fetch_lengths(mysql_result); if (!mysql_row_lengths) { return false; } mysql_field_seek(mysql_result, 0); Array ret; MYSQL_FIELD *mysql_field; int i; for (mysql_field = mysql_fetch_field(mysql_result), i = 0; mysql_field; mysql_field = mysql_fetch_field(mysql_result), i++) { Variant data; if (mysql_row[i]) { data = mysql_makevalue(String(mysql_row[i], mysql_row_lengths[i], CopyString), mysql_field); } if (result_type & PHP_MYSQL_NUM) { ret.set(i, data); } if (result_type & PHP_MYSQL_ASSOC) { ret.set(String(mysql_field->name, CopyString), data); } } return ret; }
MySQLResult *php_mysql_extract_result(const Variant& result) { MySQLResult *res = result.toResource().getTyped<MySQLResult> (!RuntimeOption::ThrowBadTypeExceptions, !RuntimeOption::ThrowBadTypeExceptions); if (res == nullptr || (res->get() == nullptr && !res->isLocalized())) { raise_warning("supplied argument is not a valid MySQL result resource"); return nullptr; } return res; }
static TableRow get_row(MySQLResult& result, MYSQL_ROW row) { TableRow record{result.num_fields()}; unsigned long * lengths = mysql_fetch_lengths(result.result()); for ( size_t f = 0; f < result.num_fields(); ++f ) { record[f] = std::string{row[f], lengths[f]}; } return record; }
static TableRow get_field_names(MySQLResult& result) { MYSQL_FIELD * fields = mysql_fetch_fields(result.result()); TableRow field_names{result.num_fields()}; for ( size_t i = 0; i < result.num_fields(); ++i ) { field_names[i] = fields[i].name; } return field_names; }
Variant f_mysql_fetch_lengths(CVarRef result) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; if (res->isLocalized()) { if (!res->isRowReady()) return false; Array ret; for (int i = 0; i < res->getFieldCount(); i++) { MySQLFieldInfo *info = res->getFieldInfo(i); if (info->type == MYSQL_TYPE_YEAR) { // special case for years, because of leading zeros ret.set(i, info->length); } else { // convert fields back to Strings to get lengths ret.set(i, res->getField(i).toString().length()); } } return ret; } MYSQL_RES *mysql_result = res->get(); unsigned long *lengths = mysql_fetch_lengths(mysql_result); if (!lengths) { return false; } Array ret; int num_fields = mysql_num_fields(mysql_result); for (int i = 0; i < num_fields; i++) { ret.set(i, (int)lengths[i]); } return ret; }
DBResult *MySQLConn::getResult() { MYSQL_RES *res = mysql_store_result(mysql); if (!res) return NULL; result.set(res); return &result; }
static void daemon_getdictmask() { if (userID.empty()) { daemon_printf( "%d unknow user id\n", CODE_USER_NOT_REGISTER ); return; } if (init_database()) { daemon_printf( "%d Connect to MySQL failed!\n", CODE_DENIED ); return; } std::string sql; sql = "SELECT dictmask FROM user_basic WHERE id="; sql += userID; if (stardictdMain.conn.query(sql.c_str(), sql.length())) { daemon_printf( "%d query failed\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d get result failed\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (!row) { res->destroy(); daemon_printf( "%d fetch row failed\n", CODE_DENIED ); return; } daemon_printf( "%d\n", CODE_OK ); const char *dictmask = row[0]; char *str = g_strdup_printf("level-%d-user/max_dict_count", userLevel); const int max_dict_count = stardictdMain.conf->get_int(str); g_free(str); std::string dictmask_str = stardictdMain.oLibs.get_dicts_list(dictmask, max_dict_count, userLevel); net_write_str(dictmask_str.c_str()); res->destroy(); }
bool f_mysql_field_seek(CVarRef result, int field /* = 0 */) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; return res->seekField(field); }
Variant f_mysql_result(CVarRef result, int row, CVarRef field /* = null_variant */) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; MYSQL_RES *mysql_result = NULL; MYSQL_ROW sql_row = NULL; unsigned long *sql_row_lengths = NULL; if (res->isLocalized()) { if (!res->seekRow(row)) return false; if (!res->fetchRow()) return false; } else { mysql_result = res->get(); if (row < 0 || row >= (int)mysql_num_rows(mysql_result)) { raise_warning("Unable to jump to row %d on MySQL result index %d", row, result.toResource()->o_getId()); return false; } mysql_data_seek(mysql_result, row); sql_row = mysql_fetch_row(mysql_result); if (!sql_row) { return false; } sql_row_lengths = mysql_fetch_lengths(mysql_result); if (!sql_row_lengths) { return false; } } int field_offset = 0; if (!field.isNull()) { if (field.isString()) { String sfield = field.toString(); const char *tmp = strchr(sfield.data(), '.'); String table_name, field_name; if (tmp) { int pos = tmp - sfield.data(); table_name = sfield.substr(0, pos); field_name = sfield.substr(pos + 1); } else { field_name = sfield; } int i = 0; bool found = false; res->seekField(0); while (i < res->getFieldCount()) { MySQLFieldInfo *info = res->getFieldInfo(i); if ((table_name.empty() || table_name.same(info->table)) && field_name.same(info->name)) { field_offset = i; found = true; break; } i++; } if (!found) { /* no match found */ raise_warning("%s%s%s not found in MySQL result index %d", table_name.data(), (table_name.empty() ? "" : "."), field_name.data(), result.toResource()->o_getId()); return false; } } else { field_offset = field.toInt32(); if (field_offset < 0 || field_offset >= (int)res->getFieldCount()) { raise_warning("Bad column offset specified"); return false; } } } if (res->isLocalized()) { Variant f = res->getField(field_offset); if (!f.isNull()) { return f.toString(); } } else { if (sql_row[field_offset]) { return String(sql_row[field_offset], sql_row_lengths[field_offset], CopyString); } } return uninit_null(); }
static void daemon_userlevel(std::string &user, std::string &fromlevel, std::string &tolevel) { if (auth_user != "root") { daemon_printf( "%d no permission\n", CODE_DENIED ); return; } int from = atoi(fromlevel.c_str()); if (fromlevel.empty() || from<0 || from>5) { daemon_printf( "%d wrong from-level\n", CODE_DENIED ); return; } int to = atoi(tolevel.c_str()); if (tolevel.empty() || to<0 || to>5 || to==from) { daemon_printf( "%d wrong to-level\n", CODE_DENIED ); return; } if (init_database()) { daemon_printf( "%d Connect to MySQL failed!\n", CODE_DENIED ); return; } std::string sql; sql = "SELECT level FROM stardict_users WHERE username="******"%d query user level failed\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d Get result failed!\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (!row) { res->destroy(); daemon_printf( "%d user doesn't exist.\n", CODE_DENIED ); return; } int clevel = atoi(row[0]); res->destroy(); if (clevel != from) { daemon_printf( "%d current level is %d.\n", CODE_DENIED, clevel ); return; } sql = "UPDATE stardict_users SET level="; gchar *str = g_strdup_printf("%d", to); sql += str; g_free(str); sql += " WHERE username="******"%d query failed\n", CODE_DENIED ); return; } std::string text; text = "Set user level: "; text += user; text += ' '; text += fromlevel; text += ' '; text += tolevel; stardictdMain.logger->log(LOG_ACCOUNT, text.c_str()); daemon_printf( "%d\n", CODE_OK ); }
bool f_mysql_data_seek(CVarRef result, int row) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; return res->seekRow(row); }
bool f_mysql_async_query_completed(CVarRef result) { MySQLResult *res = result.toResource().getTyped<MySQLResult> (!RuntimeOption::ThrowBadTypeExceptions, !RuntimeOption::ThrowBadTypeExceptions); return !res || res->get() == NULL; }
static bool HHVM_FUNCTION(mysql_field_seek, const Resource& result, int field) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; return res->seekField(field); }
static void daemon_auth(std::string &user, std::string &key) { if (user == "guest") { daemon_printf( "%d\n", CODE_OK ); return; } char *buf; struct MD5Context ctx; unsigned char digest[16]; char hex[33]; if (user == "root") { std::string &root_password = stardictdMain.conf->get_str("root-user/password"); if (root_password.empty()) { daemon_printf( "%d auth denied\n", CODE_DENIED ); return; } MD5Init(&ctx); MD5Update(&ctx, (const unsigned char*)"StarDict", 8); //StarDict-Protocol 0.4, add md5 salt. MD5Update(&ctx, (const unsigned char*)root_password.c_str(), root_password.length()); MD5Final(digest, &ctx); for (int i = 0; i < 16; i++) snprintf( hex+2*i, 3, "%02x", digest[i] ); hex[32] = '\0'; buf = g_strdup_printf("%s%s", daemonStamp, hex); } else { if (init_database()) { daemon_printf( "%d Connect to MySQL failed!\n", CODE_DENIED ); return; } std::string sql; sql = "SELECT user_id, user_md5saltpassword, level FROM stardict_users WHERE username="******"%d Query failed!\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d Get result failed!\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (!row) { res->destroy(); daemon_printf( "%d User doesn't exist!\n", CODE_DENIED ); return; } userID = row[0]; userLevel = atoi(row[2]); stardictdMain.SetUserLevel(userLevel); buf = g_strdup_printf("%s%s", daemonStamp, row[1]); res->destroy(); } MD5Init(&ctx); MD5Update(&ctx, (const unsigned char*)buf, strlen(buf)); MD5Final(digest, &ctx); for (int i = 0; i < 16; i++) snprintf( hex+2*i, 3, "%02x", digest[i] ); hex[32] = '\0'; g_free(buf); if (key != hex) { daemon_printf( "%d auth denied\n", CODE_DENIED ); return; } else { daemon_printf( "%d authenticated\n", CODE_OK ); auth_user=user; if (auth_user == "root") { stardictdMain.SetDictMask("", 0, 0); } else { std::string sql; sql = "SELECT dictmask, collatefunc, language FROM user_basic WHERE id="; sql+= userID; if (stardictdMain.conn.query(sql.c_str(), sql.length())) { daemon_printf( "%d Query failed!\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d Get result failed!\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (row) { char *str = g_strdup_printf("level-%d-user/max_dict_count", userLevel); const int max_dict_count = stardictdMain.conf->get_int(str); g_free(str); stardictdMain.SetDictMask(row[0], max_dict_count, userLevel); bool enable_collate; if (userLevel == 0) { enable_collate = stardictdMain.conf->get_bool("level-0-user/enable_collate"); } else { enable_collate = true; } if (enable_collate) { stardictdMain.SetServerCollateFunc(atoi(row[1])); } else { stardictdMain.SetServerCollateFunc(0); } stardictdMain.SetUserLang(row[2]); } else { stardictdMain.SetDictMask("", 0, 0); stardictdMain.SetServerCollateFunc(0); } res->destroy(); } } }
Variant php_mysql_field_info(const Variant& result, int field, int entry_type) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; if (!res->seekField(field)) return false; MySQLFieldInfo *info; if (!(info = res->fetchFieldInfo())) return false; switch (entry_type) { case PHP_MYSQL_FIELD_NAME: return info->name; case PHP_MYSQL_FIELD_TABLE: return info->table; case PHP_MYSQL_FIELD_LEN: return info->length; case PHP_MYSQL_FIELD_TYPE: return php_mysql_get_field_name(info->type); case PHP_MYSQL_FIELD_FLAGS: { char buf[512]; buf[0] = '\0'; unsigned int flags = info->flags; #ifdef IS_NOT_NULL if (IS_NOT_NULL(flags)) { strcat(buf, "not_null "); } #endif #ifdef IS_PRI_KEY if (IS_PRI_KEY(flags)) { strcat(buf, "primary_key "); } #endif #ifdef UNIQUE_KEY_FLAG if (flags & UNIQUE_KEY_FLAG) { strcat(buf, "unique_key "); } #endif #ifdef MULTIPLE_KEY_FLAG if (flags & MULTIPLE_KEY_FLAG) { strcat(buf, "multiple_key "); } #endif #ifdef IS_BLOB if (IS_BLOB(flags)) { strcat(buf, "blob "); } #endif #ifdef UNSIGNED_FLAG if (flags & UNSIGNED_FLAG) { strcat(buf, "unsigned "); } #endif #ifdef ZEROFILL_FLAG if (flags & ZEROFILL_FLAG) { strcat(buf, "zerofill "); } #endif #ifdef BINARY_FLAG if (flags & BINARY_FLAG) { strcat(buf, "binary "); } #endif #ifdef ENUM_FLAG if (flags & ENUM_FLAG) { strcat(buf, "enum "); } #endif #ifdef SET_FLAG if (flags & SET_FLAG) { strcat(buf, "set "); } #endif #ifdef AUTO_INCREMENT_FLAG if (flags & AUTO_INCREMENT_FLAG) { strcat(buf, "auto_increment "); } #endif #ifdef TIMESTAMP_FLAG if (flags & TIMESTAMP_FLAG) { strcat(buf, "timestamp "); } #endif int len = strlen(buf); /* remove trailing space, if present */ if (len && buf[len-1] == ' ') { buf[len-1] = 0; len--; } return String(buf, len, CopyString); } default: break; } return false; }
static bool HHVM_FUNCTION(mysql_data_seek, const Resource& result, int row) { MySQLResult *res = php_mysql_extract_result(result); if (res == NULL) return false; return res->seekRow(row); }