You are here

function ip2country_update_database in IP-based Determination of a Visitor's Country 6

Same name and namespace in other branches
  1. 8 ip2country.inc \ip2country_update_database()
  2. 5 uc_ip2country.inc \ip2country_update_database()
  3. 7 ip2country.inc \ip2country_update_database()

Updates the database.

Truncates ip2country table then reloads from ftp servers.

Parameters

$registry: Regional Internet Registry from which to get the data. Allowed values are afrinic, apnic, arin (default), lacnic, or ripe.

5 calls to ip2country_update_database()
ip2countryTestCase::testDBDownload in ./ip2country.test
Tests DB download
ip2countryTestCase::testIPLookup in ./ip2country.test
Tests IP lookup for addresses in / not in the database.
ip2country_cron in ./ip2country.module
Implements hook_cron().
ip2country_install in ./ip2country.install
Implements hook_install().
_ip2country_update in ./ip2country.admin.inc
AJAX callback to update the IP to Country database.
2 string references to 'ip2country_update_database'
ip2country_uninstall in ./ip2country.install
Implements hook_uninstall().
ip2country_update_1 in ./ip2country.install
Rename tables and variables, clean up database.

File

./ip2country.inc, line 25
Utility routines to load the IP to Country database.

Code

function ip2country_update_database($registry = 'arin') {
  $registry = drupal_strtolower(trim($registry));

  // FTP files.
  if ($registry == 'afrinic') {

    // afrinic only holds its own data - every other NIC has all the data.
    $ftp_sites = array(
      'ftp://ftp.ripe.net/pub/stats/afrinic/delegated-afrinic-latest',
    );
  }
  else {

    // Note arin doesn't play by the file-naming rules.
    $ftp_sites = array(
      'ftp://ftp.ripe.net/pub/stats/arin/delegated-arin-extended-latest',
      'ftp://ftp.ripe.net/pub/stats/apnic/delegated-apnic-latest',
      'ftp://ftp.ripe.net/pub/stats/lacnic/delegated-lacnic-latest',
      'ftp://ftp.ripe.net/pub/stats/afrinic/delegated-afrinic-latest',
      'ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-latest',
    );
  }

  // Set a run-time long enough so the script won't break.
  set_time_limit(10 * 60);

  // 10 minutes!
  // Truncate the table to remove old data.
  ip2country_empty_database();

  // Download data files from the chosen registry.
  $entries = 0;
  $summary_records = 0;
  foreach ($ftp_sites as $ftp_file) {

    // Replace Registry source with chosen registry.
    $ftp_file = str_replace('ftp.ripe', 'ftp.' . $registry, $ftp_file);

    // RipeNCC is named ripe-ncc on APNIC registry.
    if ($registry == 'apnic') {
      $ftp_file = str_replace('stats/ripencc/', 'stats/ripe-ncc/', $ftp_file);
    }

    // Fetch the FTP file using cURL.
    $txt = _ip2country_fetch_page($ftp_file);

    // Break the FTP file into records.
    $lines = explode("\n", $txt);
    unset($txt);

    // Free up memory.
    // Loop over records.
    $summary_not_found = TRUE;
    foreach ($lines as $line) {

      // Trim each line for security.
      $line = trim($line);

      // Skip comment lines and blank lines.
      if (substr($line, 0, 1) == '#' || $line == '') {
        continue;
      }

      // Split record into parts.
      $parts = explode('|', $line);

      // We're only interested in the ipv4 records.
      if ($parts[2] != 'ipv4') {
        continue;
      }

      // Save number of ipv4 records from summary line.
      if ($summary_not_found && $parts[5] == 'summary') {
        $summary_not_found = FALSE;
        $summary_records += $parts[4];
        continue;
      }

      // The registry that owns the range.
      $owner_registry = $parts[0];

      // The country code for the range.
      $country_code = $parts[1];

      // Prepare the IP data for insert.
      $ip_start = (int) ip2long($parts[3]);
      $ip_end = (int) ip2long($parts[3]) + ($parts[4] - 1);
      $range_length = (int) $parts[4];

      // Prepare the query.
      $sql = "INSERT INTO {ip2country} (\n                country,\n                registry,\n                ip_range_first,\n                ip_range_last,\n                ip_range_length\n              )\n              VALUES ('%s', '%s', %d, %d, %d)";

      // Insert range into the DB.
      db_query($sql, $country_code, $owner_registry, min($ip_start, $ip_end), max($ip_start, $ip_end), $range_length);
      $entries++;
    }
    unset($lines);

    // Free up memory.
  }

  // Return record count in table.
  variable_set('ip2country_last_update', time());
  variable_set('ip2country_last_update_rir', drupal_strtoupper($registry));
  return $entries;
}