├── php ├── qqwry │ ├── EXPERIMENTAL │ ├── TODO │ ├── CREDITS │ ├── LICENSE │ ├── libqqwry │ │ ├── .svn │ │ │ ├── entries │ │ │ ├── format │ │ │ ├── wc.db │ │ │ └── pristine │ │ │ │ ├── 15 │ │ │ │ └── 15a982719c88bdf3a6aea29555df64f660a97c22.svn-base │ │ │ │ └── 76 │ │ │ │ └── 76ac71edc639914c0ffddd503f6fe37c3fd82ece.svn-base │ │ ├── qqwry.h │ │ └── qqwry.c │ ├── INSTALL │ ├── config.w32 │ ├── tests │ │ └── qqwry.phpt │ ├── qqwry.php │ ├── test.php │ ├── config.m4 │ ├── package.xml │ ├── php_qqwry.h │ └── qqwry.c └── geoip │ ├── tests │ ├── 003.phpt │ ├── 008.phpt │ ├── 009.phpt │ ├── 001.phpt │ ├── 015.phpt │ ├── 006.phpt │ ├── 011.phpt │ ├── 007.phpt │ ├── 013.phpt │ ├── 005.phpt │ ├── 004.phpt │ ├── 010.phpt │ ├── 017.phpt │ ├── 018.phpt │ ├── 014.phpt │ ├── 016.phpt │ └── 002.phpt │ ├── README │ ├── config.w32 │ ├── geoip.def │ ├── LICENSE │ ├── php_geoip.h │ ├── ChangeLog │ ├── config.m4 │ ├── package.xml │ └── geoip.c ├── nali ├── LICENSE ├── bin │ ├── nali-dig │ ├── nali-ping │ ├── nali-nslookup │ ├── nali-tracepath │ └── nali-traceroute ├── INSTALL ├── README ├── share │ ├── nali.sh │ └── nali.pl ├── libqqwry │ ├── qqwry.h │ └── qqwry.c ├── Makefile ├── nali.c └── configure ├── README.md ├── libs ├── libqqwry.h └── libqqwry.c ├── libqqwry ├── qqwry.h └── qqwry.c └── tools ├── check-index.php ├── dump-location.php └── charset-convert.php /php/qqwry/EXPERIMENTAL: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /php/qqwry/TODO: -------------------------------------------------------------------------------- 1 | no to do 2 | -------------------------------------------------------------------------------- /php/qqwry/CREDITS: -------------------------------------------------------------------------------- 1 | surfchen 2 | -------------------------------------------------------------------------------- /php/qqwry/LICENSE: -------------------------------------------------------------------------------- 1 | New BSD 2 | -------------------------------------------------------------------------------- /nali/LICENSE: -------------------------------------------------------------------------------- 1 | 除非特别声明,否则所有文件均以GPL授权 2 | -------------------------------------------------------------------------------- /php/qqwry/libqqwry/.svn/entries: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /php/qqwry/libqqwry/.svn/format: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /nali/bin/nali-dig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | dig $@ 2>&1|nali 3 | -------------------------------------------------------------------------------- /nali/bin/nali-ping: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ping $@ 2>&1|nali 3 | -------------------------------------------------------------------------------- /nali/INSTALL: -------------------------------------------------------------------------------- 1 | ./configure 2 | make 3 | [sudo] make install 4 | -------------------------------------------------------------------------------- /nali/bin/nali-nslookup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | nslookup $@ 2>&1|nali 3 | -------------------------------------------------------------------------------- /php/qqwry/INSTALL: -------------------------------------------------------------------------------- 1 | see http://www.surfchen.org/wiki/QQWry 2 | -------------------------------------------------------------------------------- /nali/bin/nali-tracepath: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | tracepath $@ 2>&1|nali 3 | -------------------------------------------------------------------------------- /nali/bin/nali-traceroute: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | traceroute $@ 2>&1|nali 3 | -------------------------------------------------------------------------------- /nali/README: -------------------------------------------------------------------------------- 1 | 编译和安装请看INSTALL 2 | 3 | 项目主页:http://www.surfchen.org/nali 4 | -------------------------------------------------------------------------------- /php/qqwry/libqqwry/.svn/wc.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soffchen/qqwry/HEAD/php/qqwry/libqqwry/.svn/wc.db -------------------------------------------------------------------------------- /nali/share/nali.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if test $# -gt 0 3 | then 4 | echo $@|perl __DATADIR/nali.pl 5 | else 6 | perl __DATADIR/nali.pl 7 | fi 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # qqwry 2 | Fork from https://code.google.com/p/qqwry/ 3 | 4 | * qqwry.c,qqwry.h: 一个 c 实现的 lib,用来从纯真数据库里获取 ip 地址信息 5 | * nali: 一组 ip 查询工具,包括可以让 dig, traceroute 显示 ip 地理信息 6 | * pecl::qqwry: 纯真数据库查询的 PHP C 扩展实现 7 | * 纯真数据库 UTF-8 版本: 转换工具也以开源形式发布,用 php 实现 -------------------------------------------------------------------------------- /php/geoip/tests/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for database filename 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECTF-- 12 | string(%d) "%sGeoIP.dat" 13 | -------------------------------------------------------------------------------- /php/geoip/tests/008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Calling geoip_db_filename() with a non-existant database type within bound. 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | NULL 13 | -------------------------------------------------------------------------------- /php/geoip/tests/009.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Calling geoip_db_avail() with a non-existant database type within bound. 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | bool(false) 13 | -------------------------------------------------------------------------------- /php/geoip/tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking Country (Free) DB availability 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | bool(true) 15 | -------------------------------------------------------------------------------- /php/geoip/tests/015.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_region_name_by_code for Canada/Quebec 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(6) "Quebec" 15 | -------------------------------------------------------------------------------- /php/geoip/tests/006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for custom directory INI entry 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test" 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(15) "/test/GeoIP.dat" 15 | -------------------------------------------------------------------------------- /php/geoip/tests/011.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Calling geoip_database_info() with a non-existant database type within bound. 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECTF-- 12 | Warning: geoip_database_info(): Required database not available. in %s on line %d 13 | -------------------------------------------------------------------------------- /php/qqwry/config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | // If your extension references something external, use ARG_WITH 5 | // ARG_WITH("qqwry", "for qqwry support", "no"); 6 | 7 | // Otherwise, use ARG_ENABLE 8 | // ARG_ENABLE("qqwry", "enable qqwry support", "no"); 9 | 10 | if (PHP_QQWRY != "no") { 11 | EXTENSION("qqwry", "qqwry.c"); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /php/geoip/tests/007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for custom directory INI entry (with trailing slash) 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test/" 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(15) "/test/GeoIP.dat" 15 | -------------------------------------------------------------------------------- /php/geoip/README: -------------------------------------------------------------------------------- 1 | This PHP extension allows you to find the location of an IP address - City, State, 2 | Country, Longitude, Latitude, and other information as all, such as ISP and connection type. 3 | 4 | To compile it, you will need to have the GeoIP c library installed. 5 | 6 | For installation instructions for PHP extensions, see: 7 | http://www.php.net/manual/en/install.pecl.php 8 | -------------------------------------------------------------------------------- /php/geoip/tests/013.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking timezone info 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(16) "America/Montreal" 15 | string(10) "Asia/Tokyo" 16 | -------------------------------------------------------------------------------- /php/geoip/tests/005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for out of bound type with geoip_db_avail() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECTF-- 13 | Warning: geoip_db_avail(): Database type given is out of bound. in %s on line %d 14 | 15 | Warning: geoip_db_avail(): Database type given is out of bound. in %s on line %d 16 | 17 | -------------------------------------------------------------------------------- /php/geoip/tests/004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for out of bound type with geoip_db_filename() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECTF-- 13 | Warning: geoip_db_filename(): Database type given is out of bound. in %s on line %d 14 | 15 | Warning: geoip_db_filename(): Database type given is out of bound. in %s on line %d 16 | 17 | -------------------------------------------------------------------------------- /php/geoip/tests/010.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for out of bound type with geoip_database_info() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECTF-- 13 | Warning: geoip_database_info(): Database type given is out of bound. in %s on line %d 14 | 15 | Warning: geoip_database_info(): Database type given is out of bound. in %s on line %d 16 | 17 | -------------------------------------------------------------------------------- /php/geoip/tests/017.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_setup_custom_directory() 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test" 7 | --FILE-- 8 | 15 | --EXPECT-- 16 | string(27) "/some/other/place/GeoIP.dat" 17 | string(5) "/test" -------------------------------------------------------------------------------- /php/geoip/tests/018.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_setup_custom_directory() (with trailing slash) 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test/" 7 | --FILE-- 8 | 15 | --EXPECT-- 16 | string(27) "/some/other/place/GeoIP.dat" 17 | string(6) "/test/" -------------------------------------------------------------------------------- /libs/libqqwry.h: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | * 请自己给addr1和addr2分配内存,我的建议是:addr1为64字节,addr2为128字节。 4 | * 这个库不会自己分配内存,而是把结果写入addr1和addr2的内存。 5 | * 这样的设计可以使得调用方更方便地使用自己的内存机制。 6 | * 7 | * addr1是大的范围,例如南宁市 8 | * addr2是小的范围,例如邕宁区 9 | * 10 | * get_location和get_location_by_log的区别是前者传递的ip是一个字符串,例如 11 | * 222.89.22.122,这个也是我们通常所用的格式;后者传递的ip是一个十进制的ipv4地址 12 | */ 13 | int qqwry_get_location(char *addr1,char *addr2,const char *ip,FILE *qqwry_file); 14 | int qqwry_get_location_by_long(char *addr1,char *addr2,const uint32_t ip,FILE *qqwry_file); 15 | -------------------------------------------------------------------------------- /php/qqwry/tests/qqwry.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check for qqwry presence 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 20 | --EXPECT-- 21 | need additional file before testing 22 | -------------------------------------------------------------------------------- /php/geoip/config.w32: -------------------------------------------------------------------------------- 1 | // $Id: config.w32 327850 2012-10-01 12:50:22Z ab $ 2 | // vim:ft=javascript 3 | 4 | ARG_WITH("geoip", "GeoIP Support", "no"); 5 | 6 | if (PHP_GEOIP == "yes") { 7 | if (CHECK_HEADER_ADD_INCLUDE("geoip.h", "CFLAGS_GEOIP", PHP_GEOIP + ";" + PHP_PHP_BUILD + "\\include\\geoip") && 8 | CHECK_LIB("geoip_a.lib;GeoIP.lib", "geoip", PHP_GEOIP)) { 9 | AC_DEFINE('HAVE_GEOIP', 1, 'Have GeoIP support', false); 10 | AC_DEFINE('LIBGEOIP_VERSION', 1004008, 'GeoIP Version'); 11 | AC_DEFINE('HAVE_CUSTOM_DIRECTORY', 1, 'Support for custom database directory'); 12 | EXTENSION("geoip", "geoip.c"); 13 | } else { 14 | WARNING('Could not find geoip.h or geoip lib; skipping'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /php/qqwry/qqwry.php: -------------------------------------------------------------------------------- 1 | "; 3 | if(!extension_loaded('qqwry')) { 4 | dl('qqwry.' . PHP_SHLIB_SUFFIX); 5 | } 6 | $qqwry=new qqwry('/Users/surfchen/projects/qqwry/nali/php/QQWry.Dat'); 7 | 8 | list($addr1,$addr2)=$qqwry->q('127.0.0.1'); 9 | $addr1=iconv('GB2312','UTF-8',$addr1); 10 | $addr2=iconv('GB2312','UTF-8',$addr2); 11 | echo $addr1,'|',$addr2,"\n"; 12 | 13 | $arr=$qqwry->q('222.216.47.4'); 14 | $arr[0]=iconv('GB2312','UTF-8',$arr[0]); 15 | $arr[1]=iconv('GB2312','UTF-8',$arr[1]); 16 | echo $arr[0],'|',$arr[1],"\n"; 17 | 18 | $arr=$qqwry->q('64.233.187.99'); 19 | $arr[0]=iconv('GB2312','UTF-8',$arr[0]); 20 | $arr[1]=iconv('GB2312','UTF-8',$arr[1]); 21 | echo $arr[0],'|',$arr[1],"\n"; 22 | ?> 23 | -------------------------------------------------------------------------------- /libqqwry/qqwry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Surf Chen 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | /* 12 | * 请自己给addr1和addr2分配内存,我的建议是:addr1为64字节,addr2为128字节。 13 | * 这个库不会自己分配内存,而是把结果写入addr1和addr2的内存。 14 | * 这样的设计可以使得调用方更方便地使用自己的内存机制。 15 | * 16 | * addr1是大的范围,例如南宁市 17 | * addr2是小的范围,例如邕宁区 18 | * 19 | * get_location和get_location_by_long的区别是前者传递的ip是一个字符串,例如 20 | * 222.89.22.122,这个也是我们通常所用的格式;后者传递的ip是一个十进制的ipv4地址 21 | */ 22 | int qqwry_get_location(char *addr1,char *addr2,const char *ip,FILE *qqwry_file); 23 | int qqwry_get_location_by_long(char *addr1,char *addr2,const uint32_t ip,FILE *qqwry_file); 24 | -------------------------------------------------------------------------------- /nali/libqqwry/qqwry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008,2009 Surf Chen 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | /* 12 | * 请自己给addr1和addr2分配内存,我的建议是:addr1为64字节,addr2为128字节。 13 | * 这个库不会自己分配内存,而是把结果写入addr1和addr2的内存。 14 | * 这样的设计可以使得调用方更方便地使用自己的内存机制。 15 | * 16 | * addr1是大的范围,例如南宁市 17 | * addr2是小的范围,例如邕宁区 18 | * 19 | * get_location和get_location_by_long的区别是前者传递的ip是一个字符串,例如 20 | * 222.89.22.122,这个也是我们通常所用的格式;后者传递的ip是一个十进制的ipv4地址 21 | */ 22 | int qqwry_get_location(char *addr1,char *addr2,const char *ip,FILE *qqwry_file); 23 | int qqwry_get_location_by_long(char *addr1,char *addr2,const uint32_t ip,FILE *qqwry_file); 24 | -------------------------------------------------------------------------------- /php/qqwry/libqqwry/qqwry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Surf Chen 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | /* 12 | * 请自己给addr1和addr2分配内存,我的建议是:addr1为64字节,addr2为128字节。 13 | * 这个库不会自己分配内存,而是把结果写入addr1和addr2的内存。 14 | * 这样的设计可以使得调用方更方便地使用自己的内存机制。 15 | * 16 | * addr1是大的范围,例如南宁市 17 | * addr2是小的范围,例如邕宁区 18 | * 19 | * get_location和get_location_by_long的区别是前者传递的ip是一个字符串,例如 20 | * 222.89.22.122,这个也是我们通常所用的格式;后者传递的ip是一个十进制的ipv4地址 21 | */ 22 | int qqwry_get_location(char *addr1,char *addr2,const char *ip,FILE *qqwry_file); 23 | int qqwry_get_location_by_long(char *addr1,char *addr2,const uint32_t ip,FILE *qqwry_file); 24 | -------------------------------------------------------------------------------- /nali/share/nali.pl: -------------------------------------------------------------------------------- 1 | while ($line=<>) { 2 | $line =~ s/((?:[0-2]?[0-9]{1,2}\.){3}[0-2]?[0-9]{1,2})/qqwry($1)/eg; 3 | print $line; 4 | } 5 | sub qqwry { 6 | my $lang=$ENV{'LANG'}; 7 | my $ip=$_[0]; 8 | 9 | #my $iconv=`which iconv`; 10 | #if (index($iconv,"iconv")<0) { 11 | # $iconv=`whereis iconv`; 12 | #} 13 | 14 | if ($lang=~m/\.([A-z0-9\-_]+)/) { 15 | $lang=$1 16 | } else { 17 | $lang="UTF-8" 18 | } 19 | 20 | my $addr; 21 | $addr=`__QQWRYNALI $ip|iconv -f GBK -t $lang`; 22 | 23 | #if (index($iconv,"iconv")<0) { 24 | # $addr=`qqwrynali $ip`; 25 | #} else { 26 | # $iconv=~s/\n//g; 27 | # $addr=`__QQWRYNALI $ip|$iconv -f GBK -t $lang`; 28 | #} 29 | $addr =~ s/\n//g; 30 | return "$ip\033[1;31m\[$addr\]\033[0m"; 31 | } 32 | -------------------------------------------------------------------------------- /php/qqwry/libqqwry/.svn/pristine/76/76ac71edc639914c0ffddd503f6fe37c3fd82ece.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Surf Chen 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | /* 12 | * 请自己给addr1和addr2分配内存,我的建议是:addr1为64字节,addr2为128字节。 13 | * 这个库不会自己分配内存,而是把结果写入addr1和addr2的内存。 14 | * 这样的设计可以使得调用方更方便地使用自己的内存机制。 15 | * 16 | * addr1是大的范围,例如南宁市 17 | * addr2是小的范围,例如邕宁区 18 | * 19 | * get_location和get_location_by_long的区别是前者传递的ip是一个字符串,例如 20 | * 222.89.22.122,这个也是我们通常所用的格式;后者传递的ip是一个十进制的ipv4地址 21 | */ 22 | int qqwry_get_location(char *addr1,char *addr2,const char *ip,FILE *qqwry_file); 23 | int qqwry_get_location_by_long(char *addr1,char *addr2,const uint32_t ip,FILE *qqwry_file); 24 | -------------------------------------------------------------------------------- /php/geoip/tests/014.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking timezone info with (some) empty fields 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 17 | --EXPECTF-- 18 | string(%d) "America/%s" 19 | bool(false) 20 | string(%d) "Europe/%s" 21 | 22 | Warning: geoip_time_zone_by_country_and_region(): You need to specify at least the country code. in %s on line %d 23 | bool(false) 24 | 25 | Warning: geoip_time_zone_by_country_and_region(): You need to specify at least the country code. in %s on line %d 26 | bool(false) 27 | -------------------------------------------------------------------------------- /tools/check-index.php: -------------------------------------------------------------------------------- 1 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 18 | --EXPECTF-- 19 | 20 | Warning: geoip_region_name_by_code(): You need to specify the country and region codes. in %s on line %d 21 | bool(false) 22 | 23 | Warning: geoip_region_name_by_code(): You need to specify the country and region codes. in %s on line %d 24 | bool(false) 25 | bool(false) 26 | 27 | Warning: geoip_region_name_by_code(): You need to specify the country and region codes. in %s on line %d 28 | bool(false) 29 | 30 | Warning: geoip_region_name_by_code(): You need to specify the country and region codes. in %s on line %d 31 | bool(false) 32 | bool(false) 33 | -------------------------------------------------------------------------------- /nali/Makefile: -------------------------------------------------------------------------------- 1 | include config.mak 2 | all:nali.c libqqwry/qqwry.c share/nali.sh 3 | gcc -o bin/qqwrynali nali.c libqqwry/qqwry.c 4 | cp share/nali.sh bin/nali 5 | cp share/nali.pl bin/nali.pl 6 | sed -i -e 's|__DATADIR|$(DESTDIR)$(datadir)|g' bin/nali 7 | sed -i -e 's|__QQWRYNALI|$(DESTDIR)$(bindir)/qqwrynali|g' bin/nali.pl 8 | install:bin share 9 | install -d -m 0755 $(DESTDIR)$(bindir) 10 | install -d -m 0755 $(DESTDIR)$(prefix) 11 | install -d -m 0755 $(DESTDIR)$(datadir) 12 | install bin/qqwrynali $(DESTDIR)$(bindir)/qqwrynali 13 | install bin/nali $(DESTDIR)$(bindir)/nali 14 | install bin/nali-traceroute $(DESTDIR)$(bindir)/nali-traceroute 15 | install bin/nali-tracepath $(DESTDIR)$(bindir)/nali-tracepath 16 | install bin/nali-dig $(DESTDIR)$(bindir)/nali-dig 17 | install bin/nali-nslookup $(DESTDIR)$(bindir)/nali-nslookup 18 | install bin/nali-ping $(DESTDIR)$(bindir)/nali-ping 19 | install bin/nali-update $(DESTDIR)$(bindir)/nali-update 20 | install share/QQWry.Dat $(DESTDIR)$(datadir)/QQWry.Dat 21 | install bin/nali.pl $(DESTDIR)$(datadir)/nali.pl 22 | distclean: clean 23 | rm -f config.mak 24 | rm -f config.h 25 | clean: 26 | rm -f bin/qqwrynali 27 | rm -f bin/nali 28 | -------------------------------------------------------------------------------- /tools/dump-location.php: -------------------------------------------------------------------------------- 1 | ftell($input_fp)) { 24 | //echo "step 0 ... "; 25 | $c=fread($input_fp,1); 26 | $buffer=$c; 27 | if (in_array(ftell($input_fp)-1,$data_indexes)) { 28 | fseek($input_fp,3,SEEK_CUR); 29 | } else if ($c==MODE_1 || $c==MODE_2) { 30 | fseek($input_fp,3,SEEK_CUR); 31 | } else { 32 | while (ord($c=fread($input_fp,1))>0) { 33 | $buffer.=$c; 34 | } 35 | if ($c!=RECORD_END) { 36 | echo "fread error\n"; 37 | exit(1); 38 | } 39 | file_put_contents($out,$buffer."\n",FILE_APPEND); 40 | } 41 | } 42 | echo "ok\n"; 43 | -------------------------------------------------------------------------------- /php/geoip/tests/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking if all db info and name match 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 23 | --EXPECT-- 24 | string(21) "GeoIP Country Edition" 25 | string(27) "GeoIP Region Edition, Rev 0" 26 | string(25) "GeoIP City Edition, Rev 0" 27 | string(26) "GeoIP Organization Edition" 28 | string(17) "GeoIP ISP Edition" 29 | string(25) "GeoIP City Edition, Rev 1" 30 | string(27) "GeoIP Region Edition, Rev 1" 31 | string(19) "GeoIP Proxy Edition" 32 | string(19) "GeoIP ASNum Edition" 33 | string(22) "GeoIP Netspeed Edition" 34 | string(25) "GeoIP Domain Name Edition" 35 | -------------------------------------------------------------------------------- /nali/nali.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "libqqwry/qqwry.h" 6 | #include "config.h" 7 | int main(int argc, char *argv[]) 8 | { 9 | char *ip; 10 | if (argc != 2) { 11 | ip=(char *)malloc(128);//有可能前面有大段非数字字符,所以申请128 12 | ip=fgets(ip,128,stdin); 13 | } else { 14 | ip=argv[1]; 15 | } 16 | 17 | char country[1024]={'\0'}; 18 | char area[1024]={'\0'}; 19 | 20 | //char *test_ip2 = "127.0.0.1"; 21 | //char *test_ip2 = "72.14.207.191"; 22 | //char *test_ip2 = "121.0.23.2"; 23 | FILE *wry_file; 24 | int i=0; 25 | for (;i<2;++i) { 26 | if (i==0) { 27 | wry_file=fopen(NALI_QQWRY_PATH,"r"); 28 | } else if (i==1) { 29 | wry_file=fopen("./QQWry.Dat","r"); 30 | } 31 | if (wry_file!=NULL) { 32 | break; 33 | } 34 | } 35 | qqwry_get_location(country,area,ip,wry_file); 36 | fclose(wry_file); 37 | if (strlen(country)>0) { 38 | printf("%s",country); 39 | } 40 | if (strlen(area)>0) { 41 | if (strlen(country)>0) { 42 | printf(" "); 43 | } 44 | if (strlen(country)<=0) { 45 | printf("unknown"); 46 | } else { 47 | printf("%s",area); 48 | } 49 | } 50 | printf("\n"); 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /php/qqwry/test.php: -------------------------------------------------------------------------------- 1 | getlocation($ip); 33 | } 34 | $times[1]=microtime(true)-$t; 35 | 36 | $t=microtime(true); 37 | foreach ($arr as $ip) { 38 | $qqwry->q($ip); 39 | } 40 | $times[2]=microtime(true)-$t; 41 | echo "测试结束\n"; 42 | echo '是discuz的',$times[0]/$times[2],"倍\n"; 43 | echo '是coolcode的',$times[1]/$times[2],"倍\n"; 44 | 45 | 46 | echo "正确性测试 ... "; 47 | foreach ($arr as $ip) { 48 | $s1=convertip($ip); 49 | $s2=implode('',$coolcode->getlocation($ip)); 50 | $s3=implode('',$qqwry->q($ip)); 51 | if ($s3!=$s1 || $s3!=$s2) { 52 | echo $ip,"\n"; 53 | var_dump($s1); 54 | var_dump($s2); 55 | var_dump($s3); 56 | echo "错误发生\n"; 57 | exit(1); 58 | } 59 | 60 | //echo '|'; 61 | //var_dump(qqwry($ip,'QQWry.Dat')); 62 | //echo "\n"; 63 | } 64 | echo "一切ok\n"; 65 | 66 | function usage() { 67 | echo "php test.php QQWry.Dat libqqwry.php\n"; 68 | exit; 69 | } 70 | -------------------------------------------------------------------------------- /php/geoip/geoip.def: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 2002-2009 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Olivier Hill | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* GEOIPDEF(php_func, c_func, db_type) */ 20 | GEOIPDEF(geoip_country_code_by_name, GeoIP_country_code_by_name, GEOIP_COUNTRY_EDITION) 21 | GEOIPDEF(geoip_country_code3_by_name, GeoIP_country_code3_by_name, GEOIP_COUNTRY_EDITION) 22 | GEOIPDEF(geoip_country_name_by_name, GeoIP_country_name_by_name, GEOIP_COUNTRY_EDITION) 23 | 24 | #if LIBGEOIP_VERSION >= 1004005 25 | GEOIPDEF(geoip_country_code_by_name_v6, GeoIP_country_code_by_name_v6, GEOIP_COUNTRY_EDITION_V6) 26 | GEOIPDEF(geoip_country_code3_by_name_v6, GeoIP_country_code3_by_name_v6, GEOIP_COUNTRY_EDITION_V6) 27 | GEOIPDEF(geoip_country_name_by_name_v6, GeoIP_country_name_by_name_v6, GEOIP_COUNTRY_EDITION_V6) 28 | #endif -------------------------------------------------------------------------------- /php/qqwry/config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 2 | dnl config.m4 for extension qqwry 3 | 4 | dnl Comments in this file start with the string 'dnl'. 5 | dnl Remove where necessary. This file will not work 6 | dnl without editing. 7 | 8 | dnl If your extension references something external, use with: 9 | 10 | dnl PHP_ARG_WITH(qqwry, for qqwry support, 11 | dnl Make sure that the comment is aligned: 12 | dnl [ --with-qqwry Include qqwry support]) 13 | 14 | dnl Otherwise use enable: 15 | 16 | PHP_ARG_ENABLE(qqwry, whether to enable qqwry support, 17 | [ --enable-qqwry Enable qqwry support]) 18 | 19 | if test "$PHP_QQWRY" != "no"; then 20 | dnl Write more examples of tests here... 21 | 22 | dnl # --with-qqwry -> check with-path 23 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this 24 | dnl SEARCH_FOR="/include/qqwry.h" # you most likely want to change this 25 | dnl if test -r $PHP_QQWRY/$SEARCH_FOR; then # path given as parameter 26 | dnl QQWRY_DIR=$PHP_QQWRY 27 | dnl else # search default path list 28 | dnl AC_MSG_CHECKING([for qqwry files in default path]) 29 | dnl for i in $SEARCH_PATH ; do 30 | dnl if test -r $i/$SEARCH_FOR; then 31 | dnl QQWRY_DIR=$i 32 | dnl AC_MSG_RESULT(found in $i) 33 | dnl fi 34 | dnl done 35 | dnl fi 36 | dnl 37 | dnl if test -z "$QQWRY_DIR"; then 38 | dnl AC_MSG_RESULT([not found]) 39 | dnl AC_MSG_ERROR([Please reinstall the qqwry distribution]) 40 | dnl fi 41 | 42 | dnl # --with-qqwry -> add include path 43 | dnl PHP_ADD_INCLUDE($QQWRY_DIR/include) 44 | 45 | dnl # --with-qqwry -> check for lib and symbol presence 46 | dnl LIBNAME=qqwry # you may want to change this 47 | dnl LIBSYMBOL=qqwry # you most likely want to change this 48 | 49 | dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 50 | dnl [ 51 | dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $QQWRY_DIR/lib, QQWRY_SHARED_LIBADD) 52 | dnl AC_DEFINE(HAVE_QQWRYLIB,1,[ ]) 53 | dnl ],[ 54 | dnl AC_MSG_ERROR([wrong qqwry lib version or lib not found]) 55 | dnl ],[ 56 | dnl -L$QQWRY_DIR/lib -lm -ldl 57 | dnl ]) 58 | dnl 59 | dnl PHP_SUBST(QQWRY_SHARED_LIBADD) 60 | 61 | PHP_NEW_EXTENSION(qqwry, qqwry.c libqqwry/qqwry.c, $ext_shared) 62 | fi 63 | -------------------------------------------------------------------------------- /php/qqwry/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | qqwry 7 | pecl.php.net 8 | Get IP location from QQWry file 9 | QQWry is a binary file which contains ip-related locations information.This ext search it and get location information from it. 10 | 11 | 12 | Surf Chen 13 | surfchen 14 | surfchen@gmail.com 15 | yes 16 | 17 | 2008-11-25 18 | 19 | 0.1.0 20 | 0.1 21 | 22 | 23 | beta 24 | beta 25 | 26 | New BSD 27 | 28 | Initial release. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 5 51 | 52 | 53 | 1.4.0b1 54 | 55 | 56 | 57 | qqwry 58 | 59 | 60 | 61 | 62 | 0.1.0 63 | 0.1 64 | 65 | 66 | beta 67 | beta 68 | 69 | 2008-11-25 70 | New BSD 71 | 72 | Initial release. 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /nali/configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | prefix=/usr/local 3 | if test x"$1" = x"-h" -o x"$1" = x"--help" ; then 4 | echo "Usage: ./configure [options]" 5 | echo " --help print this message" 6 | echo " --prefix=PREFIX default:/usr/local" 7 | echo " --bindir=BINDIR default:$prefix/bin" 8 | echo " --datadir=BINDIR default:$prefix/share" 9 | echo "" 10 | exit 1 11 | fi 12 | 13 | if test ! -d ./libqqwry 14 | then 15 | echo there is no ./libqqwry 16 | echo see http://code.google.com/p/qqwry/ 17 | exit 1 18 | fi 19 | 20 | if test ! -f ./share/QQWry.Dat 21 | then 22 | echo please download QQWry.Dat from https://chenze.name/wenjian/QQWry.Dat 23 | exit 1 24 | fi 25 | 26 | 27 | 28 | # parse options 29 | 30 | for opt do 31 | optarg="${opt#*=}" 32 | case "$opt" in 33 | --prefix=*) 34 | prefix="$optarg" 35 | ;; 36 | --bindir=*) 37 | bindir="$optarg" 38 | ;; 39 | --datadir=*) 40 | datadir="$optarg" 41 | ;; 42 | esac 43 | done 44 | 45 | if test "z$bindir" = "z" 46 | then 47 | bindir=${prefix}/bin 48 | fi 49 | 50 | if test "z$datadir" = "z" 51 | then 52 | datadir=${prefix}/share 53 | fi 54 | 55 | 56 | # generate config files 57 | 58 | cat > config.mak << EOF 59 | prefix=$prefix 60 | bindir=$bindir 61 | datadir=$datadir 62 | EOF 63 | 64 | cat > config.h << EOF 65 | #define NALI_QQWRY_PATH "$datadir/QQWry.Dat" 66 | EOF 67 | 68 | cat > bin/nali << EOF 69 | #!/bin/sh 70 | if test \$# -gt 0 71 | then 72 | echo \$@|perl $datadir/nali.pl 73 | else 74 | perl $datadir/nali.pl 75 | fi 76 | EOF 77 | 78 | cat > bin/nali-update << EOF 79 | #!/bin/sh 80 | qqwry_dat_url="https://chenze.name/wenjian/QQWry.Dat"; 81 | qqwry_dat_local_path="$datadir/QQWry.Dat" 82 | curl=\`which curl\` 83 | wget=\`which wget\` 84 | 85 | if ! test -w \$qqwry_dat_local_path 86 | then 87 | echo You may need sudo 88 | exit 1 89 | fi 90 | 91 | if test -f /tmp/QQWry.Dat 92 | then 93 | rm -f /tmp/QQWry.Dat || exit 1 94 | fi 95 | 96 | if test "x\$curl" != "x" && test -x \$curl 97 | then 98 | command="\$curl -k --compressed \$qqwry_dat_url -o /tmp/QQWry.Dat" 99 | elif test "x\$wget" != "x" && test -x \$wget 100 | then 101 | command="\$wget --no-check-certificate \$qqwry_dat_url -O /tmp/QQWry.Dat" 102 | else 103 | echo Error: Please install curl or wget 104 | exit 1 105 | fi 106 | echo Updating \$qqwry_dat_local_path 107 | \$command && mv /tmp/QQWry.Dat \$qqwry_dat_local_path && echo Successfully Updated && exit 0 108 | 109 | echo Failed to update 110 | exit 1 111 | EOF 112 | 113 | echo '***** Configure Successfully *****' 114 | echo 115 | echo "Install:" 116 | echo 'make && make install' 117 | echo 118 | echo "Usage and Examples:"; 119 | echo 'http://www.surfchen.org/wiki/Nali' 120 | -------------------------------------------------------------------------------- /php/qqwry/php_qqwry.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2007 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id: header,v 1.16.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ */ 20 | 21 | #ifndef PHP_QQWRY_H 22 | #define PHP_QQWRY_H 23 | 24 | extern zend_module_entry qqwry_module_entry; 25 | #define phpext_qqwry_ptr &qqwry_module_entry 26 | 27 | #ifdef PHP_WIN32 28 | #define PHP_QQWRY_API __declspec(dllexport) 29 | #else 30 | #define PHP_QQWRY_API 31 | #endif 32 | 33 | #ifdef ZTS 34 | #include "TSRM.h" 35 | #endif 36 | 37 | PHP_MINIT_FUNCTION(qqwry); 38 | PHP_MSHUTDOWN_FUNCTION(qqwry); 39 | PHP_RINIT_FUNCTION(qqwry); 40 | PHP_RSHUTDOWN_FUNCTION(qqwry); 41 | PHP_MINFO_FUNCTION(qqwry); 42 | 43 | PHP_METHOD(qqwry, __construct); 44 | ZEND_BEGIN_ARG_INFO_EX(qqwry____construct_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) 45 | ZEND_END_ARG_INFO() 46 | 47 | PHP_METHOD(qqwry, q); 48 | ZEND_BEGIN_ARG_INFO_EX(qqwry__q_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) 49 | ZEND_END_ARG_INFO() 50 | 51 | typedef struct _qqwry_fp_list{ 52 | FILE *fp; 53 | char *filepath; 54 | struct _qqwry_fp_list* next; 55 | }qqwry_fp_list; 56 | 57 | /* 58 | Declare any global variables you may need between the BEGIN 59 | and END macros here: 60 | */ 61 | 62 | ZEND_BEGIN_MODULE_GLOBALS(qqwry) 63 | qqwry_fp_list *fp_list; 64 | ZEND_END_MODULE_GLOBALS(qqwry) 65 | 66 | /* In every utility function you add that needs to use variables 67 | in php_qqwry_globals, call TSRMLS_FETCH(); after declaring other 68 | variables used by that function, or better yet, pass in TSRMLS_CC 69 | after the last function argument and declare your utility function 70 | with TSRMLS_DC after the last declared argument. Always refer to 71 | the globals in your function as QQWRY_G(variable). You are 72 | encouraged to rename these macros something shorter, see 73 | examples in any other php module directory. 74 | */ 75 | 76 | #ifdef ZTS 77 | #define QQWRY_G(v) TSRMG(qqwry_globals_id, zend_qqwry_globals *, v) 78 | #else 79 | #define QQWRY_G(v) (qqwry_globals.v) 80 | #endif 81 | 82 | #endif /* PHP_QQWRY_H */ 83 | 84 | 85 | /* 86 | * Local variables: 87 | * tab-width: 4 88 | * c-basic-offset: 4 89 | * End: 90 | * vim600: noet sw=4 ts=4 fdm=marker 91 | * vim<600: noet sw=4 ts=4 92 | */ 93 | -------------------------------------------------------------------------------- /php/geoip/LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | The PHP License, version 3.01 3 | Copyright (c) 1999 - 2014 The PHP Group. All rights reserved. 4 | -------------------------------------------------------------------- 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, is permitted provided that the following conditions 8 | are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | 3. The name "PHP" must not be used to endorse or promote products 19 | derived from this software without prior written permission. For 20 | written permission, please contact group@php.net. 21 | 22 | 4. Products derived from this software may not be called "PHP", nor 23 | may "PHP" appear in their name, without prior written permission 24 | from group@php.net. You may indicate that your software works in 25 | conjunction with PHP by saying "Foo for PHP" instead of calling 26 | it "PHP Foo" or "phpfoo" 27 | 28 | 5. The PHP Group may publish revised and/or new versions of the 29 | license from time to time. Each version will be given a 30 | distinguishing version number. 31 | Once covered code has been published under a particular version 32 | of the license, you may always continue to use it under the terms 33 | of that version. You may also choose to use such covered code 34 | under the terms of any subsequent version of the license 35 | published by the PHP Group. No one other than the PHP Group has 36 | the right to modify the terms applicable to covered code created 37 | under this License. 38 | 39 | 6. Redistributions of any form whatsoever must retain the following 40 | acknowledgment: 41 | "This product includes PHP software, freely available from 42 | ". 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND 45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP 48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 | OF THE POSSIBILITY OF SUCH DAMAGE. 56 | 57 | -------------------------------------------------------------------- 58 | 59 | This software consists of voluntary contributions made by many 60 | individuals on behalf of the PHP Group. 61 | 62 | The PHP Group can be contacted via Email at group@php.net. 63 | 64 | For more information on the PHP Group and the PHP project, 65 | please see . 66 | 67 | PHP includes the Zend Engine, freely available at 68 | . 69 | -------------------------------------------------------------------------------- /php/geoip/php_geoip.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2009 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Olivier Hill | 16 | | Matthew Fonda | 17 | +----------------------------------------------------------------------+ 18 | Please contact support@maxmind.com with any comments 19 | */ 20 | 21 | #ifndef PHP_GEOIP_H 22 | #define PHP_GEOIP_H 23 | 24 | extern zend_module_entry geoip_module_entry; 25 | #define phpext_geoip_ptr &geoip_module_entry 26 | 27 | #define PHP_GEOIP_VERSION "1.1.1-dev" 28 | 29 | #if PHP_MAJOR_VERSION < 7 30 | typedef long zend_long; 31 | #endif 32 | 33 | #ifdef PHP_WIN32 34 | #define PHP_GEOIP_API __declspec(dllexport) 35 | #else 36 | #define PHP_GEOIP_API 37 | #endif 38 | 39 | #ifdef ZTS 40 | #include "TSRM.h" 41 | #endif 42 | 43 | #include 44 | #include 45 | 46 | PHP_MINIT_FUNCTION(geoip); 47 | PHP_MSHUTDOWN_FUNCTION(geoip); 48 | PHP_RINIT_FUNCTION(geoip); 49 | PHP_RSHUTDOWN_FUNCTION(geoip); 50 | PHP_MINFO_FUNCTION(geoip); 51 | 52 | 53 | PHP_FUNCTION(geoip_database_info); 54 | #define GEOIPDEF(php_func, c_func, db_type) \ 55 | PHP_FUNCTION(php_func); 56 | #include "geoip.def" 57 | #undef GEOIPDEF 58 | PHP_FUNCTION(geoip_continent_code_by_name); 59 | PHP_FUNCTION(geoip_org_by_name); 60 | PHP_FUNCTION(geoip_record_by_name); 61 | PHP_FUNCTION(geoip_id_by_name); 62 | PHP_FUNCTION(geoip_region_by_name); 63 | PHP_FUNCTION(geoip_isp_by_name); 64 | PHP_FUNCTION(geoip_db_avail); 65 | PHP_FUNCTION(geoip_db_get_all_info); 66 | PHP_FUNCTION(geoip_db_filename); 67 | #if LIBGEOIP_VERSION >= 1004001 68 | PHP_FUNCTION(geoip_region_name_by_code); 69 | PHP_FUNCTION(geoip_time_zone_by_country_and_region); 70 | #endif 71 | #ifdef HAVE_CUSTOM_DIRECTORY 72 | PHP_FUNCTION(geoip_setup_custom_directory); 73 | #endif 74 | PHP_FUNCTION(geoip_asnum_by_name); 75 | PHP_FUNCTION(geoip_domain_by_name); 76 | #if LIBGEOIP_VERSION >= 1004008 77 | PHP_FUNCTION(geoip_netspeedcell_by_name); 78 | #endif 79 | 80 | ZEND_BEGIN_MODULE_GLOBALS(geoip) 81 | char* custom_directory; 82 | int set_runtime_custom_directory; 83 | ZEND_END_MODULE_GLOBALS(geoip) 84 | 85 | #ifdef ZTS 86 | #define GEOIP_G(v) TSRMG(geoip_globals_id, zend_geoip_globals *, v) 87 | #else 88 | #define GEOIP_G(v) (geoip_globals.v) 89 | #endif 90 | 91 | #endif /* PHP_GEOIP_H */ 92 | 93 | 94 | /* 95 | * Local variables: 96 | * tab-width: 4 97 | * c-basic-offset: 4 98 | * End: 99 | * vim600: noet sw=4 ts=4 fdm=marker 100 | * vim<600: noet sw=4 ts=4 101 | */ 102 | -------------------------------------------------------------------------------- /php/geoip/ChangeLog: -------------------------------------------------------------------------------- 1 | 1.1.0-dev 2012-xx-xx 2 | 3 | * Add geoip_setup_custom_directory() to setup custom directories per request. 4 | * Remove E_NOTICES for IPs not found in database. 5 | * Fix a segfault with geoip_db_get_all_info() on newer libs (bug #64692). 6 | * Add support for geoip_netspeedcell_by_name(), geoip_asnum_by_name() and geoip_domain_by_name() (bug #67121). 7 | * Fix memory leak with custom directories (bug #67138). 8 | * Support changing custom directory via ini_set() (bug #61607). 9 | 10 | 1.0.8 2011-10-23 11 | 12 | * Windows support 13 | * Fix segfault with newer geoip libraries and geoip_db_get_all_info() (bug #60066) 14 | * Use X-Macros for repeated code 15 | * Updated tests 16 | 17 | 1.0.7 2009-03-11 18 | 19 | * Do not issue a NOTICE when values don't exist for timezone and region name (as added in 1.0.4) 20 | * Fix a compile issue on FreeBSD 21 | * Try to be bulletproof on library features detection. 22 | 23 | 1.0.6 2009-01-20 24 | 25 | * Fixing compile bug when multiple GeoIP libs are installed, bug #15372 26 | 27 | 1.0.5 2008-12-19 28 | 29 | * Small bug in phpinfo() when printing version number could crash PHP. 30 | 31 | 1.0.4 2008-12-19 32 | 33 | * Fix memleaks, bug #14851 34 | * Small patch for MacPorts by jhohle 35 | * Add geoip_time_zone_by_country_and_region() and geoip_region_name_by_code() (thanks to Sid Dunayer) 36 | * Add continent_code field for City Database, only if using GeoIP lib 1.4.3 or newer 37 | 38 | 1.0.3 2008-06-12 39 | 40 | * Change license from PHP 3.0 to PHP 3.01 for Debian? 41 | * Added geoip_continent_code_by_name() to get continent instead of country 42 | * Fixing a small casting issue (compiler warning) 43 | * Fixing missing entries in geoip_record_by_name, bug #14131 44 | 45 | 1.0.2 2007-11-20 46 | 47 | * Added geoip_isp_by_name (patch by Yannick Gard) 48 | 49 | 1.0.1 2007-08-22 50 | 51 | * Added geoip_db_avail() to check for DB availability (file found) 52 | * Added geoip_db_filename() to get the internal file name of the library 53 | * Added geoip_db_get_all_info() to fetch all info about all database types 54 | * Added some tests so that make test can crunch something. 55 | * Added database file path and name in warning when DB is not found. 56 | * Added geoip.custom_directory php.ini option to change default path for DBs 57 | 58 | 1.0.0 2007-08-14 59 | 60 | * Marked as stable 61 | * Fixing wrong version number inside extension 62 | 63 | 0.2.0 2006-08-22 64 | 65 | * Initial PECL Release 66 | * Fixing various memory leaks 67 | * Registering the C API constants in PHP 68 | 69 | 0.1.3 2006-7-10 70 | 71 | Following changes made by Olivier Hill 72 | * Missing PHP function prototypes 73 | * Fixing code foldings in Emacs 74 | * Outputting E_NOTICES instead of E_WARNING when non fatal errors 75 | * Return type of longitude/latitude should be DOUBLE and not LONG 76 | 77 | 0.1.2 2006-5-19 78 | * Following changes all contributed by Guenter Knauf 79 | - moved argument parsing up at various places before we create a GeoIP. 80 | - moved GeoIP_delete() call at various places up to get it called before we error out. 81 | - fixed one place where a missing return caused a segfault on all platforms because 82 | RETURN_STRING() was called with NULL when GeoIP lookup failed. 83 | - added php.ini entry parsing; prepared for usage of geoip.database_standard var. 84 | This works fine so far as you can test with the geoip_database_info() call which uses 85 | the database configured with the geoip.database_standard var; if not set it defaults 86 | to the usual place specified during compile time with GEOIPDATADIR. All other functions 87 | currently still ignore the geoip.database_standard setting, but default usually also 88 | to GEOIPDATADIR from what I see. Search for the dirty '//' comments .... 89 | * Added config.m4, contributed by Jonathan Whiteman of cyberflowsolutions.com 90 | 91 | 0.1.1 2005-9-21 92 | * Initial release, contributed by Matthew Fonda 93 | -------------------------------------------------------------------------------- /php/geoip/config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id: config.m4 333464 2014-05-03 10:21:31Z remi $ 2 | dnl config.m4 for extension geoip 3 | 4 | dnl Base file contributed by Jonathan Whiteman of cyberflowsolutions.com 5 | 6 | PHP_ARG_WITH(geoip, for geoip support, 7 | dnl Make sure that the comment is aligned: 8 | [ --with-geoip Include GeoIP support]) 9 | 10 | if test "$PHP_GEOIP" != "no"; then 11 | 12 | # --with-geoip -> check with-path 13 | SEARCH_PATH="/usr/local /usr /sw /opt/local" 14 | SEARCH_FOR="/include/GeoIP.h" 15 | if test -r $PHP_GEOIP/$SEARCH_FOR; then 16 | GEOIP_DIR=$PHP_GEOIP 17 | else # search default path list 18 | AC_MSG_CHECKING([for geoip files in default path]) 19 | for i in $SEARCH_PATH ; do 20 | if test -r $i/$SEARCH_FOR; then 21 | GEOIP_DIR=$i 22 | AC_MSG_RESULT([found in $i]) 23 | fi 24 | done 25 | fi 26 | 27 | if test -z "$GEOIP_DIR"; then 28 | AC_MSG_RESULT([not found]) 29 | AC_MSG_ERROR([Please reinstall the geoip distribution]) 30 | fi 31 | 32 | # --with-geoip -> add include path 33 | PHP_ADD_INCLUDE($GEOIP_DIR/include) 34 | 35 | # odd PHP4 fix 36 | if test "x$PHP_LIBDIR" = "x"; then 37 | PHP_LIBDIR=lib 38 | fi 39 | 40 | # --with-geoip -> check for lib and symbol presence 41 | LIBNAME=GeoIP # you may want to change this 42 | LIBSYMBOL=GeoIP_open # you most likely want to change this 43 | 44 | PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 45 | [ 46 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $GEOIP_DIR/$PHP_LIBDIR, GEOIP_SHARED_LIBADD) 47 | AC_DEFINE(HAVE_GEOIPLIB,1,[ ]) 48 | ],[ 49 | AC_MSG_ERROR([wrong geoip lib version or lib not found]) 50 | ],[ 51 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 52 | ]) 53 | 54 | # Checking for GeoIP_setup_custom_directory in newer lib 55 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_setup_custom_directory, 56 | [ 57 | AC_DEFINE(HAVE_CUSTOM_DIRECTORY,1,[ ]) 58 | MIN_GEOIP_VERSION=1004001 59 | ],[ 60 | ],[ 61 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 62 | ]) 63 | 64 | # Checking for GeoIP_set_charset in newer lib 65 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_set_charset, 66 | [ 67 | AC_DEFINE(HAVE_SET_CHARSET,1,[ ]) 68 | MIN_GEOIP_VERSION=1004003 69 | ],[ 70 | ],[ 71 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 72 | ]) 73 | 74 | # Checking for GeoIP_continent_by_id in newer lib 75 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_continent_by_id, 76 | [ 77 | AC_DEFINE(HAVE_CONTINENT_BY_ID,1,[ ]) 78 | MIN_GEOIP_VERSION=1004005 79 | ],[ 80 | ],[ 81 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 82 | ]) 83 | 84 | # Checking for GeoIP_addr_to_num in newer lib 85 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_addr_to_num, 86 | [ 87 | AC_DEFINE(HAVE_ADDR_TO_NUM,1,[ ]) 88 | MIN_GEOIP_VERSION=1004007 89 | ],[ 90 | ],[ 91 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 92 | ]) 93 | 94 | # Checking for GEOIP_NETSPEED_EDITION_REV1 95 | AC_CHECK_DECL(GEOIP_NETSPEED_EDITION_REV1, 96 | [ 97 | MIN_GEOIP_VERSION=1004008 98 | ],[],[ 99 | #include 100 | ]) 101 | 102 | # Checking for GEOIP_ACCURACYRADIUS_EDITION 103 | AC_CHECK_DECL(GEOIP_ACCURACYRADIUS_EDITION, 104 | [ 105 | MIN_GEOIP_VERSION=1005000 106 | ],[],[ 107 | #include 108 | ]) 109 | 110 | # Check to see if we are using the LGPL library (version 1.4.0 and newer) 111 | AC_MSG_CHECKING([for LGPL compatible GeoIP libs]) 112 | libgeoip_full_version=`find $GEOIP_DIR/$PHP_LIBDIR/ -name libGeoIP.\*.\*.\*.\* | cut -d . -f 2-5 | sort` 113 | for lines in $libgeoip_full_version; do 114 | ac_IFS=$IFS 115 | IFS="." 116 | set $lines 117 | IFS=$ac_IFS 118 | done 119 | 120 | # Version after the suffix (eg: .so.1.4.0) 121 | if test "[$]1" = "$SHLIB_SUFFIX_NAME"; then 122 | LIBGEOIP_VERSION=`expr [$]2 \* 1000000 + [$]3 \* 1000 + [$]4` 123 | # Version before the suffix (eg: 1.4.0.dylib on OS X) 124 | else 125 | LIBGEOIP_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` 126 | fi 127 | 128 | # Just in case it didn't work, try alternate method, or fail 129 | if test "x$LIBGEOIP_VERSION" = "x"; then 130 | AC_MSG_RESULT([cannot detect]) 131 | 132 | # Alternate method based on library capabilities (not 100% acurate) 133 | AC_MSG_CHECKING([library features to determine version (not acurate)]) 134 | if test "x$MIN_GEOIP_VERSION" = "x"; then 135 | AC_MSG_ERROR([For some reason, libGeoIP is installed, but I cannot determine the version used]) 136 | else 137 | LIBGEOIP_VERSION=$MIN_GEOIP_VERSION 138 | fi 139 | fi 140 | 141 | if test "$LIBGEOIP_VERSION" -lt "1004000"; then 142 | AC_MSG_RESULT([wrong version]) 143 | AC_MSG_ERROR([You need version 1.4.0 or higher of the C API]) 144 | else 145 | AC_MSG_RESULT([found $LIBGEOIP_VERSION]) 146 | AC_DEFINE_UNQUOTED(LIBGEOIP_VERSION, $LIBGEOIP_VERSION, [ ]) 147 | fi 148 | 149 | PHP_SUBST(GEOIP_SHARED_LIBADD) 150 | 151 | PHP_NEW_EXTENSION(geoip, geoip.c, $ext_shared) 152 | fi 153 | 154 | -------------------------------------------------------------------------------- /libs/libqqwry.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define BE_32(x) ((((uint8_t*)(x))[0]<<24) |\ 5 | (((uint8_t*)(x))[1]<<16) |\ 6 | (((uint8_t*)(x))[2]<<8) |\ 7 | ((uint8_t*)(x))[3]) 8 | 9 | #define LE_32(x) ((((uint8_t*)(x))[3]<<24) |\ 10 | (((uint8_t*)(x))[2]<<16) |\ 11 | (((uint8_t*)(x))[1]<<8) |\ 12 | ((uint8_t*)(x))[0]) 13 | 14 | #define LE_24(x) ((((uint8_t*)(x))[2]<<16) |\ 15 | (((uint8_t*)(x))[1]<<8) |\ 16 | ((uint8_t*)(x))[0]) 17 | 18 | #define REDIRECT_TYPE_1 0x01 19 | #define REDIRECT_TYPE_2 0x02 20 | 21 | static uint32_t ip2long(const char *ip) { 22 | uint32_t ip_long=0; 23 | uint8_t ip_len=strlen(ip); 24 | uint32_t ip_sec=0; 25 | int8_t ip_level=3; 26 | uint8_t i,n; 27 | for (i=0;i<=ip_len;i++) { 28 | if (i!=ip_len && ip[i]!='.' && ip[i]<48 || ip[i]>57) { 29 | continue; 30 | } 31 | if (ip[i]=='.' || i==ip_len) { 32 | /*too many .*/ 33 | if (ip_level==-1) { 34 | return 0; 35 | } 36 | for (n=0;nip) { 84 | fseek(qqwry_file,index_start,SEEK_SET); 85 | fread(index_bytes,7,1,qqwry_file); 86 | } 87 | return (uint32_t)LE_24(&index_bytes[4]); 88 | } 89 | static int readOrJumpRead(char *location,FILE *qqwry_file,const uint32_t data_index) { 90 | unsigned char c; 91 | unsigned char data_index_bytes[3]; 92 | uint32_t jump_data_index=0; 93 | if (data_index) { 94 | fseek(qqwry_file,data_index,SEEK_SET); 95 | } 96 | c=fgetc(qqwry_file); 97 | switch (c) { 98 | case REDIRECT_TYPE_2: 99 | case REDIRECT_TYPE_1: 100 | fread(data_index_bytes,3,1,qqwry_file); 101 | jump_data_index=LE_24(&data_index_bytes[0]); 102 | fseek(qqwry_file,jump_data_index,SEEK_SET); 103 | break; 104 | default: 105 | location[strlen(location)]=c; 106 | } 107 | if (c) { 108 | while (c=fgetc(qqwry_file)) { 109 | location[strlen(location)]=c; 110 | } 111 | } 112 | return 1; 113 | } 114 | static int is_cz88(const char *str) { 115 | int i; 116 | int l=strlen(str)-7; 117 | for (i=0;i 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #define BE_32(x) ((((uint8_t*)(x))[0]<<24) |\ 14 | (((uint8_t*)(x))[1]<<16) |\ 15 | (((uint8_t*)(x))[2]<<8) |\ 16 | ((uint8_t*)(x))[3]) 17 | 18 | #define LE_32(x) ((((uint8_t*)(x))[3]<<24) |\ 19 | (((uint8_t*)(x))[2]<<16) |\ 20 | (((uint8_t*)(x))[1]<<8) |\ 21 | ((uint8_t*)(x))[0]) 22 | 23 | #define LE_24(x) ((((uint8_t*)(x))[2]<<16) |\ 24 | (((uint8_t*)(x))[1]<<8) |\ 25 | ((uint8_t*)(x))[0]) 26 | 27 | #define REDIRECT_TYPE_1 0x01 28 | #define REDIRECT_TYPE_2 0x02 29 | 30 | static uint32_t ip2long(const char *ip) { 31 | uint32_t ip_long=0; 32 | uint8_t ip_len=strlen(ip); 33 | uint32_t ip_sec=0; 34 | int8_t ip_level=3; 35 | uint8_t i,n; 36 | for (i=0;i<=ip_len;i++) { 37 | if (i!=ip_len && ip[i]!='.' && ip[i]<48 || ip[i]>57) { 38 | continue; 39 | } 40 | if (ip[i]=='.' || i==ip_len) { 41 | /*too many .*/ 42 | if (ip_level==-1) { 43 | return 0; 44 | } 45 | for (n=0;nip) { 93 | fseek(qqwry_file,index_start,SEEK_SET); 94 | fread(index_bytes,7,1,qqwry_file); 95 | } 96 | return (uint32_t)LE_24(&index_bytes[4]); 97 | } 98 | static int readOrJumpRead(char *location,FILE *qqwry_file,const uint32_t data_index) { 99 | unsigned char c; 100 | unsigned char data_index_bytes[3]; 101 | uint32_t jump_data_index=0; 102 | if (data_index) { 103 | fseek(qqwry_file,data_index,SEEK_SET); 104 | } 105 | c=fgetc(qqwry_file); 106 | switch (c) { 107 | case REDIRECT_TYPE_2: 108 | case REDIRECT_TYPE_1: 109 | fread(data_index_bytes,3,1,qqwry_file); 110 | jump_data_index=LE_24(&data_index_bytes[0]); 111 | fseek(qqwry_file,jump_data_index,SEEK_SET); 112 | break; 113 | default: 114 | location[strlen(location)]=c; 115 | } 116 | if (c) { 117 | while (c=fgetc(qqwry_file)) { 118 | location[strlen(location)]=c; 119 | } 120 | } 121 | return 1; 122 | } 123 | static int is_cz88(const char *str) { 124 | int i; 125 | int l=strlen(str)-7; 126 | for (i=0;i 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #define BE_32(x) ((((uint8_t*)(x))[0]<<24) |\ 14 | (((uint8_t*)(x))[1]<<16) |\ 15 | (((uint8_t*)(x))[2]<<8) |\ 16 | ((uint8_t*)(x))[3]) 17 | 18 | #define LE_32(x) ((((uint8_t*)(x))[3]<<24) |\ 19 | (((uint8_t*)(x))[2]<<16) |\ 20 | (((uint8_t*)(x))[1]<<8) |\ 21 | ((uint8_t*)(x))[0]) 22 | 23 | #define LE_24(x) ((((uint8_t*)(x))[2]<<16) |\ 24 | (((uint8_t*)(x))[1]<<8) |\ 25 | ((uint8_t*)(x))[0]) 26 | 27 | #define REDIRECT_TYPE_1 0x01 28 | #define REDIRECT_TYPE_2 0x02 29 | 30 | static uint32_t ip2long(const char *ip) { 31 | uint32_t ip_long=0; 32 | uint8_t ip_len=strlen(ip); 33 | uint32_t ip_sec=0; 34 | int8_t ip_level=3; 35 | uint8_t i,n; 36 | for (i=0;i<=ip_len;i++) { 37 | if (i!=ip_len && ip[i]!='.' && ip[i]<48 || ip[i]>57) { 38 | continue; 39 | } 40 | if (ip[i]=='.' || i==ip_len) { 41 | /*too many .*/ 42 | if (ip_level==-1) { 43 | return 0; 44 | } 45 | for (n=0;nip) { 93 | fseek(qqwry_file,index_start,SEEK_SET); 94 | fread(index_bytes,7,1,qqwry_file); 95 | } 96 | return (uint32_t)LE_24(&index_bytes[4]); 97 | } 98 | static int readOrJumpRead(char *location,FILE *qqwry_file,const uint32_t data_index) { 99 | unsigned char c; 100 | unsigned char data_index_bytes[3]; 101 | uint32_t jump_data_index=0; 102 | if (data_index) { 103 | fseek(qqwry_file,data_index,SEEK_SET); 104 | } 105 | c=fgetc(qqwry_file); 106 | switch (c) { 107 | case REDIRECT_TYPE_2: 108 | case REDIRECT_TYPE_1: 109 | fread(data_index_bytes,3,1,qqwry_file); 110 | jump_data_index=LE_24(&data_index_bytes[0]); 111 | fseek(qqwry_file,jump_data_index,SEEK_SET); 112 | break; 113 | default: 114 | location[strlen(location)]=c; 115 | } 116 | if (c) { 117 | while (c=fgetc(qqwry_file)) { 118 | location[strlen(location)]=c; 119 | } 120 | } 121 | return 1; 122 | } 123 | static int is_cz88(const char *str) { 124 | int i; 125 | int l=strlen(str)-7; 126 | for (i=0;i 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #define BE_32(x) ((((uint8_t*)(x))[0]<<24) |\ 14 | (((uint8_t*)(x))[1]<<16) |\ 15 | (((uint8_t*)(x))[2]<<8) |\ 16 | ((uint8_t*)(x))[3]) 17 | 18 | #define LE_32(x) ((((uint8_t*)(x))[3]<<24) |\ 19 | (((uint8_t*)(x))[2]<<16) |\ 20 | (((uint8_t*)(x))[1]<<8) |\ 21 | ((uint8_t*)(x))[0]) 22 | 23 | #define LE_24(x) ((((uint8_t*)(x))[2]<<16) |\ 24 | (((uint8_t*)(x))[1]<<8) |\ 25 | ((uint8_t*)(x))[0]) 26 | 27 | #define REDIRECT_TYPE_1 0x01 28 | #define REDIRECT_TYPE_2 0x02 29 | 30 | static uint32_t ip2long(const char *ip) { 31 | uint32_t ip_long=0; 32 | uint8_t ip_len=strlen(ip); 33 | uint32_t ip_sec=0; 34 | int8_t ip_level=3; 35 | uint8_t i,n; 36 | for (i=0;i<=ip_len;i++) { 37 | if (i!=ip_len && ip[i]!='.' && ip[i]<48 || ip[i]>57) { 38 | continue; 39 | } 40 | if (ip[i]=='.' || i==ip_len) { 41 | /*too many .*/ 42 | if (ip_level==-1) { 43 | return 0; 44 | } 45 | for (n=0;nip) { 93 | fseek(qqwry_file,index_start,SEEK_SET); 94 | fread(index_bytes,7,1,qqwry_file); 95 | } 96 | return (uint32_t)LE_24(&index_bytes[4]); 97 | } 98 | static int readOrJumpRead(char *location,FILE *qqwry_file,const uint32_t data_index) { 99 | unsigned char c; 100 | unsigned char data_index_bytes[3]; 101 | uint32_t jump_data_index=0; 102 | if (data_index) { 103 | fseek(qqwry_file,data_index,SEEK_SET); 104 | } 105 | c=fgetc(qqwry_file); 106 | switch (c) { 107 | case REDIRECT_TYPE_2: 108 | case REDIRECT_TYPE_1: 109 | fread(data_index_bytes,3,1,qqwry_file); 110 | jump_data_index=LE_24(&data_index_bytes[0]); 111 | fseek(qqwry_file,jump_data_index,SEEK_SET); 112 | break; 113 | default: 114 | location[strlen(location)]=c; 115 | } 116 | if (c) { 117 | while (c=fgetc(qqwry_file)) { 118 | location[strlen(location)]=c; 119 | } 120 | } 121 | return 1; 122 | } 123 | static int is_cz88(const char *str) { 124 | int i; 125 | int l=strlen(str)-7; 126 | for (i=0;i 3 | * 4 | * 5 | * This source code is under the terms of the 6 | * GNU Lesser General Public License. 7 | * see 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #define BE_32(x) ((((uint8_t*)(x))[0]<<24) |\ 14 | (((uint8_t*)(x))[1]<<16) |\ 15 | (((uint8_t*)(x))[2]<<8) |\ 16 | ((uint8_t*)(x))[3]) 17 | 18 | #define LE_32(x) ((((uint8_t*)(x))[3]<<24) |\ 19 | (((uint8_t*)(x))[2]<<16) |\ 20 | (((uint8_t*)(x))[1]<<8) |\ 21 | ((uint8_t*)(x))[0]) 22 | 23 | #define LE_24(x) ((((uint8_t*)(x))[2]<<16) |\ 24 | (((uint8_t*)(x))[1]<<8) |\ 25 | ((uint8_t*)(x))[0]) 26 | 27 | #define REDIRECT_TYPE_1 0x01 28 | #define REDIRECT_TYPE_2 0x02 29 | 30 | static uint32_t ip2long(const char *ip) { 31 | uint32_t ip_long=0; 32 | uint8_t ip_len=strlen(ip); 33 | uint32_t ip_sec=0; 34 | int8_t ip_level=3; 35 | uint8_t i,n; 36 | for (i=0;i<=ip_len;i++) { 37 | if (i!=ip_len && ip[i]!='.' && ip[i]<48 || ip[i]>57) { 38 | continue; 39 | } 40 | if (ip[i]=='.' || i==ip_len) { 41 | /*too many .*/ 42 | if (ip_level==-1) { 43 | return 0; 44 | } 45 | for (n=0;nip) { 93 | fseek(qqwry_file,index_start,SEEK_SET); 94 | fread(index_bytes,7,1,qqwry_file); 95 | } 96 | return (uint32_t)LE_24(&index_bytes[4]); 97 | } 98 | static int readOrJumpRead(char *location,FILE *qqwry_file,const uint32_t data_index) { 99 | unsigned char c; 100 | unsigned char data_index_bytes[3]; 101 | uint32_t jump_data_index=0; 102 | if (data_index) { 103 | fseek(qqwry_file,data_index,SEEK_SET); 104 | } 105 | c=fgetc(qqwry_file); 106 | switch (c) { 107 | case REDIRECT_TYPE_2: 108 | case REDIRECT_TYPE_1: 109 | fread(data_index_bytes,3,1,qqwry_file); 110 | jump_data_index=LE_24(&data_index_bytes[0]); 111 | fseek(qqwry_file,jump_data_index,SEEK_SET); 112 | break; 113 | default: 114 | location[strlen(location)]=c; 115 | } 116 | if (c) { 117 | while (c=fgetc(qqwry_file)) { 118 | location[strlen(location)]=c; 119 | } 120 | } 121 | return 1; 122 | } 123 | static int is_cz88(const char *str) { 124 | int i; 125 | int l=strlen(str)-7; 126 | for (i=0;i | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | #ifdef HAVE_CONFIG_H 20 | #include "config.h" 21 | #endif 22 | 23 | #include "errno.h" 24 | #include "php.h" 25 | #include "php_ini.h" 26 | #include "ext/standard/info.h" 27 | #include "php_qqwry.h" 28 | #include "libqqwry/qqwry.h" 29 | 30 | #define QQWRY_ADDR1_LEN 64 31 | #define QQWRY_ADDR2_LEN 128 32 | 33 | ZEND_DECLARE_MODULE_GLOBALS(qqwry) 34 | 35 | /* True global resources - no need for thread safety here */ 36 | static zend_class_entry *qqwry_class_entry_ptr = NULL; 37 | 38 | /* {{{ proto string qqwry(string qqwry_path) 39 | */ 40 | PHP_METHOD(qqwry,__construct) 41 | { 42 | char *qqwry_path = NULL; 43 | size_t qqwry_len; 44 | zval * _this_zval = NULL; 45 | if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,getThis(), "Os",&_this_zval,qqwry_class_entry_ptr, &qqwry_path,&qqwry_len) == FAILURE) { 46 | return; 47 | } 48 | #if PHP_API_VERSION <= 20131106 49 | add_property_string(_this_zval,"f",qqwry_path,1); 50 | #else 51 | add_property_string(_this_zval,"f",qqwry_path); 52 | #endif 53 | } 54 | /* }}} */ 55 | 56 | /* {{{ proto string q(string arg) 57 | Return Array,of which the 1st value is addr1 and the 2nd value is addr2*/ 58 | PHP_METHOD(qqwry,q) 59 | { 60 | char *ip_string = NULL; 61 | size_t ipstring_len; 62 | zval * _this_zval = NULL; 63 | 64 | if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,getThis(), "Os",&_this_zval,qqwry_class_entry_ptr, &ip_string, &ipstring_len) == FAILURE) { 65 | return; 66 | } 67 | #if PHP_API_VERSION <= 20131106 68 | zval *zaddr1,*zaddr2; 69 | zval **tmp; 70 | #else 71 | zval zaddr1,zaddr2; 72 | zval *tmp; 73 | #endif 74 | char *addr1=(char *)emalloc(QQWRY_ADDR1_LEN); 75 | char *addr2=(char *)emalloc(QQWRY_ADDR2_LEN); 76 | memset(addr1,0,QQWRY_ADDR1_LEN); 77 | memset(addr2,0,QQWRY_ADDR2_LEN); 78 | char *qqwry_path; 79 | 80 | #if PHP_API_VERSION <= 20131106 81 | if (zend_hash_find(Z_OBJPROP_P(_this_zval),"f",sizeof("f"),(void **)&tmp)==FAILURE) { 82 | return; 83 | } 84 | qqwry_path=Z_STRVAL_PP(tmp); 85 | #else 86 | zend_string *sp = zend_string_init("f", sizeof("f") - 1, 0); 87 | if ((tmp = zend_hash_find(Z_OBJPROP_P(_this_zval), sp)) == NULL) { 88 | return; 89 | } 90 | qqwry_path=Z_STRVAL_P(tmp); 91 | #endif 92 | 93 | FILE *fp=NULL; 94 | qqwry_fp_list *qfl=QQWRY_G(fp_list); 95 | while (qfl) { 96 | if (!strcmp(qfl->filepath,qqwry_path)) { 97 | fp=qfl->fp; 98 | break; 99 | } 100 | qfl=qfl->next; 101 | } 102 | 103 | if (!fp) { 104 | qqwry_fp_list *pre_qfl=NULL; 105 | qfl=QQWRY_G(fp_list); 106 | while (qfl) { 107 | pre_qfl=qfl; 108 | qfl=qfl->next; 109 | } 110 | fp=fopen(qqwry_path,"rb"); 111 | if (!fp) { 112 | php_error_docref(NULL TSRMLS_CC, E_WARNING,"%s",strerror(errno)); 113 | return; 114 | } 115 | qfl=emalloc(sizeof(qqwry_fp_list)); 116 | qfl->filepath = estrndup(qqwry_path, strlen(qqwry_path)); 117 | qfl->fp=fp; 118 | qfl->next=NULL; 119 | if (pre_qfl) { 120 | pre_qfl->next=qfl; 121 | } else { 122 | QQWRY_G(fp_list)=qfl; 123 | } 124 | } 125 | 126 | qqwry_get_location(addr1,addr2,ip_string,fp); 127 | 128 | #if PHP_API_VERSION <= 20131106 129 | MAKE_STD_ZVAL(zaddr1); 130 | ZVAL_STRING(zaddr1,addr1,0); 131 | MAKE_STD_ZVAL(zaddr2); 132 | ZVAL_STRING(zaddr2,addr2,0); 133 | 134 | array_init(return_value); 135 | add_next_index_zval(return_value,zaddr1); 136 | add_next_index_zval(return_value,zaddr2); 137 | #else 138 | ZVAL_STRING(&zaddr1,addr1); 139 | efree(addr1); 140 | ZVAL_STRING(&zaddr2,addr2); 141 | efree(addr2); 142 | 143 | array_init(return_value); 144 | add_next_index_zval(return_value,&zaddr1); 145 | add_next_index_zval(return_value,&zaddr2); 146 | #endif 147 | 148 | } 149 | /* }}} */ 150 | 151 | 152 | 153 | /* {{{ qqwry_functions[] 154 | */ 155 | zend_function_entry qqwry_functions[] = { 156 | {NULL, NULL, NULL} /* Must be the last line in qqwry_functions[] */ 157 | }; 158 | /* }}} */ 159 | 160 | /* {{{ qqwry_methods[] 161 | */ 162 | static zend_function_entry php_qqwry_class_functions[] = { 163 | PHP_ME(qqwry, __construct, NULL, ZEND_ACC_PUBLIC) 164 | PHP_ME(qqwry, q, NULL, ZEND_ACC_PUBLIC) 165 | {NULL, NULL, NULL} /* Must be the last line in qqwry_functions[] */ 166 | }; 167 | /* }}} */ 168 | 169 | 170 | /* {{{ qqwry_module_entry 171 | */ 172 | zend_module_entry qqwry_module_entry = { 173 | #if ZEND_MODULE_API_NO >= 20010901 174 | STANDARD_MODULE_HEADER, 175 | #endif 176 | "qqwry", 177 | qqwry_functions, 178 | PHP_MINIT(qqwry), 179 | PHP_MSHUTDOWN(qqwry), 180 | PHP_RINIT(qqwry), /* Replace with NULL if there's nothing to do at request start */ 181 | PHP_RSHUTDOWN(qqwry), /* Replace with NULL if there's nothing to do at request end */ 182 | PHP_MINFO(qqwry), 183 | #if ZEND_MODULE_API_NO >= 20010901 184 | "0.1", /* Replace with version number for your extension */ 185 | #endif 186 | STANDARD_MODULE_PROPERTIES 187 | }; 188 | /* }}} */ 189 | 190 | #ifdef COMPILE_DL_QQWRY 191 | ZEND_GET_MODULE(qqwry) 192 | #endif 193 | 194 | 195 | 196 | /* {{{ PHP_MINIT_FUNCTION 197 | */ 198 | PHP_MINIT_FUNCTION(qqwry) 199 | { 200 | #ifdef ZTS 201 | ZEND_INIT_MODULE_GLOBALS(qqwry,NULL,NULL); 202 | #endif 203 | zend_class_entry qqwry_class_entry; 204 | INIT_CLASS_ENTRY(qqwry_class_entry, "qqwry", php_qqwry_class_functions); 205 | qqwry_class_entry_ptr = zend_register_internal_class(&qqwry_class_entry TSRMLS_CC); 206 | return SUCCESS; 207 | } 208 | /* }}} */ 209 | 210 | /* {{{ PHP_MSHUTDOWN_FUNCTION 211 | */ 212 | PHP_MSHUTDOWN_FUNCTION(qqwry) 213 | { 214 | return SUCCESS; 215 | } 216 | /* }}} */ 217 | 218 | /* {{{ PHP_RINIT_FUNCTION 219 | */ 220 | PHP_RINIT_FUNCTION(qqwry) 221 | { 222 | QQWRY_G(fp_list)=NULL; 223 | return SUCCESS; 224 | } 225 | /* }}} */ 226 | 227 | /* {{{ PHP_RSHUTDOWN_FUNCTION 228 | */ 229 | PHP_RSHUTDOWN_FUNCTION(qqwry) 230 | { 231 | qqwry_fp_list *qfl=QQWRY_G(fp_list); 232 | qqwry_fp_list *pre_qfl=NULL; 233 | while (qfl) { 234 | pre_qfl=qfl; 235 | qfl=qfl->next; 236 | fclose(pre_qfl->fp); 237 | efree(pre_qfl->filepath); 238 | efree(pre_qfl); 239 | } 240 | return SUCCESS; 241 | } 242 | /* }}} */ 243 | 244 | /* {{{ PHP_MINFO_FUNCTION 245 | */ 246 | PHP_MINFO_FUNCTION(qqwry) 247 | { 248 | php_info_print_table_start(); 249 | php_info_print_table_header(2, "qqwry support", "enabled"); 250 | php_info_print_table_end(); 251 | } 252 | /* }}} */ 253 | 254 | /* 255 | * Local variables: 256 | * tab-width: 4 257 | * c-basic-offset: 4 258 | * End: 259 | * vim600: noet sw=4 ts=4 fdm=marker 260 | * vim<600: noet sw=4 ts=4 261 | */ 262 | -------------------------------------------------------------------------------- /tools/charset-convert.php: -------------------------------------------------------------------------------- 1 | ftell($input_fp)) { 50 | $c=fread($input_fp,1); 51 | $buffer=$c; 52 | if (strpos($data_indexes_str,'.'.(ftell($input_fp)-1).'.')!==false) { 53 | $buffer.=fread($input_fp,3); 54 | } else if ($c==MODE_1 || $c==MODE_2) { 55 | $buffer.=fread($input_fp,3); 56 | } else { 57 | while (ord($c=fread($input_fp,1))>0) { 58 | $buffer.=$c; 59 | } 60 | if ($c!=RECORD_END) { 61 | echo "fread error\n"; 62 | exit(1); 63 | } 64 | $buffer_old_len=strlen($buffer); 65 | $buffer=iconv('GBK','UTF-8',$buffer); 66 | $total_larger += (strlen($buffer)-$buffer_old_len); 67 | $offset_larger[ftell($input_fp)]=$total_larger; 68 | //file_put_contents('tmp2.zh.utf8',$buffer."\n",FILE_APPEND); 69 | $buffer.=$c; 70 | } 71 | $l=strlen($buffer); 72 | $i++; 73 | echo "\r",$i,'-------'; 74 | $location_utf8_data.=$buffer; 75 | } 76 | //exit; 77 | file_put_contents($tmp_data_dir.'/location_utf8_data',$location_utf8_data); 78 | storeVar('total_larger',$total_larger); 79 | storeVar('offset_larger',$offset_larger); 80 | touch($tmp_data_dir.'/step2'); 81 | } else { 82 | echo "skip step 2\n"; 83 | $location_utf8_data=file_get_contents($tmp_data_dir.'/location_utf8_data'); 84 | loadVar('total_larger'); 85 | loadVar('offset_larger'); 86 | } 87 | echo "\ntotal larger:",$total_larger,"\n"; 88 | 89 | $output_fp=fopen($output_file,'ab'); 90 | 91 | if (!file_exists($tmp_data_dir.'/step3')) { 92 | echo 'patching header ... '; 93 | fwrite($output_fp,pack('V',$index_start+$total_larger)); 94 | fwrite($output_fp,pack('V',$index_end+$total_larger)); 95 | echo "ok\n"; 96 | touch($tmp_data_dir.'/step3'); 97 | } else { 98 | echo "skip step 3\n"; 99 | } 100 | 101 | /* 102 | patching index block must before patching data block. 103 | 104 | because we must get new indexes data 105 | to check a point in data block such as 0x01 is a redirect mod mark or a part of a ip. 106 | 107 | Of course I can get these data during step 2 108 | if I create a new data indexes array. 109 | As you guys knows, large array is a bullshit. 110 | */ 111 | if (!file_exists($tmp_data_dir.'/step4')) { 112 | echo 'patching index block (+',$total_larger,')... '; 113 | $i=0; 114 | fseek($input_fp,$index_start); 115 | $buffer=''; 116 | while ($index_end_bottom!=ftell($input_fp)) { 117 | $buffer .= fread($input_fp,4); 118 | 119 | $f_offset=$data_indexes[$i]; 120 | $f_offset_new=$f_offset; 121 | for ($n=0;$n<=$f_offset;$n++) { 122 | if (isset($offset_larger[$f_offset-$n])) { 123 | $f_offset_new+=$offset_larger[$f_offset-$n]; 124 | break; 125 | } 126 | } 127 | if ($f_offset_new===$f_offset) { 128 | echo 'warning: new offset','===old offset(',$f_offset,') i:',$i,"\n"; 129 | } else { 130 | /* 131 | update data_indexes 132 | which will be used to check 133 | whether a point in data block is the start of a ip 134 | */ 135 | $data_indexes[$i]=$f_offset_new; 136 | } 137 | 138 | $buffer .= substr(pack('V',$f_offset_new),0,3); 139 | fseek($input_fp,3,SEEK_CUR); 140 | $i++; 141 | } 142 | file_put_contents($tmp_data_dir.'/index_block',$buffer); 143 | storeVar('data_indexes',$data_indexes); 144 | echo "ok\n"; 145 | touch($tmp_data_dir.'/step4'); 146 | } else { 147 | loadVar('data_indexes'); 148 | $buffer=file_get_contents($tmp_data_dir.'/index_block'); 149 | echo "skip step 4\n"; 150 | } 151 | 152 | //strpos() is better than in_array() 153 | $data_indexes_str='.'.implode('.',$data_indexes).'.'; 154 | unset($data_indexes); 155 | 156 | if (!file_exists($tmp_data_dir.'/step5')) { 157 | echo 'patching data block ... '; 158 | $f_offset=0; 159 | for ($i=0;$i 2 | 6 | geoip 7 | pecl.php.net 8 | Map IP address to geographic places 9 | This PHP extension allows you to find the location of an IP address - City, State, Country, Longitude, Latitude, and other information as all, such as ISP and connection type. For more info, please visit Maxmind's website. 10 | 11 | 12 | 13 | Olivier Hill 14 | ohill 15 | ohill@php.net 16 | yes 17 | 18 | 2014-05-01 19 | 20 | 21 | 1.1.1-dev 22 | 1.0.3 23 | 24 | 25 | beta 26 | stable 27 | 28 | PHP License 29 | * 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 4.3.0 66 | 67 | 68 | 1.4.0b1 69 | 70 | 71 | 72 | geoip 73 | 74 | 75 | 76 | 77 | 1.1.0 78 | 1.0.3 79 | 80 | 81 | beta 82 | stable 83 | 84 | 2014-05-01 85 | PHP License 86 | * Add geoip_setup_custom_directory() to setup custom directories per request. 87 | * Remove E_NOTICES for IPs not found in database. 88 | * Fix a segfault with geoip_db_get_all_info() on newer libs (bug #64692). 89 | * Add support for geoip_netspeedcell_by_name(), geoip_asnum_by_name() and geoip_domain_by_name() (bug #67121). 90 | * Fix memory leak with custom directories (bug #67138). 91 | * Support changing custom directory via ini_set() (bug #61607). 92 | 93 | 94 | 95 | 96 | 1.0.8 97 | 1.0.3 98 | 99 | 100 | stable 101 | stable 102 | 103 | 2011-10-23 104 | PHP License 105 | * Windows support 106 | * Fix segfault with newer geoip libraries and geoip_db_get_all_info() (bug #60066) 107 | * Use X-Macros for repeated code 108 | * Updated tests 109 | 110 | 111 | 112 | 113 | 1.0.7 114 | 1.0.3 115 | 116 | 117 | stable 118 | stable 119 | 120 | 2009-03-11 121 | PHP License 122 | * Do not issue a NOTICE when values don't exist for timezone and region name (as added in 1.0.4) 123 | * Fix a compile issue on FreeBSD 124 | * Try to be bulletproof on library features detection. 125 | 126 | 127 | 128 | 129 | 1.0.6 130 | 1.0.3 131 | 132 | 133 | stable 134 | stable 135 | 136 | 2009-01-20 137 | PHP License 138 | * Fixing compile bug when multiple GeoIP libs are installed, bug #15372. 139 | 140 | 141 | 142 | 143 | 1.0.5 144 | 1.0.3 145 | 146 | 147 | stable 148 | stable 149 | 150 | 2008-12-19 151 | PHP License 152 | * Small bug in phpinfo() when printing version number could crash PHP. 153 | 154 | 155 | 156 | 157 | 1.0.4 158 | 1.0.3 159 | 160 | 161 | stable 162 | stable 163 | 164 | 2008-12-19 165 | PHP License 166 | * Fix memleaks, bug #14851 167 | * Small patch for MacPorts by jhohle 168 | * Add geoip_time_zone_by_country_and_region() and geoip_region_name_by_code() (thanks to Sid Dunayer) 169 | * Add continent_code field for City Database, only if using GeoIP lib 1.4.3 or newer 170 | 171 | 172 | 173 | 174 | 1.0.3 175 | 1.0.3 176 | 177 | 178 | stable 179 | stable 180 | 181 | 2008-06-12 182 | PHP License 183 | * Change license from PHP 3.0 to PHP 3.01 for Debian? 184 | * Added geoip_continent_code_by_name() to get continent instead of country 185 | * Fixing a small casting issue (compiler warning) 186 | * Fixing missing entries in geoip_record_by_name(), bug #14131 187 | 188 | 189 | 190 | 191 | 1.0.2 192 | 1.0.2 193 | 194 | 195 | stable 196 | stable 197 | 198 | 2007-11-20 199 | PHP 200 | * Added geoip_isp_by_name (patch by Yannick Gard) 201 | 202 | 203 | 204 | 205 | 1.0.1 206 | 1.0.1 207 | 208 | 209 | stable 210 | stable 211 | 212 | 2007-08-22 213 | PHP 214 | * Added geoip_db_avail() to check for DB availability (file found) 215 | * Added geoip_db_filename() to get the internal file name of the library 216 | * Added geoip_db_get_all_info() to fetch all info about all database types 217 | * Added some tests so that make test can crunch something. 218 | * Added database file path and name in warning when DB is not found. 219 | * Added geoip.custom_directory php.ini option to change default path for DBs 220 | 221 | 222 | 223 | 224 | 1.0.0 225 | 1.0.0 226 | 227 | 228 | stable 229 | stable 230 | 231 | 2007-08-14 232 | PHP 233 | * Marked as stable 234 | * Fixing wrong version number inside extension 235 | 236 | 237 | 238 | 239 | 0.2.0 240 | 0.2.0 241 | 242 | 243 | beta 244 | beta 245 | 246 | 2006-08-22 247 | PHP 248 | Initial PECL release 249 | 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /php/geoip/geoip.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2009 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Olivier Hill | 16 | | Matthew Fonda | 17 | +----------------------------------------------------------------------+ 18 | Please contact support@maxmind.com with any comments 19 | */ 20 | 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include 27 | #include 28 | #ifdef PHP_WIN32 29 | #include 30 | #endif 31 | 32 | #include "php.h" 33 | #include "php_ini.h" 34 | #include "ext/standard/info.h" 35 | #include "php_geoip.h" 36 | 37 | 38 | 39 | ZEND_DECLARE_MODULE_GLOBALS(geoip) 40 | 41 | static int le_geoip; 42 | 43 | /* {{{ */ 44 | zend_function_entry geoip_functions[] = { 45 | PHP_FE(geoip_database_info, NULL) 46 | #define GEOIPDEF(php_func, c_func, db_type) \ 47 | PHP_FE(php_func, NULL) 48 | #include "geoip.def" 49 | #undef GEOIPDEF 50 | PHP_FE(geoip_continent_code_by_name, NULL) 51 | PHP_FE(geoip_org_by_name, NULL) 52 | PHP_FE(geoip_record_by_name, NULL) 53 | PHP_FE(geoip_id_by_name, NULL) 54 | PHP_FE(geoip_region_by_name, NULL) 55 | PHP_FE(geoip_isp_by_name, NULL) 56 | PHP_FE(geoip_db_avail, NULL) 57 | PHP_FE(geoip_db_get_all_info, NULL) 58 | PHP_FE(geoip_db_filename, NULL) 59 | #if LIBGEOIP_VERSION >= 1004001 60 | PHP_FE(geoip_region_name_by_code, NULL) 61 | PHP_FE(geoip_time_zone_by_country_and_region, NULL) 62 | #endif 63 | #ifdef HAVE_CUSTOM_DIRECTORY 64 | PHP_FE(geoip_setup_custom_directory, NULL) 65 | #endif 66 | PHP_FE(geoip_asnum_by_name, NULL) 67 | PHP_FE(geoip_domain_by_name, NULL) 68 | #if LIBGEOIP_VERSION >= 1004008 69 | PHP_FE(geoip_netspeedcell_by_name, NULL) 70 | #endif 71 | {NULL, NULL, NULL} 72 | }; 73 | /* }}} */ 74 | 75 | /* {{{ geoip_module_entry 76 | */ 77 | zend_module_entry geoip_module_entry = { 78 | #if ZEND_MODULE_API_NO >= 20010901 79 | STANDARD_MODULE_HEADER, 80 | #endif 81 | "geoip", 82 | geoip_functions, 83 | PHP_MINIT(geoip), 84 | PHP_MSHUTDOWN(geoip), 85 | PHP_RINIT(geoip), 86 | PHP_RSHUTDOWN(geoip), 87 | PHP_MINFO(geoip), 88 | #if ZEND_MODULE_API_NO >= 20010901 89 | PHP_GEOIP_VERSION, /* version number of the extension */ 90 | #endif 91 | STANDARD_MODULE_PROPERTIES 92 | }; 93 | /* }}} */ 94 | 95 | #ifdef COMPILE_DL_GEOIP 96 | ZEND_GET_MODULE(geoip) 97 | #endif 98 | 99 | #ifdef HAVE_CUSTOM_DIRECTORY 100 | /* {{{ geoip_change_custom_directory() helper function 101 | */ 102 | static void geoip_change_custom_directory(char *value) 103 | { 104 | #if LIBGEOIP_VERSION >= 1004007 105 | GeoIP_cleanup(); 106 | #else 107 | int i; 108 | if (GeoIPDBFileName != NULL) { 109 | for (i = 0; i < NUM_DB_TYPES; i++) { 110 | if (GeoIPDBFileName[i]) { 111 | free(GeoIPDBFileName[i]); 112 | } 113 | } 114 | free(GeoIPDBFileName); 115 | GeoIPDBFileName = NULL; 116 | } 117 | #endif 118 | 119 | GeoIP_setup_custom_directory(value); 120 | GeoIP_db_avail(GEOIP_COUNTRY_EDITION); 121 | } 122 | /* }}} */ 123 | #endif 124 | 125 | #ifdef HAVE_CUSTOM_DIRECTORY 126 | /* {{{ PHP_INI_MH 127 | + */ 128 | static PHP_INI_MH(OnUpdateDirectory) 129 | { 130 | if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { 131 | GEOIP_G(set_runtime_custom_directory) = 1; 132 | #if PHP_MAJOR_VERSION >= 7 133 | geoip_change_custom_directory(new_value->val); 134 | #else 135 | geoip_change_custom_directory(new_value); 136 | #endif 137 | return SUCCESS; 138 | } 139 | 140 | #if PHP_MAJOR_VERSION >= 7 141 | return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); 142 | #else 143 | return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); 144 | #endif 145 | } 146 | /* }}} */ 147 | #endif 148 | 149 | /* {{{ PHP_INI 150 | */ 151 | PHP_INI_BEGIN() 152 | #ifdef HAVE_CUSTOM_DIRECTORY 153 | STD_PHP_INI_ENTRY("geoip.custom_directory", NULL, PHP_INI_ALL, OnUpdateDirectory, custom_directory, zend_geoip_globals, geoip_globals) 154 | #endif 155 | PHP_INI_END() 156 | /* }}} */ 157 | 158 | /* {{{ php_geoip_init_globals 159 | */ 160 | static void php_geoip_init_globals(zend_geoip_globals *geoip_globals) 161 | { 162 | geoip_globals->custom_directory = NULL; 163 | geoip_globals->set_runtime_custom_directory = 0; 164 | } 165 | /* }}} */ 166 | 167 | /* {{{ PHP_MINIT_FUNCTION 168 | */ 169 | PHP_MINIT_FUNCTION(geoip) 170 | { 171 | ZEND_INIT_MODULE_GLOBALS(geoip, php_geoip_init_globals, NULL); 172 | REGISTER_INI_ENTRIES(); 173 | 174 | /* @TODO: Do something for custom_directory before initialization here */ 175 | 176 | #ifdef HAVE_CUSTOM_DIRECTORY 177 | GeoIP_setup_custom_directory(GEOIP_G(custom_directory)); 178 | #endif 179 | /* This will initialize file structure */ 180 | GeoIP_db_avail(GEOIP_COUNTRY_EDITION); 181 | 182 | /* For database type constants */ 183 | REGISTER_LONG_CONSTANT("GEOIP_COUNTRY_EDITION", GEOIP_COUNTRY_EDITION, CONST_CS | CONST_PERSISTENT); 184 | REGISTER_LONG_CONSTANT("GEOIP_REGION_EDITION_REV0", GEOIP_REGION_EDITION_REV0, CONST_CS | CONST_PERSISTENT); 185 | REGISTER_LONG_CONSTANT("GEOIP_CITY_EDITION_REV0", GEOIP_CITY_EDITION_REV0, CONST_CS | CONST_PERSISTENT); 186 | REGISTER_LONG_CONSTANT("GEOIP_ORG_EDITION", GEOIP_ORG_EDITION, CONST_CS | CONST_PERSISTENT); 187 | REGISTER_LONG_CONSTANT("GEOIP_ISP_EDITION", GEOIP_ISP_EDITION, CONST_CS | CONST_PERSISTENT); 188 | REGISTER_LONG_CONSTANT("GEOIP_CITY_EDITION_REV1", GEOIP_CITY_EDITION_REV1, CONST_CS | CONST_PERSISTENT); 189 | REGISTER_LONG_CONSTANT("GEOIP_REGION_EDITION_REV1", GEOIP_REGION_EDITION_REV1, CONST_CS | CONST_PERSISTENT); 190 | REGISTER_LONG_CONSTANT("GEOIP_PROXY_EDITION", GEOIP_PROXY_EDITION, CONST_CS | CONST_PERSISTENT); 191 | REGISTER_LONG_CONSTANT("GEOIP_ASNUM_EDITION", GEOIP_ASNUM_EDITION, CONST_CS | CONST_PERSISTENT); 192 | REGISTER_LONG_CONSTANT("GEOIP_NETSPEED_EDITION", GEOIP_NETSPEED_EDITION, CONST_CS | CONST_PERSISTENT); 193 | REGISTER_LONG_CONSTANT("GEOIP_DOMAIN_EDITION", GEOIP_DOMAIN_EDITION, CONST_CS | CONST_PERSISTENT); 194 | #if LIBGEOIP_VERSION >= 1004008 195 | REGISTER_LONG_CONSTANT("GEOIP_NETSPEED_EDITION_REV1",GEOIP_NETSPEED_EDITION_REV1,CONST_CS | CONST_PERSISTENT); 196 | #endif 197 | 198 | /* For netspeed constants */ 199 | REGISTER_LONG_CONSTANT("GEOIP_UNKNOWN_SPEED", GEOIP_UNKNOWN_SPEED, CONST_CS | CONST_PERSISTENT); 200 | REGISTER_LONG_CONSTANT("GEOIP_DIALUP_SPEED", GEOIP_DIALUP_SPEED, CONST_CS | CONST_PERSISTENT); 201 | REGISTER_LONG_CONSTANT("GEOIP_CABLEDSL_SPEED", GEOIP_CABLEDSL_SPEED, CONST_CS | CONST_PERSISTENT); 202 | REGISTER_LONG_CONSTANT("GEOIP_CORPORATE_SPEED", GEOIP_CORPORATE_SPEED, CONST_CS | CONST_PERSISTENT); 203 | 204 | return SUCCESS; 205 | } 206 | /* }}} */ 207 | 208 | /* {{{ PHP_MSHUTDOWN_FUNCTION 209 | */ 210 | PHP_MSHUTDOWN_FUNCTION(geoip) 211 | { 212 | return SUCCESS; 213 | } 214 | /* }}} */ 215 | 216 | 217 | /* {{{ PHP_RINIT_FUNCTION 218 | */ 219 | PHP_RINIT_FUNCTION(geoip) 220 | { 221 | return SUCCESS; 222 | } 223 | /* }}} */ 224 | 225 | 226 | /* {{{ PHP_RSHUTDOWN_FUNCTION 227 | */ 228 | PHP_RSHUTDOWN_FUNCTION(geoip) 229 | { 230 | #ifdef HAVE_CUSTOM_DIRECTORY 231 | /* If we have a custom directory (and have support from */ 232 | /* libgeoip, we reset the extension to default directory) */ 233 | if (GEOIP_G(set_runtime_custom_directory)) { 234 | geoip_change_custom_directory(GEOIP_G(custom_directory)); 235 | GEOIP_G(set_runtime_custom_directory) = 0; 236 | } 237 | #endif 238 | 239 | return SUCCESS; 240 | } 241 | /* }}} */ 242 | 243 | /* {{{ PHP_MINFO_FUNCTION 244 | */ 245 | PHP_MINFO_FUNCTION(geoip) 246 | { 247 | char buf[32]; 248 | 249 | php_info_print_table_start(); 250 | php_info_print_table_header(2, "geoip support", "enabled"); 251 | php_info_print_table_row(2, "geoip extension version", PHP_GEOIP_VERSION); 252 | snprintf(buf, sizeof(buf), "%d", LIBGEOIP_VERSION); 253 | php_info_print_table_row(2, "geoip library version", buf); 254 | php_info_print_table_end(); 255 | DISPLAY_INI_ENTRIES(); 256 | } 257 | /* }}} */ 258 | 259 | /* {{{ proto boolean geoip_db_avail( [ int database ] ) */ 260 | PHP_FUNCTION(geoip_db_avail) 261 | { 262 | zend_long edition; 263 | 264 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &edition) == FAILURE) { 265 | return; 266 | } 267 | 268 | if (edition < 0 || edition >= NUM_DB_TYPES) 269 | { 270 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 271 | return; 272 | } 273 | 274 | RETURN_BOOL(GeoIP_db_avail(edition)); 275 | } 276 | /* }}} */ 277 | 278 | /* {{{ proto string geoip_db_filename( [ int database ] ) */ 279 | PHP_FUNCTION(geoip_db_filename) 280 | { 281 | zend_long edition; 282 | 283 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &edition) == FAILURE) { 284 | return; 285 | } 286 | 287 | if (edition < 0 || edition >= NUM_DB_TYPES) 288 | { 289 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 290 | return; 291 | } 292 | 293 | if (NULL != GeoIPDBFileName[edition]) 294 | #if PHP_MAJOR_VERSION >= 7 295 | RETURN_STRING(GeoIPDBFileName[edition]); 296 | #else 297 | RETURN_STRING(GeoIPDBFileName[edition], 1); 298 | #endif 299 | } 300 | /* }}} */ 301 | 302 | /* {{{ proto array geoip_db_get_all_info( ) */ 303 | PHP_FUNCTION(geoip_db_get_all_info) 304 | { 305 | int i; 306 | 307 | array_init(return_value); 308 | 309 | for (i=0; i < NUM_DB_TYPES; i++) 310 | { 311 | if (NULL != GeoIPDBDescription[i]) 312 | { 313 | #if PHP_MAJOR_VERSION >= 7 314 | zval real_row; 315 | zval *row = &real_row; 316 | 317 | array_init(row); 318 | #else 319 | zval *row; 320 | ALLOC_INIT_ZVAL(row); 321 | array_init(row); 322 | #endif 323 | 324 | add_assoc_bool(row, "available", GeoIP_db_avail(i)); 325 | if (GeoIPDBDescription[i]) { 326 | #if PHP_MAJOR_VERSION >= 7 327 | add_assoc_string(row, "description", (char *)GeoIPDBDescription[i]); 328 | #else 329 | add_assoc_string(row, "description", (char *)GeoIPDBDescription[i], 1); 330 | #endif 331 | } 332 | if (GeoIPDBFileName[i]) { 333 | #if PHP_MAJOR_VERSION >= 7 334 | add_assoc_string(row, "filename", GeoIPDBFileName[i]); 335 | #else 336 | add_assoc_string(row, "filename", GeoIPDBFileName[i], 1); 337 | #endif 338 | } 339 | 340 | add_index_zval(return_value, i, row); 341 | } 342 | } 343 | } 344 | /* }}} */ 345 | 346 | /* {{{ proto string geoip_database_info( [ int database ] ) 347 | Returns GeoIP Database information */ 348 | PHP_FUNCTION(geoip_database_info) 349 | { 350 | GeoIP * gi; 351 | char * db_info; 352 | zend_long edition = GEOIP_COUNTRY_EDITION; 353 | 354 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &edition) == FAILURE) { 355 | return; 356 | } 357 | 358 | if (edition < 0 || edition >= NUM_DB_TYPES) 359 | { 360 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 361 | return; 362 | } 363 | 364 | if (GeoIP_db_avail(edition)) { 365 | gi = GeoIP_open_type(edition, GEOIP_STANDARD); 366 | } else { 367 | if (NULL != GeoIPDBFileName[edition]) 368 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 369 | else 370 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available."); 371 | return; 372 | } 373 | 374 | db_info = GeoIP_database_info(gi); 375 | GeoIP_delete(gi); 376 | 377 | #if PHP_MAJOR_VERSION >= 7 378 | RETVAL_STRING(db_info); 379 | #else 380 | RETVAL_STRING(db_info, 1); 381 | #endif 382 | free(db_info); 383 | } 384 | /* }}} */ 385 | 386 | /* {{{ */ 387 | #if PHP_MAJOR_VERSION >= 7 388 | #define GEOIPDEF(php_func, c_func, db_type) \ 389 | PHP_FUNCTION(php_func) \ 390 | { \ 391 | GeoIP * gi; \ 392 | char * hostname = NULL; \ 393 | const char * return_code; \ 394 | size_t arglen; \ 395 | \ 396 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { \ 397 | return; \ 398 | } \ 399 | \ 400 | if (GeoIP_db_avail(db_type)) { \ 401 | gi = GeoIP_open_type(db_type, GEOIP_STANDARD); \ 402 | } else { \ 403 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[db_type]); \ 404 | return; \ 405 | } \ 406 | \ 407 | return_code = c_func(gi, hostname); \ 408 | GeoIP_delete(gi); \ 409 | if (return_code == NULL) { \ 410 | RETURN_FALSE; \ 411 | } \ 412 | RETURN_STRING((char*)return_code); \ 413 | \ 414 | } 415 | #else 416 | #define GEOIPDEF(php_func, c_func, db_type) \ 417 | PHP_FUNCTION(php_func) \ 418 | { \ 419 | GeoIP * gi; \ 420 | char * hostname = NULL; \ 421 | const char * return_code; \ 422 | int arglen; \ 423 | \ 424 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { \ 425 | return; \ 426 | } \ 427 | \ 428 | if (GeoIP_db_avail(db_type)) { \ 429 | gi = GeoIP_open_type(db_type, GEOIP_STANDARD); \ 430 | } else { \ 431 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[db_type]); \ 432 | return; \ 433 | } \ 434 | \ 435 | return_code = c_func(gi, hostname); \ 436 | GeoIP_delete(gi); \ 437 | if (return_code == NULL) { \ 438 | RETURN_FALSE; \ 439 | } \ 440 | RETURN_STRING((char*)return_code, 1); \ 441 | \ 442 | } 443 | #endif 444 | #include "geoip.def" 445 | #undef GEOIPDEF 446 | /* }}} */ 447 | 448 | /* {{{ proto string geoip_continent_code_by_name( string hostname ) 449 | Returns the Continent name found in the GeoIP Database */ 450 | PHP_FUNCTION(geoip_continent_code_by_name) 451 | { 452 | GeoIP * gi; 453 | char * hostname = NULL; 454 | int id; 455 | #if PHP_MAJOR_VERSION >= 7 456 | size_t arglen; 457 | #else 458 | int arglen; 459 | #endif 460 | 461 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 462 | return; 463 | } 464 | 465 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 466 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 467 | } else { 468 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 469 | return; 470 | } 471 | 472 | id = GeoIP_id_by_name(gi, hostname); 473 | GeoIP_delete(gi); 474 | if (id == 0) { 475 | RETURN_FALSE; 476 | } 477 | #if PHP_MAJOR_VERSION >= 7 478 | RETURN_STRING((char *)GeoIP_country_continent[id]); 479 | #else 480 | RETURN_STRING((char *)GeoIP_country_continent[id], 1); 481 | #endif 482 | } 483 | /* }}} */ 484 | 485 | /* {{{ proto string geoip_org_by_name( string hostname ) 486 | Returns the Organization Name found in the GeoIP Database */ 487 | PHP_FUNCTION(geoip_org_by_name) 488 | { 489 | GeoIP * gi; 490 | char * hostname = NULL; 491 | char * org; 492 | #if PHP_MAJOR_VERSION >= 7 493 | size_t arglen; 494 | #else 495 | int arglen; 496 | #endif 497 | 498 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 499 | return; 500 | } 501 | 502 | if (GeoIP_db_avail(GEOIP_ORG_EDITION)) { 503 | gi = GeoIP_open_type(GEOIP_ORG_EDITION, GEOIP_STANDARD); 504 | } else { 505 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ORG_EDITION]); 506 | return; 507 | } 508 | 509 | org = GeoIP_org_by_name(gi, hostname); 510 | GeoIP_delete(gi); 511 | if (org == NULL) { 512 | RETURN_FALSE; 513 | } 514 | #if PHP_MAJOR_VERSION >= 7 515 | RETVAL_STRING(org); 516 | #else 517 | RETVAL_STRING(org, 1); 518 | #endif 519 | free(org); 520 | } 521 | /* }}} */ 522 | 523 | /* {{{ proto string geoip_asnum_by_name( string hostname ) 524 | Returns the Domain Name found in the GeoIP Database */ 525 | PHP_FUNCTION(geoip_asnum_by_name) 526 | { 527 | GeoIP * gi; 528 | char * hostname = NULL; 529 | char * org; 530 | #if PHP_MAJOR_VERSION >= 7 531 | size_t arglen; 532 | #else 533 | int arglen; 534 | #endif 535 | 536 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 537 | return; 538 | } 539 | 540 | if (GeoIP_db_avail(GEOIP_ASNUM_EDITION)) { 541 | gi = GeoIP_open_type(GEOIP_ASNUM_EDITION, GEOIP_STANDARD); 542 | } else { 543 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ASNUM_EDITION]); 544 | return; 545 | } 546 | 547 | org = GeoIP_name_by_name(gi, hostname); 548 | GeoIP_delete(gi); 549 | if (org == NULL) { 550 | RETURN_FALSE; 551 | } 552 | #if PHP_MAJOR_VERSION >= 7 553 | RETVAL_STRING(org); 554 | #else 555 | RETVAL_STRING(org, 1); 556 | #endif 557 | free(org); 558 | } 559 | /* }}} */ 560 | 561 | /* {{{ proto string geoip_domain_by_name( string hostname ) 562 | Returns the Domain Name found in the GeoIP Database */ 563 | PHP_FUNCTION(geoip_domain_by_name) 564 | { 565 | GeoIP * gi; 566 | char * hostname = NULL; 567 | char * org; 568 | #if PHP_MAJOR_VERSION >= 7 569 | size_t arglen; 570 | #else 571 | int arglen; 572 | #endif 573 | 574 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 575 | return; 576 | } 577 | 578 | if (GeoIP_db_avail(GEOIP_DOMAIN_EDITION)) { 579 | gi = GeoIP_open_type(GEOIP_DOMAIN_EDITION, GEOIP_STANDARD); 580 | } else { 581 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_DOMAIN_EDITION]); 582 | return; 583 | } 584 | 585 | org = GeoIP_name_by_name(gi, hostname); 586 | GeoIP_delete(gi); 587 | if (org == NULL) { 588 | RETURN_FALSE; 589 | } 590 | #if PHP_MAJOR_VERSION >= 7 591 | RETVAL_STRING(org); 592 | #else 593 | RETVAL_STRING(org, 1); 594 | #endif 595 | free(org); 596 | } 597 | /* }}} */ 598 | 599 | #if LIBGEOIP_VERSION >= 1004008 600 | /* {{{ proto string geoip_netspeedcell_by_name( string hostname ) 601 | Returns the Net Speed found in the GeoIP Database */ 602 | PHP_FUNCTION(geoip_netspeedcell_by_name) 603 | { 604 | GeoIP * gi; 605 | char * hostname = NULL; 606 | char * org; 607 | #if PHP_MAJOR_VERSION >= 7 608 | size_t arglen; 609 | #else 610 | int arglen; 611 | #endif 612 | 613 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 614 | return; 615 | } 616 | 617 | if (GeoIP_db_avail(GEOIP_NETSPEED_EDITION_REV1)) { 618 | gi = GeoIP_open_type(GEOIP_NETSPEED_EDITION_REV1, GEOIP_STANDARD); 619 | } else { 620 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1]); 621 | return; 622 | } 623 | 624 | org = GeoIP_name_by_name(gi, hostname); 625 | GeoIP_delete(gi); 626 | if (org == NULL) { 627 | RETURN_FALSE; 628 | } 629 | #if PHP_MAJOR_VERSION >= 7 630 | RETVAL_STRING(org); 631 | #else 632 | RETVAL_STRING(org, 1); 633 | #endif 634 | free(org); 635 | } 636 | /* }}} */ 637 | #endif 638 | 639 | /* {{{ proto array geoip_record_by_name( string hostname ) 640 | Returns the detailed City information found in the GeoIP Database */ 641 | PHP_FUNCTION(geoip_record_by_name) 642 | { 643 | GeoIP * gi; 644 | char * hostname = NULL; 645 | #if PHP_MAJOR_VERSION >= 7 646 | size_t arglen; 647 | #else 648 | int arglen; 649 | #endif 650 | GeoIPRecord * gir; 651 | 652 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 653 | return; 654 | } 655 | 656 | if (GeoIP_db_avail(GEOIP_CITY_EDITION_REV1) || GeoIP_db_avail(GEOIP_CITY_EDITION_REV0)) { 657 | if (GeoIP_db_avail(GEOIP_CITY_EDITION_REV1)) { 658 | gi = GeoIP_open_type(GEOIP_CITY_EDITION_REV1, GEOIP_STANDARD); 659 | } else { 660 | gi = GeoIP_open_type(GEOIP_CITY_EDITION_REV0, GEOIP_STANDARD); 661 | } 662 | } else { 663 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_CITY_EDITION_REV0]); 664 | return; 665 | } 666 | gir = GeoIP_record_by_name(gi, hostname); 667 | 668 | GeoIP_delete(gi); 669 | 670 | if (NULL == gir) { 671 | RETURN_FALSE; 672 | } 673 | 674 | array_init(return_value); 675 | #if PHP_MAJOR_VERSION >= 7 676 | # if LIBGEOIP_VERSION >= 1004003 677 | add_assoc_string(return_value, "continent_code", (gir->continent_code == NULL) ? "" : gir->continent_code); 678 | # endif 679 | add_assoc_string(return_value, "country_code", (gir->country_code == NULL) ? "" : gir->country_code); 680 | add_assoc_string(return_value, "country_code3", (gir->country_code3 == NULL) ? "" : gir->country_code3); 681 | add_assoc_string(return_value, "country_name", (gir->country_name == NULL) ? "" : gir->country_name); 682 | add_assoc_string(return_value, "region", (gir->region == NULL) ? "" : gir->region); 683 | add_assoc_string(return_value, "city", (gir->city == NULL) ? "" : gir->city); 684 | add_assoc_string(return_value, "postal_code", (gir->postal_code == NULL) ? "" : gir->postal_code); 685 | #else 686 | # if LIBGEOIP_VERSION >= 1004003 687 | add_assoc_string(return_value, "continent_code", (gir->continent_code == NULL) ? "" : gir->continent_code, 1); 688 | # endif 689 | add_assoc_string(return_value, "country_code", (gir->country_code == NULL) ? "" : gir->country_code, 1); 690 | add_assoc_string(return_value, "country_code3", (gir->country_code3 == NULL) ? "" : gir->country_code3, 1); 691 | add_assoc_string(return_value, "country_name", (gir->country_name == NULL) ? "" : gir->country_name, 1); 692 | add_assoc_string(return_value, "region", (gir->region == NULL) ? "" : gir->region, 1); 693 | add_assoc_string(return_value, "city", (gir->city == NULL) ? "" : gir->city, 1); 694 | add_assoc_string(return_value, "postal_code", (gir->postal_code == NULL) ? "" : gir->postal_code, 1); 695 | #endif 696 | add_assoc_double(return_value, "latitude", gir->latitude); 697 | add_assoc_double(return_value, "longitude", gir->longitude); 698 | #if LIBGEOIP_VERSION >= 1004005 699 | add_assoc_long(return_value, "dma_code", gir->metro_code); 700 | #else 701 | add_assoc_long(return_value, "dma_code", gir->dma_code); 702 | #endif 703 | add_assoc_long(return_value, "area_code", gir->area_code); 704 | 705 | GeoIPRecord_delete(gir); 706 | } 707 | /* }}} */ 708 | 709 | /* {{{ proto integer geoip_id_by_name( string hostname ) 710 | Returns the Net Speed found in the GeoIP Database */ 711 | PHP_FUNCTION(geoip_id_by_name) 712 | { 713 | GeoIP * gi; 714 | char * hostname = NULL; 715 | #if PHP_MAJOR_VERSION >= 7 716 | size_t arglen; 717 | #else 718 | int arglen; 719 | #endif 720 | int netspeed; 721 | 722 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 723 | return; 724 | } 725 | 726 | if (GeoIP_db_avail(GEOIP_NETSPEED_EDITION)) { 727 | gi = GeoIP_open_type(GEOIP_NETSPEED_EDITION, GEOIP_STANDARD); 728 | } else { 729 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_NETSPEED_EDITION]); 730 | return; 731 | } 732 | 733 | netspeed = GeoIP_id_by_name(gi, hostname); 734 | GeoIP_delete(gi); 735 | RETURN_LONG(netspeed); 736 | } 737 | /* }}} */ 738 | 739 | /* {{{ proto array geoip_region_by_name( string hostname ) 740 | Returns the Country Code and region found in the GeoIP Database */ 741 | PHP_FUNCTION(geoip_region_by_name) 742 | { 743 | GeoIP * gi; 744 | char * hostname = NULL; 745 | #if PHP_MAJOR_VERSION >= 7 746 | size_t arglen; 747 | #else 748 | int arglen; 749 | #endif 750 | GeoIPRegion * region; 751 | 752 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 753 | return; 754 | } 755 | 756 | if (GeoIP_db_avail(GEOIP_REGION_EDITION_REV0) || GeoIP_db_avail(GEOIP_REGION_EDITION_REV1)) { 757 | if (GeoIP_db_avail(GEOIP_REGION_EDITION_REV1)) { 758 | gi = GeoIP_open_type(GEOIP_REGION_EDITION_REV1, GEOIP_STANDARD); 759 | } else { 760 | gi = GeoIP_open_type(GEOIP_REGION_EDITION_REV0, GEOIP_STANDARD); 761 | } 762 | } else { 763 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_REGION_EDITION_REV0]); 764 | return; 765 | } 766 | 767 | region = GeoIP_region_by_name(gi, hostname); 768 | GeoIP_delete(gi); 769 | 770 | if (NULL == region) { 771 | RETURN_FALSE; 772 | } 773 | 774 | array_init(return_value); 775 | #if PHP_MAJOR_VERSION >= 7 776 | add_assoc_string(return_value, "country_code", region->country_code); 777 | add_assoc_string(return_value, "region", region->region); 778 | #else 779 | add_assoc_string(return_value, "country_code", region->country_code, 1); 780 | add_assoc_string(return_value, "region", region->region, 1); 781 | #endif 782 | 783 | GeoIPRegion_delete(region); 784 | } 785 | /* }}} */ 786 | 787 | /* {{{ proto string geoip_isp_by_name( string hostname ) 788 | Returns the ISP Name found in the GeoIP Database */ 789 | PHP_FUNCTION(geoip_isp_by_name) 790 | { 791 | GeoIP * gi; 792 | char * hostname = NULL; 793 | char * isp; 794 | #if PHP_MAJOR_VERSION >= 7 795 | size_t arglen; 796 | #else 797 | int arglen; 798 | #endif 799 | 800 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 801 | return; 802 | } 803 | 804 | if (GeoIP_db_avail(GEOIP_ISP_EDITION)) { 805 | gi = GeoIP_open_type(GEOIP_ISP_EDITION, GEOIP_STANDARD); 806 | } else { 807 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ISP_EDITION]); 808 | return; 809 | } 810 | 811 | isp = GeoIP_name_by_name(gi, hostname); 812 | GeoIP_delete(gi); 813 | if (isp == NULL) { 814 | RETURN_FALSE; 815 | } 816 | #if PHP_MAJOR_VERSION >= 7 817 | RETVAL_STRING(isp); 818 | #else 819 | RETVAL_STRING(isp, 1); 820 | #endif 821 | free(isp); 822 | } 823 | 824 | #if LIBGEOIP_VERSION >= 1004001 825 | /* {{{ proto string geoip_region_name_by_code( string country_code, string region_code ) 826 | Returns the region name for some country code and region code combo */ 827 | PHP_FUNCTION(geoip_region_name_by_code) 828 | { 829 | char * country_code = NULL; 830 | char * region_code = NULL; 831 | const char * region_name; 832 | #if PHP_MAJOR_VERSION >= 7 833 | size_t countrylen, regionlen; 834 | #else 835 | int countrylen, regionlen; 836 | #endif 837 | 838 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &country_code, &countrylen, ®ion_code, ®ionlen) == FAILURE) { 839 | return; 840 | } 841 | 842 | if (!countrylen || !regionlen) { 843 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "You need to specify the country and region codes."); 844 | RETURN_FALSE; 845 | } 846 | 847 | region_name = GeoIP_region_name_by_code(country_code, region_code); 848 | if (region_name == NULL) { 849 | RETURN_FALSE; 850 | } 851 | #if PHP_MAJOR_VERSION >= 7 852 | RETURN_STRING((char*)region_name); 853 | #else 854 | RETURN_STRING((char*)region_name, 1); 855 | #endif 856 | } 857 | /* }}} */ 858 | #endif 859 | 860 | #if LIBGEOIP_VERSION >= 1004001 861 | /* {{{ proto string geoip_time_zone_by_country_and_region( string country, string region ) 862 | Returns the time zone for some country code and region code combo */ 863 | PHP_FUNCTION(geoip_time_zone_by_country_and_region) 864 | { 865 | char * country = NULL; 866 | char * region = NULL; 867 | const char * timezone; 868 | #if PHP_MAJOR_VERSION >= 7 869 | size_t countrylen, arg2len; 870 | #else 871 | int countrylen, arg2len; 872 | #endif 873 | 874 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &country, &countrylen, ®ion, &arg2len) == FAILURE) { 875 | return; 876 | } 877 | 878 | if (!countrylen) { 879 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "You need to specify at least the country code."); 880 | RETURN_FALSE; 881 | } 882 | 883 | timezone = GeoIP_time_zone_by_country_and_region(country, region); 884 | if (timezone == NULL) { 885 | RETURN_FALSE; 886 | } 887 | #if PHP_MAJOR_VERSION >= 7 888 | RETURN_STRING((char*)timezone); 889 | #else 890 | RETURN_STRING((char*)timezone, 1); 891 | #endif 892 | } 893 | /* }}} */ 894 | #endif 895 | 896 | #ifdef HAVE_CUSTOM_DIRECTORY 897 | /* {{{ proto void geoip_setup_custom_directory( string directory ) 898 | Sets the custom directory for GeoIP databases */ 899 | PHP_FUNCTION(geoip_setup_custom_directory) 900 | { 901 | char * dir = NULL; 902 | #if PHP_MAJOR_VERSION >= 7 903 | size_t dirlen; 904 | #else 905 | int dirlen; 906 | #endif 907 | 908 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &dir, &dirlen) == FAILURE) { 909 | return; 910 | } 911 | 912 | GEOIP_G(set_runtime_custom_directory) = 1; 913 | geoip_change_custom_directory(dir); 914 | } 915 | /* }}} */ 916 | #endif 917 | 918 | 919 | /* 920 | * Local variables: 921 | * tab-width: 4 922 | * c-basic-offset: 4 923 | * End: 924 | * vim600: noet sw=4 ts=4 fdm=marker 925 | * vim<600: noet sw=4 ts=4 926 | */ 927 | --------------------------------------------------------------------------------