List maxmind_bindings::call_maxmind(std::vector < std::string > ip_addresses, const char* file, std::vector < std::string > fields){ //Open file MMDB_s geo_file; int result; result = MMDB_open(file, 0, &geo_file); if(result != MMDB_SUCCESS){ throw std::range_error("The geolocation database could not be opened"); } //Create references and holding std::vector < std::string >& ip_ref = ip_addresses; int input_size = ip_addresses.size(); IntegerVector rownames(input_size); rownames = Rcpp::seq(1,input_size); List output = lookup(ip_ref, &geo_file, fields); output.attr("class") = "data.frame"; output.attr("names") = fields; output.attr("row.names") = rownames; //Close and return MMDB_close(&geo_file); return output; }
MMDB_s *open_ok(const char *db_file, int mode, const char *mode_desc) { if (0 != access(db_file, R_OK)) { BAIL_OUT( "could not read the specified file - %s\nIf you are in a git checkout try running 'git submodule update --init'", db_file); } MMDB_s *mmdb = (MMDB_s *)calloc(1, sizeof(MMDB_s)); if (NULL == mmdb) { BAIL_OUT("could not allocate memory for our MMDB_s struct"); } int status = MMDB_open(db_file, mode, mmdb); int is_ok = ok(MMDB_SUCCESS == status, "open %s status is success - %s", db_file, mode_desc); if (!is_ok) { diag("open status code = %d (%s)", status, MMDB_strerror(status)); free(mmdb); return NULL; } is_ok = ok(NULL != mmdb, "returned mmdb struct is not null for %s - %s", db_file, mode_desc); if (!is_ok) { free(mmdb); return NULL; } return mmdb; }
vmod_geoip2__init(VRT_CTX, struct vmod_geoip2_geoip2 **vpp, const char *vcl_name, VCL_STRING filename) { struct vmod_geoip2_geoip2 *vp; MMDB_s mmdb; int error; (void)vcl_name; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(vpp); AZ(*vpp); VSL(SLT_Debug, 0, "geoip2.geoip2: Using maxminddb %s", MMDB_lib_version()); error = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb); if (error != MMDB_SUCCESS) { VSL(SLT_Error, 0, "geoip2.geoip2: %s", MMDB_strerror(error)); return; } ALLOC_OBJ(vp, VMOD_GEOIP2_MAGIC); AN(vp); *vpp = vp; vp->mmdb = mmdb; }
int main(void) { in_addrX ipnum; struct stat sstat; char *fname = get_test_db_fname(); int err = stat(fname, &sstat); ok(err == 0, "%s exists", fname); MMDB_s *mmdb = MMDB_open(fname, MMDB_MODE_MEMORY_CACHE); ok(mmdb != NULL, "MMDB_open successful"); if (mmdb) { MMDB_root_entry_s root = {.entry.mmdb = mmdb }; char *ipstr = "24.24.24.24"; ip_to_num(mmdb, ipstr, &ipnum); err = MMDB_lookup_by_ipnum_128(ipnum.v6, &root); ok(err == MMDB_SUCCESS, "Search for %s SUCCESSFUL", ipstr); ok(root.entry.offset > 0, "Found something %s good", ipstr); MMDB_decode_all_s *decode_all; int err = MMDB_get_tree(&root.entry, &decode_all); if (err == MMDB_SUCCESS) { if (decode_all != NULL) MMDB_dump(mmdb, decode_all, 0); MMDB_free_decode_all(decode_all); } } done_testing(); }
CAMLprim value mmdb_ml_open(value s) { CAMLparam1(s); CAMLlocal1(mmdb_handle); if (polymorphic_variants.poly_bool == 0 || polymorphic_variants.poly_float == 0 || polymorphic_variants.poly_int == 0 || polymorphic_variants.poly_string == 0) { polymorphic_variants.poly_bool = caml_hash_variant("Bool"); polymorphic_variants.poly_float = caml_hash_variant("Float"); polymorphic_variants.poly_int = caml_hash_variant("Int"); polymorphic_variants.poly_string = caml_hash_variant("String"); } unsigned int len = caml_string_length(s); char *copied = caml_strdup(String_val(s)); if (strlen(copied) != (size_t)len) { caml_failwith("Could not open MMDB database"); } MMDB_s *this_db = caml_stat_alloc(sizeof(*this_db)); int status = MMDB_open(copied, MMDB_MODE_MMAP, this_db); mmdb_handle = caml_alloc_custom(&mmdb_custom_ops, sizeof(*this_db), 0, 1); check_status(status); memcpy(Data_custom_val(mmdb_handle), this_db, sizeof(*this_db)); caml_stat_free(this_db); caml_stat_free(copied); CAMLreturn(mmdb_handle); }
static char * ngx_http_geoip2(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_geoip2_conf_t *gcf = conf; ngx_str_t *value; int status, nelts, i; ngx_http_geoip2_db_t *database; char *rv; ngx_conf_t save; value = cf->args->elts; if (gcf->databases == NULL) { gcf->databases = ngx_array_create(cf->pool, 2, sizeof(ngx_http_geoip2_db_t)); if (gcf->databases == NULL) { return NGX_CONF_ERROR; } } else { nelts = (int) gcf->databases->nelts; database = gcf->databases->elts; for (i = 0; i < nelts; i++) { if (ngx_strcmp(value[1].data, database[i].mmdb.filename) == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "Duplicate GeoIP2 mmdb - %V", &value[1]); return NGX_CONF_ERROR; } } } database = ngx_array_push(gcf->databases); if (database == NULL) { return NGX_CONF_ERROR; } status = MMDB_open((char *) value[1].data, MMDB_MODE_MMAP, &database->mmdb); if (status != MMDB_SUCCESS) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "MMDB_open(\"%V\") failed - %s", &value[1], MMDB_strerror(status)); return NGX_CONF_ERROR; } #if (NGX_HAVE_INET6) ngx_memset(&database->address, 0, sizeof(database->address)); #else database->address = 0; #endif save = *cf; cf->handler = ngx_http_geoip2_add_variable; cf->handler_conf = (void *) database; rv = ngx_conf_parse(cf, NULL); *cf = save; return rv; }
int geoip2_init_pv(char *path) { int status = MMDB_open(path, MMDB_MODE_MMAP, &_handle_GeoIP); if(MMDB_SUCCESS != status) { LM_ERR("cannot open GeoIP database file at: %s\n", path); return -1; } return 0; }
bool Init( void ) { if ( handle ) { return true; } handle = new MMDB_s{}; int status = -1; char fs_gameString[MAX_CVAR_VALUE_STRING]; trap->Cvar_VariableStringBuffer( "fs_game", fs_gameString, sizeof(fs_gameString) ); const char *sPath = va( "%s/GeoLite2-Country.mmdb", fs_gameString ); trap->Print( "Loading %s\n", sPath ); fileHandle_t f = NULL_FILE; unsigned int len = trap->FS_Open( sPath, &f, FS_READ ); // no file if ( !f ) { return false; } // empty file if ( !len || len == -1 ) { trap->FS_Close( f ); return false; } // alloc memory for buffer char *buf = (char *)malloc( len + 1 ); if ( !buf ) { return false; } trap->FS_Read( buf, len, f ); trap->FS_Close( f ); buf[len] = '\0'; // pass it off to the json reader char *tmpFilePath = nullptr; trap->Print( "writing to temporary file\n" ); if ( WriteToTemporaryFile( buf, len, &tmpFilePath ) ) { trap->Print( "loading from temporary file %s\n", tmpFilePath ); if ( (status = MMDB_open( tmpFilePath, MMDB_MODE_MMAP, handle ) ) != MMDB_SUCCESS ) { trap->Print( "Error occured while initialising MaxMind GeoIP: \"%s\"\n", MMDB_strerror( status ) ); delete handle; handle = nullptr; return false; } } free( buf ); return true; }
static int Reader_init(PyObject *self, PyObject *args, PyObject *kwds) { char *filename; int mode = 0; static char *kwlist[] = {"database", "mode", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &filename, &mode)) { return -1; } if (mode != 0 && mode != 1) { PyErr_Format(PyExc_ValueError, "Unsupported open mode (%i). Only " "MODE_AUTO and MODE_MMAP_EXT are supported by this extension.", mode); return -1; } if (0 != access(filename, R_OK)) { PyErr_Format(FILE_NOT_FOUND_ERROR, "No such file or directory: '%s'", filename); return -1; } MMDB_s *mmdb = (MMDB_s *)malloc(sizeof(MMDB_s)); if (NULL == mmdb) { PyErr_NoMemory(); return -1; } Reader_obj *mmdb_obj = (Reader_obj *)self; if (!mmdb_obj) { free(mmdb); PyErr_NoMemory(); return -1; } uint16_t status = MMDB_open(filename, MMDB_MODE_MMAP, mmdb); if (MMDB_SUCCESS != status) { free(mmdb); PyErr_Format( MaxMindDB_error, "Error opening database file (%s). Is this a valid MaxMind DB file?", filename ); return -1; } mmdb_obj->mmdb = mmdb; return 0; }
int geoip2_open_db(void) { int rc; if ((rc = MMDB_open(MMG_city_db_path.s, MMDB_MODE_MMAP, &mmdb)) != MMDB_SUCCESS) { if (rc == MMDB_IO_ERROR) LM_ERR("IO error: %s\n", strerror(errno)); LM_ERR("Unable to open City DB at path '%.*s'\n", (int)strlen(MMG_city_db_path.s),MMG_city_db_path.s); return -1; } return 0; }
static VALUE geoip2_compat_initialize(VALUE self, VALUE path) { Check_Type(path, T_STRING); char* db = StringValuePtr(path); MMDB_s *mmdb; Data_Get_Struct(self, MMDB_s, mmdb); int status = MMDB_open(db, MMDB_MODE_MMAP, mmdb); if (status != MMDB_SUCCESS) { rb_raise(egeoip2_compat_Exception, "GeoIP2Compat - %s: %s", MMDB_strerror(status), db ); } return self; }
// ------------------------------------------------------------------------------------------------ DbHnd::DbHnd(CSStr filepath, Uint32 flags) : mDb() { // Validate the specified file path if (!filepath || *filepath == '\0') { STHROWF("Invalid database file path"); } // Let's attempt to open the specified database const Int32 status = MMDB_open(filepath, flags, &mDb); // Validate the result of the operation if (status != MMDB_SUCCESS) { STHROWF("Unable to open the specified database [%s]", MMDB_strerror(status)); } }
// Open the maxmind db file int open_mmdb(MMDB_s *mmdb_handle) { int mmdb_baddb = MMDB_open(MMDB_CITY_PATH, MMDB_MODE_MMAP, mmdb_handle); if (mmdb_baddb != MMDB_SUCCESS) { #if DEBUG fprintf(stderr, "[ERROR] open_mmdb: Can't open %s - %s\n", MMDB_CITY_PATH, MMDB_strerror(mmdb_baddb)); if (MMDB_IO_ERROR == mmdb_baddb) { fprintf(stderr, "[ERROR] open_mmdb: IO error: %s\n", strerror(mmdb_baddb)); } #endif mmdb_handle = NULL; return 1; } return 0; }
LOCAL MMDB_s open_or_die(const char *fname) { MMDB_s mmdb; int status = MMDB_open(fname, MMDB_MODE_MMAP, &mmdb); if (MMDB_SUCCESS != status) { fprintf(stderr, "\n Can't open %s - %s\n", fname, MMDB_strerror(status)); if (MMDB_IO_ERROR == status) { fprintf(stderr, " IO error: %s\n", strerror(errno)); } fprintf(stderr, "\n"); exit(2); } return mmdb; }
int main(void) { int gai_error, mmdb_error; MMDB_s mmdb; char *ip = "8.8.8.8"; int status = MMDB_open("/home/lannister/Documentos/GeoLite2-City.mmdb", MMDB_MODE_MMAP, &mmdb); if (MMDB_SUCCESS != status) { printf("Fail WTF"); } MMDB_lookup_result_s result = MMDB_lookup_string(&mmdb, ip, &gai_error, &mmdb_error); if (MMDB_SUCCESS != mmdb_error) { printf("Fail WTF2"); } int exit_code = 0; char *country = NULL; MMDB_entry_data_s entry_data; status = MMDB_get_value(&result.entry, &entry_data,"city","names","es", NULL); if (entry_data.has_data) { country = strndup(entry_data.utf8_string, entry_data.data_size); printf("%s\n", country); }else{ printf("No city"); } status = MMDB_get_value(&result.entry, &entry_data,"country","names","es", NULL); if (entry_data.has_data) { country = strndup(entry_data.utf8_string, entry_data.data_size); printf("%s\n", country); } MMDB_close(&mmdb); return 0; }
int main(int argc, char *const argv[]) { int verbose = 0; int character; char *fname = NULL; while ((character = getopt(argc, argv, "vf:")) != -1) { switch (character) { case 'v': verbose = 1; break; case 'f': fname = strdup(optarg); break; default: case '?': usage(argv[0]); } } argc -= optind; argv += optind; if (!fname) { fname = strdup(MMDB_DEFAULT_DATABASE); } assert(fname != NULL); //MMDB_s *mmdb = MMDB_open(fname, MMDB_MODE_MEMORY_CACHE); MMDB_s *mmdb = MMDB_open(fname, MMDB_MODE_STANDARD); if (!mmdb) die("Can't open %s\n", fname); free(fname); char *ipstr = argv[0]; union { struct in_addr v4; struct in6_addr v6; } ip; int ai_family = is_ipv4(mmdb) ? AF_INET : AF_INET6; int ai_flags = AI_V4MAPPED; // accept everything if (ipstr == NULL || 0 != MMDB_resolve_address(ipstr, ai_family, ai_flags, &ip)) { fprintf(stderr, "Invalid IP\n"); exit(1); } if (verbose) { dump_meta(mmdb); } MMDB_root_entry_s root = {.entry.mmdb = mmdb }; int status = is_ipv4(mmdb) ? MMDB_lookup_by_ipnum(htonl(ip.v4.s_addr), &root) : MMDB_lookup_by_ipnum_128(ip.v6, &root); if (status == MMDB_SUCCESS) { dump_ipinfo(ipstr, &root); } return (0); }
CODESTARTactivateCnf runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance int status = MMDB_open(pData->pszMmdbFile, MMDB_MODE_MMAP, &pWrkrData->mmdb); if(MMDB_SUCCESS != status) { dbgprintf("Can't open %s - %s\n", pData->pszMmdbFile, MMDB_strerror(status)); if(MMDB_IO_ERROR == status) { dbgprintf(" IO error: %s\n", strerror(errno)); } errmsg.LogError(0, RS_RET_SUSPENDED, "can not initialize maxminddb"); // ABORT_FINALIZE(RS_RET_SUSPENDED); } ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature ENDisCompatibleWithFeature
void test_mmdb(MMDB_s * mmdb) { char *ipstr; char *(*ip_string)[2] = mmdb->depth == 32 ? ip4_string : ip6_string; for (int i = 0; (ipstr = ip_string[i][0]); i++) { in_addrX ipnum; MMDB_root_entry_s root = {.entry.mmdb = mmdb }; ip_to_num(mmdb, ipstr, &ipnum); int err = mmdb->depth == 32 ? MMDB_lookup_by_ipnum(ipnum.v4.s_addr, &root) : MMDB_lookup_by_ipnum_128(ipnum.v6, &root); ok(err == MMDB_SUCCESS, "Search for %s SUCCESSFUL", ipstr); ok(root.entry.offset == 0, "No entries found for %s good", ipstr); ipstr = ip_string[i][1]; ip_to_num(mmdb, ipstr, &ipnum); err = mmdb->depth == 32 ? MMDB_lookup_by_ipnum(ipnum.v4.s_addr, &root) : MMDB_lookup_by_ipnum_128(ipnum.v6, &root); ok(err == MMDB_SUCCESS, "Search for %s SUCCESSFUL", ipstr); ok(root.entry.offset > 0, "Found something %s good", ipstr); MMDB_return_s country; MMDB_get_value(&root.entry, &country, "country", NULL); ok(country.offset > 0, "Found country hash for %s", ipstr); if (country.offset) { MMDB_entry_s country_hash = {.mmdb = mmdb,.offset = country.offset }; MMDB_return_s result; MMDB_get_value(&country_hash, &result, "iso_code", NULL); ok(result.offset > 0, "Found country code for %s", ipstr); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "US") == 0, "Country code is US for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "ascii", NULL); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "United States") == 0, "Country name ascii match United States for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "de", NULL); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "USA") == 0, "Country name de is USA for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "es", NULL); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "Estados Unidos") == 0, "Country name es is Estados Unidos for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "whatever", NULL); ok(result.offset == 0, "Country name whatever is not found for %s", ipstr); MMDB_return_s military, cellular, flt, dbl; MMDB_get_value(&root.entry, &military, "traits", "is_military", NULL); ok(military.offset != 0, "traits/is_military _is_ found for %s", ipstr); ok(military.type == MMDB_DTYPE_BOOLEAN, "is_military.type _is_ MMDB_DTYPE_BOOLEAN for %s", ipstr); ok(military.uinteger == 0, "traits/is_military _is_ 0"); MMDB_get_value(&root.entry, &cellular, "traits", "cellular", NULL); ok(cellular.offset != 0, "traits/cellular _is_ found for %s", ipstr); ok(cellular.type == MMDB_DTYPE_BOOLEAN, "cellular.type _is_ MMDB_DTYPE_BOOLEAN for %s", ipstr); ok(cellular.uinteger == 1, "traits/is_cellular _is_ 1"); MMDB_get_value(&root.entry, &flt, "test_data", "max", "float_t", NULL); ok(flt.offset != 0, "test_data/max/float_t _is_ found for %s", ipstr); ok(flt.type == MMDB_DTYPE_IEEE754_FLOAT, "flt.type _is_ MMDB_DTYPE_IEEE754_FLOAT for %s", ipstr); ok(!dbl_cmp(flt.float_value, 9999.99), "test_data/max/float_t _is_ nearly 9999.99"); MMDB_get_value(&root.entry, &dbl, "test_data", "max", "double_t", NULL); ok(dbl.offset != 0, "test_data/max/double_t _is_ found for %s", ipstr); ok(dbl.type == MMDB_DTYPE_IEEE754_DOUBLE, "dbl.type _is_ MMDB_DTYPE_IEEE754_DOUBLE for %s", ipstr); ok(!dbl_cmp(dbl.double_value, 999999999.9999), "test_data/max/double_t _is_ nearly 999999999.9999"); { double expect[] = { 0.000000, 0.000000, 1.000000, 0.100000, 0.123000, 10.000000, 7.990000, 1000000000.000000, -1.000000, -0.100000, -0.123000, -10.000000, -7.990000, -1000000000.000000 }; int cnt = sizeof(expect) / sizeof(double); MMDB_return_s got; MMDB_get_value(&root.entry, &dbl, "test_data", "tst", "array_ieee754_double_t", NULL); ok(dbl.offset > 0, "Found it"); if (dbl.offset > 0) { MMDB_entry_s dbl_array = {.mmdb = mmdb,.offset = dbl.offset }; for (int i = 0; i < cnt; i++) { char idx[256]; snprintf(idx, sizeof(idx), "%d", i); MMDB_get_value(&dbl_array, &got, idx, NULL); ok(got.offset != 0, "Found something"); ok(got.type == MMDB_DTYPE_IEEE754_DOUBLE, "type ok (is %d)", got.type); ok(!dbl_cmp(got.double_value, expect[i]), "test_data/max/double_t _is_ nearly %f", expect[i]); } check_illegal_index(&dbl_array, -1); check_illegal_index(&dbl_array, cnt); } } } } } int main(void) { char *fnames[] = { "./data/v4-24.mmdb", "./data/v4-28.mmdb", "./data/v4-32.mmdb", "./data/v6-24.mmdb", "./data/v6-28.mmdb", "./data/v6-32.mmdb", NULL }; char *fname; for (char **ptr = fnames; (fname = *ptr++);) { struct stat sstat; int err = stat(fname, &sstat); ok(err == 0, "%s exists", fname); MMDB_s *mmdb_m = MMDB_open(fname, MMDB_MODE_MEMORY_CACHE); ok(mmdb_m != NULL, "MMDB_open successful ( MMDB_MODE_MEMORY_CACHE )"); if (mmdb_m) { test_mmdb(mmdb_m); MMDB_close(mmdb_m); } MMDB_s *mmdb_s = MMDB_open(fname, MMDB_MODE_STANDARD); ok(mmdb_s != NULL, "MMDB_open successful ( MMDB_MODE_STANDARD )"); if (mmdb_s) { test_mmdb(mmdb_s); MMDB_close(mmdb_s); } } done_testing(); }
bool loadDatabase() { const auto isDatabaseLoaded = HandleDB.filename != nullptr; if (isDatabaseLoaded) { return true; } const char *databases[] = { "City", "Country" // Is the default shipped database with AMXX. }; const auto modName = MF_GetModname(); const auto dataDir = MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"); char file[260]; auto status = -1; for (auto& database : databases) { // MF_BuildPathname not used because backslash // makes CreateFileMapping failing under windows. ke::SafeSprintf(file, sizeof file, "%s/%s/GeoLite2-%s.mmdb", modName, dataDir, database); status = MMDB_open(file, MMDB_MODE_MMAP, &HandleDB); if (status == MMDB_SUCCESS) { break; } if (status != MMDB_FILE_OPEN_ERROR) { MF_Log("Could not open %s - %s", file, MMDB_strerror(status)); if (status == MMDB_IO_ERROR) { MF_Log(" IO error: %s", strerror(errno)); } } } if (status != MMDB_SUCCESS) { MF_Log("Could not find GeoIP2 databases. Disabled natives."); return false; } MF_Log("Database info: %s %i.%i", HandleDB.metadata.description.descriptions[0]->description, HandleDB.metadata.binary_format_major_version, HandleDB.metadata.binary_format_minor_version); // Retrieve supported languages. for (size_t i = 0; i < HandleDB.metadata.languages.count; i++) { LangList.append(ke::AString(HandleDB.metadata.languages.names[i])); } return true; }
static geoip2_t* geoip2_new(const char* pathname, const char* map_name, dclists_t* dclists, const dcmap_t* dcmap, const bool city_auto_mode, const bool city_no_region) { dmn_assert(pathname); dmn_assert(map_name); dmn_assert(dclists); geoip2_t* db = xcalloc(1, sizeof(*db)); int status = MMDB_open(pathname, MMDB_MODE_MMAP, &db->mmdb); if(status != MMDB_SUCCESS) { dmn_log_err("plugin_geoip: map '%s': Failed to open GeoIP2 database '%s': %s", map_name, pathname, MMDB_strerror(status)); free(db); return NULL; } MMDB_metadata_s* meta = &db->mmdb.metadata; if(!geoip2_mmdb_log_meta(meta, map_name, pathname)) { geoip2_destroy(db); return NULL; } // The database format spec indicates that minor version bumps // should be backwards compatible, so we only need to check // the major version here. if(meta->binary_format_major_version != 2U) { dmn_log_err("plugin_geoip: map '%s': GeoIP2 database '%s' has" " unsupported binfmt major version %" PRIu16, map_name, pathname, meta->binary_format_major_version ); geoip2_destroy(db); return NULL; } // Both our own code and the current libmaxminddb seem to have // built-in assumptions based on record_size of 32 or less, // yet the spec allows for larger in the future. if(meta->record_size > 32U) { dmn_log_err("plugin_geoip: map '%s': GeoIP2 database '%s' has" " unsupported record_size %" PRIu16, map_name, pathname, meta->record_size ); geoip2_destroy(db); return NULL; } if(meta->ip_version != 4U && meta->ip_version != 6U) { dmn_log_err("plugin_geoip: map '%s': GeoIP2 database '%s' has" " unsupported ip_version %" PRIu16, map_name, pathname, meta->ip_version ); geoip2_destroy(db); return NULL; } // The check for /City/ is how the official Perl API detects // the City-level data model, so it's probably a reliable bet. // We assume anything that didn't match /City/ is a Country-level // database. This will technically "work" for GeoIP2 if there is no // Country-level info, but everything will default. So, warn about the // Country defaulting if the database_type does not match /Country/. db->is_city = !!strstr(meta->database_type, "City"); if(!db->is_city) { if(city_auto_mode) { dmn_log_err("plugin_geoip: map '%s': GeoIP2 DB '%s' is not a City-level" " database and this map uses auto_dc_coords", map_name, pathname); geoip2_destroy(db); return NULL; } if(!strstr(meta->database_type, "Country")) dmn_log_warn("plugin_geoip: map '%s': Assuming GeoIP2 database '%s'" " has standard MaxMind Country data, but type is actually '%s'", map_name, pathname, meta->database_type ); } db->is_v4 = meta->ip_version == 4U; db->city_auto_mode = city_auto_mode; db->city_no_region = city_no_region; db->pathname = strdup(pathname); db->map_name = strdup(map_name); db->dclists = dclists; db->dcmap = dcmap; return db; }
bool Init( void ) { if ( handle ) { return true; } handle = new MMDB_s{}; int status = -1; const char *sPath = "GeoLite2-Country.mmdb"; trap->Print( "Loading %s\n", sPath ); fileHandle_t f = NULL_FILE; unsigned int len = trap->FS_Open( sPath, &f, FS_READ ); // no file if ( !f ) { return false; } // empty file if ( !len || len == -1 ) { trap->FS_Close( f ); return false; } // alloc memory for buffer char *buf = (char *)malloc( len + 1 ); if ( !buf ) { return false; } trap->FS_Read( buf, len, f ); trap->FS_Close( f ); buf[len] = '\0'; const char *extension = nullptr; for ( const char *p = sPath + strlen(sPath); p != sPath; p-- ) { if ( *p == '.' ) { extension = p; break; } } char *tmpFilePath = nullptr; if ( WriteToTemporaryFile( buf, len, &tmpFilePath, extension ) ) { trap->Print( "Failed to create temporary file\n" ); free( buf ); return false; } trap->Print( "loading from temporary file %s\n", tmpFilePath ); status = MMDB_open( tmpFilePath, MMDB_MODE_MMAP, handle ); if ( status != MMDB_SUCCESS ) { trap->Print( "Error occured while initialising MaxMind GeoIP: \"%s\"\n", MMDB_strerror( status ) ); delete handle; handle = nullptr; free( tmpFilePath ); free( buf ); return false; } free( tmpFilePath ); free( buf ); return true; }