From 3b149631f0eb732049e04fa0c89d09c7aa2376f9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 20:22:53 +0200 Subject: Adding upstream version 1.6.12. Signed-off-by: Daniel Baumann --- .clang-format | 5 + .gitignore | 49 + .travis.yml | 36 + AUTHORS | 1 + COPYING | 504 ++ ChangeLog | 973 ++++ GeoIP.spec.in | 76 + INSTALL | 370 ++ LICENSE | 28 + Makefile.am | 15 + Makefile.vc | 84 + NEWS.md | 50 + README.OSX | 53 + README.dev.md | 35 + README.md | 248 + apps/Makefile.am | 18 + apps/Makefile.vc | 25 + apps/geoiplookup.c | 375 ++ apps/geoiplookup6.c | 195 + appveyor.yml | 20 + bootstrap | 19 + configure.ac | 77 + data/GeoIP.dat | Bin 0 -> 3960 bytes dev-bin/clang-format-all.sh | 15 + dev-bin/release.sh | 61 + geoip.ico | Bin 0 -> 3062 bytes geoip.pc.in | 12 + get_ver.awk | 14 + libGeoIP/GeoIP.c | 2766 ++++++++++ libGeoIP/GeoIP.h | 444 ++ libGeoIP/GeoIPCity.c | 330 ++ libGeoIP/GeoIPCity.h | 72 + libGeoIP/GeoIP_deprecated.c | 248 + libGeoIP/GeoIP_internal.h | 23 + libGeoIP/Makefile.am | 19 + libGeoIP/Makefile.vc | 47 + libGeoIP/pread.c | 97 + libGeoIP/pread.h | 27 + libGeoIP/regionName.c | 10197 ++++++++++++++++++++++++++++++++++++ libGeoIP/timeZone.c | 1775 +++++++ m4/.placeholder | 0 man/Makefile.am | 26 + man/geoiplookup.1.in | 37 + man/geoiplookup6.1.in | 42 + regioncode/generate_regionName.pl | 176 + regioncode/region_codes.csv | 4108 +++++++++++++++ test/Makefile.am | 38 + test/Makefile.vc | 29 + test/benchmark.c | 183 + test/city_test.txt | 2 + test/country_test.txt | 61 + test/country_test2.txt | 61 + test/country_test_name.txt | 1 + test/fail_test.txt | 1 + test/proxy_test.txt | 17 + test/region_test.txt | 24 + test/test-geoip-asnum.c | 56 + test/test-geoip-city.c | 77 + test/test-geoip-domain.c | 67 + test/test-geoip-invalid-file.c | 29 + test/test-geoip-isp.c | 58 + test/test-geoip-netspeed.c | 59 + test/test-geoip-org.c | 67 + test/test-geoip-region.c | 118 + test/test-geoip.c | 146 + timezone/generate_timeZone.pl | 75 + timezone/timezone.txt | 717 +++ 67 files changed, 25678 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 GeoIP.spec.in create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 Makefile.am create mode 100644 Makefile.vc create mode 100644 NEWS.md create mode 100644 README.OSX create mode 100644 README.dev.md create mode 100644 README.md create mode 100644 apps/Makefile.am create mode 100644 apps/Makefile.vc create mode 100644 apps/geoiplookup.c create mode 100644 apps/geoiplookup6.c create mode 100644 appveyor.yml create mode 100755 bootstrap create mode 100644 configure.ac create mode 100644 data/GeoIP.dat create mode 100755 dev-bin/clang-format-all.sh create mode 100755 dev-bin/release.sh create mode 100644 geoip.ico create mode 100644 geoip.pc.in create mode 100644 get_ver.awk create mode 100644 libGeoIP/GeoIP.c create mode 100644 libGeoIP/GeoIP.h create mode 100644 libGeoIP/GeoIPCity.c create mode 100644 libGeoIP/GeoIPCity.h create mode 100644 libGeoIP/GeoIP_deprecated.c create mode 100644 libGeoIP/GeoIP_internal.h create mode 100644 libGeoIP/Makefile.am create mode 100644 libGeoIP/Makefile.vc create mode 100644 libGeoIP/pread.c create mode 100644 libGeoIP/pread.h create mode 100644 libGeoIP/regionName.c create mode 100644 libGeoIP/timeZone.c create mode 100644 m4/.placeholder create mode 100644 man/Makefile.am create mode 100644 man/geoiplookup.1.in create mode 100644 man/geoiplookup6.1.in create mode 100755 regioncode/generate_regionName.pl create mode 100644 regioncode/region_codes.csv create mode 100644 test/Makefile.am create mode 100644 test/Makefile.vc create mode 100644 test/benchmark.c create mode 100644 test/city_test.txt create mode 100644 test/country_test.txt create mode 100644 test/country_test2.txt create mode 100644 test/country_test_name.txt create mode 100644 test/fail_test.txt create mode 100644 test/proxy_test.txt create mode 100644 test/region_test.txt create mode 100644 test/test-geoip-asnum.c create mode 100644 test/test-geoip-city.c create mode 100644 test/test-geoip-domain.c create mode 100644 test/test-geoip-invalid-file.c create mode 100644 test/test-geoip-isp.c create mode 100644 test/test-geoip-netspeed.c create mode 100644 test/test-geoip-org.c create mode 100644 test/test-geoip-region.c create mode 100644 test/test-geoip.c create mode 100755 timezone/generate_timeZone.pl create mode 100644 timezone/timezone.txt diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..a72e2df --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +BinPackArguments: false +BinPackParameters: false +IndentCaseLabels: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..67550b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +*.la +*.lo +*.o +*.swp +*~ +.DS_Store +.deps +.libs +/m4 +GeoIP-*.tar.gz +GeoIP.spec +Makefile +Makefile.in +aclocal.m4 +apps/geoiplookup +apps/geoiplookup6 +apps/geoipupdate +autom4te.cache +compile +config.guess +config.log +config.status +config.sub +configure +depcomp +geoip.pc +install-sh +libtool +ltmain.sh +man/geoiplookup.1 +man/geoiplookup6.1 +man/geoipupdate.1 +missing +test-driver +test/benchmark +test/test-geoip +test/test-geoip-asnum +test/test-geoip-city +test/test-geoip-domain +test/test-geoip-invalid-file +test/test-geoip-invalid-file.log +test/test-geoip-invalid-file.trs +test/test-geoip-isp +test/test-geoip-netspeed +test/test-geoip-org +test/test-geoip-region +test/test-geoip.log +test/test-geoip.trs +test/test-suite.log diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..305b113 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,36 @@ +--- +sudo: false +addons: + coverity_scan: + project: + description: Build submitted via Travis CI + name: maxmind/geoip-api-c + notification_email: dev-ci@maxmind.com + build_command_prepend: ./configure; make clean + build_command: make -j 4 + branch_pattern: .*coverity.* +language: c +compiler: + - clang + - gcc +env: + global: + secure: |- + bMDurejTvGTXwVcD/fTij5xkhqOzwHSFQHxP1tLGBfemvRQ/FgX2E2M8rWaD + KbgKCgTSNB7fKtAvkFP+uteJ3/RY4HrQxlkY4/lG6tqlYJDCyLjxC0LLU5GE + hfW0iiu9ozNtJzQ2A2O3mgTUmN4+ay25VMTfoAYALvT67qpW+NM= +before_script: + - ./bootstrap + - CFLAGS="-Wall -Wextra -Werror -Wno-unused-parameter" ./configure + - make +script: + - make check +notifications: + email: + on_failure: always + on_success: change + recipients: + - dev-ci@maxmind.com + slack: + rooms: + secure: "WfyHKjt7GkS4U1tFmleDAwXEcs99LW33Gp0p8OwIPaV8ZI7WXZTw1ClJwr+Bpa9TDgfl26HX6IBcgX4ef/SAGvfLkYdEK8czYA2iT7VRudNQb/2oXdlwFz3hgY7yaROohkUgjo+IMq2efWFix7Z149ynex2k78Qp5g4GdZOLz48=\n" diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..539a706 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +T.J. Mather diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..602bfc9 --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..b6b2ca0 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,973 @@ +1.6.12 2018-01-17 + +* Populate metro and area code when performing lookups in IPv6 City databases. + Previously this was only done when using IPv4 City databases. + +1.6.11 2017-05-15 + +* Fix use of a NULL pointer when opening a corrupt database with + `GeoIP_open`. Reported by Stephan Zeisberg. GitHub #87. + +1.6.10 2017-03-29 + +* GeoIP_database_info now returns the full version string rather than + incorrectly truncating it. GitHub #79. +* This API is now distributed with a small test copy of GeoIP.dat rather than + a full copy. +* Fix issue where Visual Studio 2015 was optimizing out initialization code. + Reported and fixed by Scott Godin. GitHub #81. +* Fix test/benchmark on Windows. Gisle Vanem. GitHub #75. + +1.6.9 2016-01-11 + +* Fix a regression introduced in version 1.6.8, which caused + GeoIP_database_info to erroneously return NULL. + +1.6.8 2016-01-11 + +* Allow compilation on older systems by relaxing the autoconf and automake + minimum versions. Thank you, Jose Rubio! +* Avoid potential problems in multi-threaded environments by consistently using + pread() rather than read(). +* Fix various small issues reported by clang's static analyser. + +1.6.7 2015-10-30 + +* Fixed a MSVC parser stack overflow when parsing `regionName.c` and + `timeZone.c`. Fix by elliotlo. GitHub #64. +* Updated region codes and timezones. +* When using `GEOIP_MEMORY_CACHE` with an invalid database file, the search + tree traversal could attempt to read memory outside of the memory allocated + for the memory cache, resulting in a segmentation fault. A check was added + to ensure that the traversal code does not try to read beyond the end of the + file, whether in memory, memory mapped, or on disk. +* Previously the return values from file reads were ignored. We now check + these values to ensure that there were no errors. + + +1.6.6 2015-07-28 + +* Replaced usage of deprecated fileno, read, and lseek on Visual Studio 2005+ + with their ISO C++ conformant replacements. (Fix by ClaudiuHKS. GitHub #55.) +* A warning about using a double as a float was fixed. (Fix by ClaudiuHKS. + GitHub #56.) +* Fixed segfault when doing a lookup on an empty database. (Fix by NesoK. + GitHub #62.) +* Fixed a memcheck error from valgrind in the `_check_mtime` + function. (Reported by yurivct. GitHub #60.) +* Fixed `_check_mtime` to check the return value of `gettimeofday` rather than + just assuming it worked. + + +1.6.5 2015-02-25 + +* A segmentation fault in `geoiplookup` was fixed when the utility was passed + an invalid database. (Reported in Red Hat bug #1180874.) +* Additional validation was added for validation of the size used in the + creation of the index cache. (Based on discussion in Red Hat bug #832913.) +* Changed the code to only look up country codes by using functions which + ensure that we do not try to look past the end of an array. (Reported by + Ivan Sorokin. GitHub #53) + + +1.6.4 2015-01-12 + +* Update Fips codes (Boris Zentner) +* Several issues with the MinGW build were fixed. (Thomas Pöchtrager. Github + #46.) +* Use a constructor in pread.c to ensure the critical section is always + initialized. (Thomas Pöchtrager. Github #47.) +* Added missing include of `io.h` on Windows. (Thomas Pöchtrager. Github #49.) +* Fixed `configure` warning that `'missing' script is too old or missing`. + (Reported by Floren Munteanu. Github #33.) +* Previously `nmake /f Makefile.vc clean` would fail on Windows. This was + fixed. +* Obsolete win32 and NetWare make files were removed. +* Numerous documentation updates. (Reported by Thomas Pöchtrager. GitHub #48.) + + +1.6.3 2014-10-29 + +* Added a GEOIP_SILENCE flag. Include this flag when calling GeoIP_open to + prevent any messages from being written to stderr. (Philip Prindeville + and Boris Zentner) +* Mitigate a possible race condition when running under threads in the + GeoIP_cleanup function. (Anthon Pang) +* Added some recommendations to the docs on using this library in a + threaded application. (Boriz Zentner) +* Fixed some bugs discovered by coverity, including failure to check some + system call return values and making sure all strings are + null-terminated. (Boris Zentner) + + +1.6.2 2014-07-08 + +* Two files required for building on Win32 were missing from the 1.6.1 + release. These files were added. There are no changes affecting other + platforms. (Boris Zentner) + + +1.6.1 2014-06-26 + +* Improve Win32 support (Evan Hunt) +* Update FIPS codes (Boris Zentner) + + +1.6.0 2013-10-29 + +* Remove geoipupdate (Boris Zentner) + + +1.5.2 2013-10-29 + +* Update region and time zones (Boris Zentner) +* Fix benchmark script (Boris Zentner) +* Remove autogenerated files ltmain.sh, man/geoip*.1 (Boris Zentner) +* Explain how to download free geolite databases in the README.md and + GeoIP.conf.default (Boris Zentner) +* geoipupdate returns 1 on error 0 on success instead of the error code + (Boris Zentner) +* README is replaced by README.md (Gregory Oschwald) +* Add support for OS X Mavericks (Boris Zentner) + + +1.5.1 2013-05-14 + +* Update time_zone for Ontario, Canada (Boris Zentner) +* geoiplookup and geoiplookup6 exit code is 0 when user asked for help + (Jan Safranek) +* Added -h option to geoiplookup6 (Jan Safranek) +* Do not load the database file if nodes and file size do not make + sense. (Boris Zentner) +* Keep README and man pages in pure ascii. (Boris Zentner) +* It doesn't make sense to use GEOIP_INDEX_MODE with small databases + like GEOIP_COUNTRY_EDITION. Instead of undefined behaviour we handle + it silently as GEOIP_MEMORY_MODE (Boris Zentner) +* Update FIPS codes for Greece (Boris Zentner) + + +1.5.0 2013-02-21 + +* Rename custom_directory to GeoIP_custom_directory. (Boris Zentner) +* Make sure the database match the requested type. This is helpful for + Databases with the same default name and the general geoiplookup form + (geoiplookup without a specific database) (Boris Zentner) +* apps/geoiplookup6.c use the ipnum instead of the hostname for lookups. + (Boris Zentner) +* Use configure.ac instead of configure.in (Boris Zentner) +* Region lookup is a bit faster (Boris Zentner) +* Add pkg-config file (Bastien Nocera) +* Updates required to build a Windows DLL under MinGW (Gerald Combs) +* Make API thread safe (Boris Zentner) +* geoiplookup's default charset is UTF8 + -l change the charset back to iso8859-1 (Boris Zentner) +* geoipupdate skips \r otherwise it might be part of the last + product_id (Boris Zentner) +* Update time zones (Boris Zentner) +* Update Region codes (Boris Zentner) +* Remove the unused CITYCONFIDENCE* database types (Boris Zentner) +* bootstrap rebuilds ltmain.sh (Boris Zentner) +* Update README.OSX for Lion (Boris Zentner) +* Change Macedonia to Macedonia, The Former Yugoslav Republic of + (Boris Zentner) +* Add region_name to geoiplookup GEOIP_CITY_EDITION_REV1 (Boris Zentner) +* Add region_name to geoiplookup GEOIP_CITY_EDITION_REV0 (Chris Johnson) +* Add a --disable-data-files option. This allows you to build and install + the library without having a data/GeoIP.dat file. This is useful when + building the library from a checkout of the source tree, rather than a + tarball (Dave Rolsky) +* Add GEOIP_ACCURACYRADIUS_EDITION and GEOIP_ACCURACYRADIUS_EDITION_V6 + (Boris Zentner) +* Add more database types GEOIP_COUNTRYCONF_EDITION, + GEOIP_CITYCONF_EDITION, GEOIP_REGIONCONF_EDITION and + GEOIP_POSTALCONF_EDITION (Boris Zentner) +* Fix default filenames for GEOIP_NETSPEED_EDITION_REV1 and + GEOIP_NETSPEED_EDITION_REV1_V6 (Boris Zentner) + + +1.4.8 + +* Fix GEOIP_DOMAIN_EDITION_V6 (Boris Zentner) +* Add new Datatypes GEOIP_NETSPEED_EDITION_REV1_V6 and + GEOIP_NETSPEED_EDITION_REV1 (Boris Zentner) +* Fix possible directory traversal weakness in geoipupdate-pureperl.pl with + malicious update server (Boris Zentner) +* Fix GEOIP_ORG_EDITION_V6 and GEOIP_ISP_EDITION_V6 (Boris Zentner) + + +1.4.7 2011-12-19 + +* Upd timezone.c Add SX, BQ and CW remove AN and FX (Boris Zentner) +* Add support for the new types in geoiplookup6 (Boris Zentner) +* Add new database types GEOIP_CITY_EDITION_REV0_V6, + GEOIP_CITY_EDITION_REV1_V6, GEOIP_DOMAIN_EDITION_V6, + GEOIP_ORG_EDITION_V6 and GEOIP_ISP_EDITION_V6 (Boris Zentner) +* Remove AN and FX. Add SX, BQ and CW (Boris Zentner) +* Fix possible segfault in geoipupdate if the connection disappear + unexpected. (Boris Zentner) +* Add sanity check for geoipupdate-pureperl.pl (Boris Zentner) +* Add GEOIP_USERTYPE_EDITION and GEOIP_USERTYPE_EDITION_V6 + datatypes (Boris Zentner) +* Add new functions GeoIP_is_private_ipnum_v4 and GeoIP_is_private_v4 + (Boris Zentner) +* Add new functions GeoIP_teredo and GeoIP_enable_teredo. + teredo is enabled by default (Boris Zentner) +* Fix output of geoiplookup for unknown or private regions. + (Boris Zentner) +* Fix geoipupdate-pureperl.pl to accept more product codes. + (Boris Zentner) +* Fix minor output issue in geoipupdate -v (Boris Zentner) +* Add support for various databases. (Boris Zentner) +* Add experimental teredo support (Boris Zentner) +* Fix possible buffer overflow in conjunction with + http_proxies (Elso Andras) +* Remove memcpy/bcopy macro for BSD (Boris Zentner) +* Add GeoIP_lib_version and GeoIP_cleanup (Ladar Levison) +* Upd Makefile.vc (Thomas Winzig) +* Fix typo in DK,18,Midtjylland (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100810 (Boris Zentner) +* Fix continent codes (Boris Zentner) +* Fix 3letter country codes for ATA, BVT, IOT, CXR, CCK, ATF, HMD, + MYT, SGS and UMI (Boris Zentner) +* Fix typo/segfault in GeoIP_id_by_name_v6 (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100529 (Boris Zentner) +* Remove buffered IO functions, to fix issues with dup'ed file + descriptors (Boris Zentner) +* Fix very minor memleak in geoipupdate (Boris Zentner) +* Add GEOIP_CITYCONFIDENCEDIST_EDITION, GEOIP_LARGE_COUNTRY_EDITION + and GEOIP_LARGE_COUNTRY_EDITION_V6 database types (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100422 (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100420 (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes 20100221 (Boris Zentner) +* Add missing timezones (Boris Zentner) +* Add missing include for Windows 2000 (Jaap Keute) +* 'GeoIP Database up to date' and 'Updated database' prints to stdout + instead of stderr (Boris Zentner) +* Add missing GeoIPRecord_delete to geoiplookup.c (Piotr Kaczuba) +* Add some IPv4 helper functions + unsigned long GeoIP_addr_to_num(const char *addr); + char * GeoIP_num_to_addr(unsigned long ipnum); (Boris Zentner) +* Fix default name for the accuracy radius database to GeoIPDistance.dat (Boris Zentner) +* Add GEOIP_CITYCONFIDENCE_EDITION database type. (Boris Zentner) +* geoiplookup use GeoIPDistance.dat files if avail (Boris Zentner) +* Fix geoiplookup/geoiplookup6 output, when the databaseinfo string is + not avail. (Boris Zentner) +* Change continent code for RU from AS to EU (Boris Zentner) +* Add GEOIP_ACCURACYRADIUS_EDITION database type. (Boris Zentner) +* Add GEOIP_LOCATIONA_EDITION the database to map back from binary to + the csv database (Boris Zentner) +* Change Turkey's continent code from Asia to Europe (Boris Zentner) +* Rename _iso_8859_1__utf8 to _GeoIP_iso_8859_1__utf8 (Boris Zentner) +* GEOIP_ORG_EDITION, GEOIP_ISP_EDITION, GEOIP_DOMAIN_EDITION and + GEOIP_ASNUM_EDITION databases return UTF8 results, if gi->charset is set + to GEOIP_CHARSET_UTF8 (Boris Zentner) +* Avoid unnecesary call to gettimeofday when GEOIP_CHECK_CACHE is not set (John Douglass) +* Delayed loading of changed database files for 60 seconds. To avoid + reading halve written databases (Boris Zentner) +* Update README.OSX for Leopard and Snow Leopard (Boris Zentner) +* Add more IPv6 functions (Boris Zentner) + const char *GeoIP_country_code_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_code_by_name_v6 (GeoIP* gi, const char *host); + const char *GeoIP_country_code3_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_code3_by_name_v6 (GeoIP* gi, const char *host); + const char *GeoIP_country_name_by_addr_v6 (GeoIP* gi, const char *addr); + const char *GeoIP_country_name_by_name_v6 (GeoIP* gi, const char *host); +* Make sure that GeoIP_*_v6 functions refuse GEOIP_PROXY_EDITION and + GEOIP_NETSPEED_EDITION databases (Boris Zentner) +* Update libGeoIP/regionName.c with FIPS codes from 20090723 (Boris Zentner) +* Fix geoipupdate's -v option to not change the license filename (Thom May) +* Fix geoipupdate's exit code (Thom May) +* Add support for ASNUM_EDITION (Boris Zentner) +* Fix -i output for larger values, sign issue (Boris Zentner) +* Add -i flag for more information on netmask, range_by_ip and the current network range (Boris Zentner) +* Add support for DOMAIN_EDITION database type (Boris Zentner) +* Fix apps/geoipupdate-pureperl.pl output layer on W32 (Boris Zentner) + + +1.4.6 2009-02-25 + +* Fix geoipupdate's my_printf function (Boris Zentner) +* Fix typo in apps/geoipupdate-pureperl.pl replace PerlIO::Gzip with PerlIO::gzip (Boris Zentner) +* Update region codes in libGeoIP/regionName.c (Boris Zentner) +* Fix regioncode/generate_regionName.pl to handle regioncodes with ',' correct (Boris Zentner) +* Update fips codes 20090201 (Boris Zentner) +* Fix unicode builds on WIN32 and eliminate some warnings (Stu Redman) +* Fix sign error in _iso_8859_1__utf8 for PPC64 (Boris Zentner) +* Change WIN32 to _WIN32, since _WIN32 is defined by default. _WIN32 is also defined for WIN64 machines (Boris Zentner) +! Remove the WSAStartup call from GeoIP_open. All Applications need to call WSAStartup and WSACleanup to initialize the Windows Socket library. Before they use any of the GeoIP_*_by_name functions. (Boris Zentner) +* geoiplookup and test-geoip-* output N/A instead of (null) (Boris Zentner) +* Silence various warnings. (Boris Zentner) +* Add more timezone region's for Australia +* Fix possible segfault in apps/geoiplookup with null pointers in non gnu printf implementations for example solaris (Boris Zentner) +* Add README.OSX to build fat binaries easy (Boris Zentner) +* Silence vasprintf warning via AC_GNU_SOURCE (Boris Zentner) +* Add several Makefiles to build a static GeoIP.lib for w32 (Stanislaw Pusep and Randy Kobes) +* Silence signedness warnings (Peter Volkov) +* Remove --with-city configure option. (Boris Zentner) +* Remove configure's --with-dbdir option. Use the similar --datadir instead (Peter Volkov) +* Various autotools improvements and cleanups. Including parallel + build fix (Peter Volkov) +* Fix libGeoIP/timeZone.c (Martin Haller) +* Fix timezone/generate_timeZone.pl (Boris Zenter) +* Sync FIPS codes again Jan 14th, 2009 (Boris Zentner) +* Fix CA,NL regioncode. (Boris Zentner) +* Change logic in generate_regionName.pl and GeoIP_region_name_by_code to handle any mixture of two letter fips codes matching [A-Z0-9]{2} the change allow GZ and WE region codes (Boris Zentner) +* Sync regionName.c with http://www.maxmind.com/app/fips10_4 from Dec 17th, 2008 (Boris Zentner) +* Fix _GeoIP_lookupaddress for 64bit big endian systems like ppc64 (Peter Volkov) +* Add proper WIN32/64 support (Gerald Combs) +* Escape - in all manpages (Patrick Matthäi) +* Add manpage for geoiplookup6 (Boris Zentner) +* Fix -d command line option (Klaus Heinz) +* GeoIPUpdate.c use vasprintf if avail, otherwise try vsnprintf and sprintf (Boris Zentner) +* avoid pre/postincrement and assignment on the same variable (Boris Zentner) + + +1.4.5 2008-09-16 + +* metro_code replace the depreciated dma_code field (Boris Zentner) +* Add new function GeoIP_range_by_ip_delete + r = GeoIP_range_by_ip(gi, '24.24.24.24'); + ... + GeoIP_range_by_ip_delete(r); (Boris Zentner) +* Fix small memoryleak and wrap around in GeoIP_range_by_ip (Boris Zentner) +* CHECK_CACHE stat the database file not faster than once a second anymore (Patrick McManus) +* Fixed a typo in the geoipupdate(1) manpage and also an non-existent path on Debian (Patrick Matthäi) +* Fixes two little format errors (hyphen used as minus sign) in both manpages (Patrick Matthäi) +* Sync regionName.c with a recent fips code list (Boris Zentner) +* Fix segfault when open failed for a custom file (-f) (Boris Zentner) +* Fix sync geoiplookup's man page with the code (Klaus Heinz) +* remove unused code from GeoIP_country_name_by_addr and GeoIP_country_code3_by_addr (Boris Zentner) +* Fix geoiplookup and geoiplookup6 to distinguish between failed namelookups and unknown ips (Boris Zentner) +* add geoiplookup6 that can handle the new database type GEOIP_COUNTRY_EDITION_V6 (Boris Zentner) +* add new functions to handle ipv6: + GEOIP_API const char *GeoIP_country_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API const char *GeoIP_country_code_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API const char *GeoIP_country_code3_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_org_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_org_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API char *GeoIP_org_by_name_v6 (GeoIP* gi, const char *name); + GEOIP_API int GeoIP_id_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API int GeoIP_id_by_name_v6 (GeoIP* gi, const char *host); + GEOIP_API int GeoIP_id_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API GeoIPRegion * GeoIP_region_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API GeoIPRegion * GeoIP_region_by_name_v6 (GeoIP* gi, const char *host); + GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum_v6 (GeoIP *gi, geoipv6_t ipnum); + GEOIP_API void GeoIP_assign_region_by_inetaddr_v6(GeoIP* gi, geoipv6_t inetaddr, GeoIPRegion *gir); + GEOIP_API char *GeoIP_name_by_ipnum_v6 (GeoIP* gi, geoipv6_t ipnum); + GEOIP_API char *GeoIP_name_by_addr_v6 (GeoIP* gi, const char *addr); + GEOIP_API char *GeoIP_name_by_name_v6 (GeoIP* gi, const char *name); + + # allowed input for addr + 2001:4860:0:1001::68 + ::85.8.93.71 + ::1 + ::5508::5d47 + ::ffff:5508::5d47 + + # allowed input for host + ipv6.google.com + 2001:4860:0:1001::68 + ::85.8.93.71 + ::1 + ::5508::5d47 + ::ffff:5508::5d47 + (Boris Zentner) +* Fix geoiplookup usage string (add -d -f) (Boris Zentner) +* Added GeoIP_range_by_ip, returns the start and end IP address for the range containing the IP address. + This range has a constant value in the GeoIP database. +* Add geoipupdate-pureperl.pl a alternative geoipupdate version. with Proxy Server support via via the "http_proxy" environment variable. Easy to customize. (Boris Zentner) +* Add WIN64 since WIN32 is not defined on WIN64 Systems (Boris Zentner) +* Fix WIN32 compilation by encircle all MMAP functions with #ifdef WIN32 #endif pairs. MMAP is not avail in W32 (Boris Zentner) +* Update timezone/generate_timeZone.pl (Boris Zentner) +* Update libGeoIP/timeZone.c (Boris Zentner) +* Added GeoIP_printf and GeoIP_fprintf as a experimental feature to + libGeoIPUpdate. (Boris Zentner, Andrew Droffner) +* Added cast in _iso_8859_1__utf8 function to fix NetWare/Win32 compilation issue (Guenter Knauf) +* Add HTTP Proxy Server support for geoipupdate via the "http_proxy" + environment variable. + ie: export http_proxy="http://proxy-hostname:port" + (Andrew Droffner, Derek Nicol) +* Notice, that __YOU__ need to free the results of + + GeoIP_database_info + GeoIP_name_by_ipnum + GeoIP_name_by_addr + GeoIP_name_by_name + GeoIP_org_by_ipnum + GeoIP_org_by_addr + GeoIP_org_by_name + + not libgeoip + (Boris Zentner, Andrew Cheung) +* Fixed segfault with geoiplookup, if used with a custom_file database, that + could not be opened. (Boris Zentner) +* Add Usage info for options -f and -d in geoipupdate (Boris Zentner) +* Fixed segfault with geoipupdate when called with a illformed license file + (Boris Zentner) +* Update add more timezones to GeoIP_time_zone_by_country_and_region + (Boris Zentner) +* Add array access functions so programs can avoid accessing the + arrays directly which whould break binary compatability (Ludwig Nussel at SUSE) +* Updated README to state API is only thread-safe if GEOIP_CHECK_CACHE is not used + + +1.4.4 2008-1-21 + +* Updated original geoipupdate to return "Invalid product ID or subscription expired" +* Added BL/Saint Barthelemy, MF/Saint Martin (ISO-3166-1 additions) +* Check for illegal IP strings, return 0 if IP is not well formed IPv4 e.g. 1.2.3.4.5 and 1.2.3 +* Clarified that while core GeoIP library is LGPL, libGeoIPUpdate depends on md5.c and types.h which are GPL. +* speedup the conversion from ipstring to ipnum in _GeoIP_addr_to_num. Doubles the speed of GEOIP_MEMORY_CACHE and GEOIP_MMAP_CACHE +* Added new mmap shared memory caching option, GEOIP_MMAP_CACHE (Peter Shipley, LookSmart) + - mmaps: our maps are shared, but we need only private readonly pages + + +1.4.3 2007-8-30 + +! CHANGE with geoiplookup facility: -v flag now returns database info for all databases, not just GeoIP Country +* Added ability to get netmask of network block from last lookup using GeoIP_last_netmask +* Fixed GeoIP_database_info bug with GeoLite City +* Replaced 4 with sizeof(char*) to fix issues with geoipupdate on 64 Bit machines +* Added GeoIP_set_charset function - enables UTF8 output of city name if GEOIP_CHARSET_UTF8 flag is passed +to GeoIP_set_charset +* Fixed segfault issue if calling GeoIP_db_avail before opening a database +* Added continent_code to GeoIP City's record struct (Frank Mather) + + +1.4.2 2007-2-8 + +* Added -d flag to enable custom path for geoipupdate utility program (Frank Mather) +* Replaced _WIN32 with WIN32 since WIN32 is already set by compilers +* Moved var definitions to top of code, defined size_t (Guenter Knauf) +* Added Makefile.win32, Makefile.netware, get_ver.awk, geoip.ico to EXTRA_DIST in Makefile.am (Guenter Knauf) + + +1.4.1 2007-1-2 + +* Replaced CS/Serbia and Montenegro with RS/Serbia, removed ZR/Zaire, added ME/Montenegro +* Added AX/Aland Islands, GG/Guernsey, IM/Isle of Man, JE/Jersey (ISO-3166-1 changes) +* Added GeoIP_time_zone_by_country_and_region, to lookup zoneinfo timezone by country and region (Frank Mather) +* Added GeoIP_region_name_by_code, to lookup region name from region code (Frank Mather) +* added -f and -d flags to enable custom paths for geoiplookup utility program (Frank Mather) +* Added benchmarks for GeoIP Region and City in test/benchmark.c (Frank Mather) +* Fixed build issue when using --as-needed flag (Diego 'Flameeyes' Pettenò) +* Add sanity checking for filename returned by MaxMind.com server for geoipupdate filename + (Dean Gaudet, arctic.org) +* Fixed memory leaks under error conditions, buffer overflow using sprintf, + and issue where a corrupted cache file could core dump the file + (Nick Galbreath, Right Media Inc) + + +1.4.0 2006-8-7 + +* Changed license from GPL to LGPL, so that PHP Extension can be included in PECL (Olivier Hill) +* Rewrote GEOIP_CHECK_CACHE code, fixed numerous bugs + - CheckCache now works if GeoIP file is overwriten by mv command + - Fixed bug where CheckCache kept reloading in GEOIP_STANDARD_MODE + - Fixed segfault issue in GEOIP_MEMORY_CACHE mode + - Fixed garbage data appearing in GEOIP_INDEX_CACHE mode + - Fixed realloc in case realloc returns new memory block (Andre Morozov of Stone Steps) +* Updated geoipupdate to print status messages for each database instead of just last database +* Check that gi is not null before running code in GeoIP_delete +* Fixed alpha-3 codes ordering, replaced TLS,TKM,TUN,TON with TKM,TUN,TON,TLS +* TP/East Timor changed to TL/Timor-Leste, reflecting changes in ISO-3166 + +* Added Netware and Windows makefiles (Guenter Knauf) +* Fixed NetWare compiler issue with char block[block_size] declaration (Guenter Knauf) +* Updated geoipupdate example to run weekly + + +1.3.17 2006-5-14 + +* Fixed headers for Windows/Netware compilation (Guenter Knauf) +* Fixed Received Error -21 (Sanity check database_info string failed) + when running geoipupdate with GeoIP Country when UserId and + productIds were not specified. Bug was introduced in 1.3.15. + + +1.3.16 2006-4-17 + +* Fixed compliation error in GeoIPUpdate.c + + +1.3.15 2006-4-14 + +* Updated README documentation +* Updated geoipupdate so that it writes file as it is uncompressed instead +of storing entire GeoIP.dat file in memory (Frank Mather) +* Updated geoiplookup so that it returns GeoIP Domain Name if available + (Frank Mather) +* Updated geoipupdate so that it reports whether databases are updated +in non-verbose mode (Frank Mather) + + +1.3.14 2005-9-7 + +* Check if byte, ushort, ulong, u16, u32 are defined in configure + script. Fixes compilation issue on FreeBSD systems. +* Check for Big Endian byte order (needed for MD5 code in geoipupdate + to work properly on Mac OS X and other Big Endian processors) +* Fixed GEOIP_CHECK_CACHE mode when used with GEOIP_STANDARD to + only refresh upon file change +* Fixed memory leak when refreshing file in GEOIP_CHECK_CACHE mode +* Updated ltmain.sh to support Debian GNU/k*BSD bug #315425 (Marek Habersack) +* Added lookup functions using IP numeric representation as input (Frank Mather) +* Removed geoipexport +* Replaced Yugoslavia with Serbia and Montenegro +* Updated geoiplookup to only perform country lookup once instead of twice by + using GeoIP_id_by_name + + +1.3.13 2005-8-1 + +* Fixed autoconf weirdness that resulted in libraries being + installed without .so suffix + + +1.3.12 2005-7-19 + +* Removed -lGeoIP from libGeoIPUpdate_la_LIBADD - fixes compilation error + if GeoIP isn't already installed (Thomas Steudten) + + +1.3.11 2005-7-7 + +* Fixed gcc warnings and bug. Use int + instead of char for checking the return value of getopt in geoipupdate.c. + Moved the internal functions to GeoIP_internal.h to get rid + of those 'implicit declaration' warnings. (Ludwig Nussel/SUSE) +* Cleaned up name space by prefixing internal functions with + _GeoIP* (Ludwig Nussel/SUSE) +* Memory Leak fix for GeoIP City if fread error +* Added more verbose error messages for geoipupdate (Frank Mather) +* Added check for zlib.h to configure.in + + +1.3.10 2005-4-17 + +* Added types.h to Makefile.am - fixes compilation error + + +1.3.9 2005-4-14 + +* fixed bug with GEOIP_INDEX_CACHE (Frank Mather) +* fixed segfault issue if GeoIP.dat not found (Frank Mather) +* Updated MD5 checksum code to use GnuPG code which works + on 64bit machines (Frank Mather) +* Fixed memory leak in test-geoip-isp.c and test-geoip-org.c +* Added support for GeoIP Domain Names in geoipupdate + + +1.3.8 2004-11-7 + +* Updated geoipupdate to report invalid userID and productID errors +* Check if gethostbyname_r is version that returns int or is other version + - should fix compile errors on Solaris and FreeBSD +* Updated URL to get license key, userId, and product Ids in conf/GeoIP.conf.default +* Updated test case, removed www.asahi.com +* Added support for GEOIP_INDEX_CACHE - which just caches + the most frequently access index portion of the database, resulting + in faster lookups than GEOIP_STANDARD, but less memory usage than + GEOIP_MEMORY_CACHE (Frank Mather) + + +1.3.7 2004-10-5 + +* Updated test case, removed www.bundesregierung.de added www.asahi.com + + +1.3.6 2004-8-8 + +* Check for gethostbyname_r support in configure (Mac OS X doesn't support gethostbyname_r) +* Made GeoIP City code thread safe +* Fixed bug with geoipupdate reading in product ids +* Added support for GeoIP Netspeed geoipupdate +* Fix memleak in lookupaddress (Ludwig Nussel/SUSE) +* Add prototype for _full_path_to to make 64bit clean + (Ludwig Nussel/SUSE) +* Add return values to test programs (Ludwig Nussel/SUSE) + + +1.3.5 2004-7-5 + +* Added more documentation to README file +* Made GEOIP_CHECK_CACHE work with GEOIP_STANDARD mode - reloads filehandle + in case file changes. +* Added GeoIP_country_code_by_ipnum and GeoIP_id_by_ipnum to use + existing ulong IP Address in numeric form instead of having to + convert it to string (Boris Hajduk) +* Made code thread safe by replacing gethostbyname with gethostbyname_r + + +1.3.4 2004-6-4 + +* Fixed bug where *.gz file(s) didn't get removed after geoipupdate + + +1.3.3 2004-6-2 + +* Added support for NetSpeed lookup to geoiplookup +* inet_addr patch for 64 bit systems (Thomas Steudten) +* Added Support for automated downloads of GeoIP Region, City, ISP and + Organization databases (Frank Mather) +* INADDR_NONE Patch for Solaris 9 (John Young) + + +1.3.2 2004-4-20 + +* Added support for Maxmind NetSpeed + +* MinGW patch from Stanislaw Pusep + + I was re-compiling Geolizer (http://sysd.org/log.php#glzr) on Win32 so I + firstly needed to put up-to-date Win32 compatibility of libGeoIP itself. + Fortunately MinGW plataform evolved a lot since last time I used it to + compile libGeoIP. I'm sending you the patch with changes required for + libGeoIP to work on both Win32 and UN*X. UN*X behavior is unaffected. Now, + detailed explanation of what I did at all: + + 1) Made correct header imports for both Win32 and UN*X. UN*X imports netdb.h + & netinet/in.h and Win32 imports windows.h & winsock.h + 2) Win32 gethostbyname() is only able to resolve hostnames, it can't convert + "127.0.0.1" string to 32-bit IP address. Thus I added lookupaddress() + function that safely resolves any string to IP address and replaced all + gethostbyname() calls by it. + 3) Database files were referenced by pre-compiled static strings. I + malloc()ed buffers for file names so they can be changed "on fly". Thus, + on Win32 version GeoIP.dat & other files are being seeked in the same + directory as executable file or library. + 4) Added README.MinGW file with brief explanation on how to get GeoIP + working under MinGW system. + + +1.3.1 2003-11-11 + +* Check for stdint.h in autoconf (Sean Chittenden) +* prevent the geoipupdate man page from trying to install itself directly in + the system directory (Gyepi Sam) + + +1.3.0 2003-09-29 + +* Fixed includes to compile on Windows (Fabrice Colin) +* Removed the _addr_to_num() calls from GeoIP_*_by_name() +* _seek_record() optimizations (Maurice Cinquini) + 1) Use a single buf ptr inside the loops. + Set to the stack buffer or the cached memory the start of the function. + 2) Unroll the i=0,1 loop to allow constant folding. + 3) Unroll the j loop for the common case of j = STANDARD_RECORD_LENGTH + (I've already done the above changes see attached function.) + With gcc -O2 calculating x[0] and x[1] for STANDARD_RECORD_LENGTH now + only takes 15 (was > 100) i80x86 instructions with 6 byte accesses of RAM. + 4) only calculate x[0], x[1] when needed, may be a bigger win + than the above since all the other optimizations above only reduced + CPU instructions operating on CPU cached RAM. +! IMPORTANT API Change: Changed GeoIPRegion to have region in structure. Saves space and a malloc. + Since GeoIPRegion.region is no longer a pointer but an in-structure + array so test the first byte of region == 0 rather testing if the region + pointer is NULL. (Maurice Cinquini) +* Added GeoIP_assign_region_by_inetaddr which doesn't do any mallocs and made all other region APIs go thru it (Maurice Cinquini) +* Replaced _h_addr_to_num() with ntohl() and removed _h_addr_to_num() (Maurice Cinquini) +* Fixed bug when IP address not found in region rev1 database (Jason Linhart) +* Added added extern "C" to GeoIPCity.h fixes problems when included in C++ library + + +1.2.2 2003-08-10 + +* Added support for GeoIP ISP Edition identifier +* Fixed bug in GeoIP_database_info (Jason Linhart) +* Added support for GeoIP AS Number Edition +! renamed GeoIP_org_by_* functions to GeoIP_name_by_* to reduce confusion + since these functions are used by GeoIP ISP and GeoIP ASNum as well + as GeoIP Organization +* Added support for GeoIP Proxy Edition +! renamed GeoIP_country_id_by_* functions to GeoIP_id_by_* + + +1.2.1 2003-07-12 + +* Added GeoIP_record_id_by_addr and GeoIP_next_record functions +* Added support for new GeoIP Region format, including Canadian Provinces + + +1.2.0 2003-04-26 + +* Added support for GeoIP City format revision 1, including dma code and area code +* geoiplookup returns results from GeoIP Region, City, ISP and Organization databases +* Standardized location for GeoIP Region, City, ISP and Organization databases +* Added GeoIP_open_type to open database from default location for other dbs besides country +* Added check to make sure that the appropriate database is loaded for each lookup method +* Updated update code to check for first 12 characters of license key +* Added GeoIP_country_continent array to lookup continent by country ID + + +1.1.9 2003-03-10 + +* merged windows patch into main code base (Kenneth R. Robinette) +* Changed const int to #define for windows compatibility + + +1.1.8 2003-03-04 + +* Fixed bug with city database introduced in 1.1.6 + + +1.1.7 2003-03-04 + +* Fixed bug introduced in 1.1.6 when run in GEOIP_STANDARD mode +* Added test to test GEOIP_STANDARD + + +1.1.6 2003-03-03 + +* Added spec for building RPMs (Ryan Weaver) +* Added support for 4byte records for Organization database +* Changed Taiwan, Province of China to Taiwan + + +1.1.5 2003-02-10 + +* Added support for GeoIP Organization database + + +1.1.4 2002-12-30 + +* Cast number to int in _num_to_addr in geoipexport (Ralf S. Engelschall) +* Removed printf debug statements from geoipexport +* correct library build ordering (Ralf S. Engelschall) +* ulong -> unsigned long (Sean Chittenden) + + +1.1.3 2002-12-24 + +* Added GeoIPUpdate.h to EXTRA_DISTS +* Compile fixes for Solaris, FreeBSD (Michael McClennen, Corris Randall) +* Handle NULL in printf in test-geoip-region + + +1.1.2 2002-12-16 + +* Added support for postal codes +* Added geoipexport, program to export bit binary file to + binary tree format and csv format +* Split update code into separate library, GeoIPUpdate.la +* Allow passing NULL callback to GeoIP_update_database function + (Sean Chittenden) +* Added geoipexport program, exports to CSV file +* Added GeoIP_database_edition method +* Changed DATADIR to GEOIPDATADIR + + +1.1.1 2002-11-07 + +* Fixed segfault issue with GeoIPRegion_delete +* Handle test failures where lookup returns NULL more gracefully + + +1.1.0 2002-11-06 + +* Perform sanity checking before installing datebase using geoipupdate +* Removed file locking, since we install file by renaming instead of writing to it. +* Fixed geoipupdate to check for NULL return value +* Added constants for different editions +* Added O1 code for "Other country", used in per-country city editions +* fixed multi-line string literals warning in test-geoip.c +* Use enum constants for GeoIP_update_database values +* Added GEOIP_CHECK_CACHE option (not working yet) + + +1.0.10 2002-10-28 + +* IMPORTANT API Change - Return NULL instead of '--' and 'N/A' + Be sure to check the return value for NULL to avoid segmentation faults!!!! +* Added callback to print messages from GeoIP_update_database +* Moved GeoIPConfFile to geoipupdate.c +* Changed databaseSegments to unsigned int (Chris Gibbs) +* Fixed compiler warnings (Chris Gibbs) +* API Change - GeoIPRegion region member set to NULL when no region available +* Change short int to int (Chris Gibbs) +* Added write/read file locking for GeoIPUpdate.c/GeoIP.c + + +1.0.9 2002-10-16 + +* removed -ansi from Makefile.am to avoid compile error on Solaris 8 +* Compile fix for FreeBSD Stable (Kimura Fuyuki) + + +1.0.8 2002-10-05 + +* Included header required for *BSD (Akinori Musha) + + +1.0.7 2002-10-05 + +* Fixed compilation error with GeoIPUpdate.c + + +1.0.6 2002-10-04 + +* Moved update code into separate file +* Added md5 checksums to update code +* Fixed memory leak when running geoiplookup -v +* Moved const RECORD_LENGTH to #define RECORD_LENGTH for Windows compatibility + (Randy Kobes) +* Cleaned up GeoIP_new code + + +1.0.5 2002-09-23 + +* Supports GeoIP Regional Edition +* Macau is now "Macao" per ISO 3166-1 change +* Romania "ROM" is now "ROU" per ISO 3166-1 change +* Added #define for memcpy -> BSD's bcopy (Chris Gibbs) +* Removed "private" functions from GeoIP.h + + +1.0.4 2002-08-27 + +* rewrote _seek_country to use loop instead of recursion for faster performance +* Removed "orphan" nodes from demo database resulting in smaller size (Jason Linhart) +* Moved changes for building windows DLL into separate patch +* Fixed segfaults when passed malformed IP addresses + + +1.0.3 2002-08-26 + +* Added more changes for windows compatibility + (Stanislaw Pusep) +* Added benchmark program + + +1.0.2 2002-08-21 + +* Open database using "rb" for windows compatibility + (Stanislaw Pusep) +* Removed superfluous inet_ntop command (Stanislaw Pusep) + + +1.0.1 2002-08-20 + +* Fixed bug with resolving hostnames +* More fixes for compiler warnings (Chris Gibbs) +* Changed int to unsigned int in _is_ipaddr (Chris Gibbs) + + +1.0.0 2002-08-12 + +* Changed license to GPL +* Don't perform Reverse DNS lookups on IP addresses +* Only include getopt.h on Linux (OpenPKG patch) +* Avoid the_license_key_str warning (OpenPKG patch) +* Added license for March 2002 database + + +0.3.0 2002-08-04 + +* Added support for 'A2', Satellite Providers + + +0.2.8 2002-07-30 + +* Handle malformed input gracefully +* Added section to README on Solaris workarounds +* Added geoipupdate man page + + +0.2.7 2002-07-27 + +* Added section to README on automatic updates +* link to socket library on solaris + + +0.2.6 2002-07-25 + +* optimized GeoIP_open (Chris Gibbs) +* check for partial file read in GeoIP_open (Chris Gibbs) +* optimized _addr_to_num() (Chris Gibbs) +* changed write and read to send and recv for sockets +* Only install GeoIP.conf and GeoIP.dat if not already installed + + +0.2.5 2002-07-22 + +* Added verbose option to GeoIP_update_database + + +0.2.4 2002-07-22 + +* Fix for GeoIP_update_database + + +0.2.3 2002-07-22 + +* Fixes for FreeBSD +* All calls to malloc are checked for NULL pointer (Chris Gibbs) +* Fixed spelling of "Kazakhstan" (Chris Gibbs) +* Initialize cache_buf to NULL (Chris Gibbs) +* More memory leak fixes (Chris Gibbs) + + +0.2.2 2002-07-18 + +* Added update database function +* Fixed memory leak in GeoIP_new (Chris Gibbs) + + +0.2.1 2002-07-03 + +* Added support for anonymous proxies + + +0.2.0 2002-06-23 + +* Added new memory caching option for improved performance + + +0.1.7 2002-05-29 + +* Only add -lnsl for systems that support libnsl +* Added decl for 3 letter country code array to GeoIP.h + + +0.1.6 2002-05-25 + +* Added 3 letter country code + + +0.1.5 2002-05-23 + +* Added -lnsl fixed compile errors + + +0.1.4 2002-05-11 + +* Fixed bugs in demo March 2002 database + + +0.1.3 2002-04-21 + +* Fixed bug related to signed int (Brian Grossman) +* Better error handling when hostname not found +* Fixed bug when netmask=32 for netblock + + +0.1.2 2002-04-20 + +* Added two new functions, GeoIP_country_id_by_addr + and GeoIP_country_id_by_name. +* Made GeoIP_country_code and GeoIP_country_name + viewable outside of library, to be with with + GeoIP_country_id_by_* functions. + + +0.1.1 2002-04-07 + +* GeoIP.h is now installed to includedir +* constructor and destructor are now provided by + GeoIP_new, GeoIP_open, and GeoIP_delete + + +0.1.0 2002-04-07 + +* Initial release diff --git a/GeoIP.spec.in b/GeoIP.spec.in new file mode 100644 index 0000000..9405b6e --- /dev/null +++ b/GeoIP.spec.in @@ -0,0 +1,76 @@ +Name: @PACKAGE@ +Version: @VERSION@ +Summary: GeoIP is a C library finds the location of an IP address. +Release: 1 +Group: System Environment/Libraries +URL: http://dev.maxmind.com/geoip/downloadable +Vendor: MaxMind, Inc. +Source0: http://www.maxmind.com/download/geoip/api/c/GeoIP-latest.tar.gz +License: LGPLv2.1+ +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +GeoIP is a C library that enables the user to find geographical and +network information of an IP address. +Included is a free GeoLite Country database +that is updated at the beginning of every month. +To download the latest free GeoLite databases, go to: +http://dev.maxmind.com/geoip/geolite + +%package devel +Summary: GeoIP headers, libraries +Group: Development/Libraries +Requires: %name = %{version} + +%description devel +This package contain the devel files for GeoIP. + +%prep +%setup -q + +%build +%configure +make +make check + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +%makeinstall +# Fixup permissions on shared libraries so that findreqs will work right. +chmod 755 $RPM_BUILD_ROOT/%{_libdir}/* + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%doc AUTHORS COPYING ChangeLog README.md TODO +%attr(0755,root,root) %{_libdir}/*.so.*.* +%{_bindir}/* +%{_sysconfdir}/* +%dir %{_datadir}/GeoIP +%{_datadir}/GeoIP/* +%{_libdir}/*.so +%{_mandir}/*/* + +%files devel +%{_includedir}/* +%{_libdir}/*.a +%{_libdir}/*.la + +%changelog +* Fri Apr 14 2006 Thomas Mather +- Updated description to reference free GeoLite City database + +* Thu Jul 7 2005 Thomas Mather +- Updated description to reflect monthly updates for free country database. + +* Mon Sep 8 2003 Dr. Peter Bieringer +- Fix for RHL 9, created a new devel package definition. + +* Thu Feb 27 2003 Ryan Weaver +- Initial RPM Build diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..a1e89e1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..06b048b --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +There are two licenses, one for the C library software, and one for +the GeoLite Country database. + +SOFTWARE LICENSE + +Copyright (C) 2015 MaxMind, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +For a copy of the LGPL License, see the COPYING file. + +DATA LICENSE (GeoLite Country and City Databases) + +The GeoLite databases are distributed under the Creative Commons +Attribution-ShareAlike 3.0 Unported License. The attribution +requirement may be met by including the following in all advertising +and documentation mentioning features of or use of this database: + + This product includes GeoLite data created by MaxMind, available from + http://www.maxmind.com. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..ad9b1ea --- /dev/null +++ b/Makefile.am @@ -0,0 +1,15 @@ +AM_CPPFLAGS = -Wall -ansi +ACLOCAL_AMFLAGS = -I m4 + +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = \ + libGeoIP \ + apps \ + test \ + man + +pkgconfigdir = $(libdir)/pkgconfig/ +nodist_pkgconfig_DATA = geoip.pc + +EXTRA_DIST = LICENSE NEWS.md README.md README.OSX bootstrap GeoIP.spec GeoIP.spec.in Makefile.vc get_ver.awk geoip.ico geoip.pc.in data/GeoIP.dat diff --git a/Makefile.vc b/Makefile.vc new file mode 100644 index 0000000..fde3e48 --- /dev/null +++ b/Makefile.vc @@ -0,0 +1,84 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +################################################################# +# configuration section +################################################################ + +# place to put the GeoIP.dat database file +# !!! Please keep the 2 \\ as directory separators !!! +# +GEOIPDATADIR="C:\\Windows\\SYSTEM32" +# +# System inc, lib, and bin directories +!ifndef INSTDIR +INSTDIR="C:\GeoIP" +!endif + +# Location where GeoIP.lib should be installed my "make install" +INSTALL_LIB=$(INSTDIR)\Lib + +#Location where .h files should be installed by "make install". +INSTALL_INC=$(INSTDIR)\Include + +#Location where programs should be installed by "make install". +INSTALL_BIN=$(INSTDIR)\Bin + +################################################################ +# end configuration section +################################################################ + +DATA_DIR=data + +DATA_FILE=GeoIP.dat + +LIB_DIR = libGeoIP + +TEST_DIR=test + +APP_DIR=apps + +GEOIP_LIB = GeoIP.lib + +APP_PROGRAMS = geoiplookup.exe + +TEST_PROGRAMS = benchmark.exe test-geoip.exe + +all: GeoIP.lib test_progs app_progs + +$(GEOIP_LIB): + cd $(LIB_DIR) + $(MAKE) -nologo -f Makefile.vc GEOIPDATADIR=$(GEOIPDATADIR) + cd .. + +test_progs: + cd $(TEST_DIR) + $(MAKE) -nologo -f Makefile.vc + cd .. + +app_progs: + cd $(APP_DIR) + $(MAKE) -nologo -f Makefile.vc + cd .. + +test: $(GEOIP_LIB) test_progs + cd $(TEST_DIR) + benchmark.exe + test-geoip.exe + cd .. + +install: $(GEOIP_LIB) app_progs + cd $(LIB_DIR) + copy $(GEOIP_LIB) $(INSTALL_LIB) + copy *.h $(INSTALL_INC) + cd ..\$(APP_DIR) + copy $(APP_PROGRAMS) $(INSTALL_BIN) + cd ..\$(DATA_DIR) + copy $(DATA_FILE) $(GEOIPDATADIR) + cd .. + +clean: + del $(LIB_DIR)\*.obj $(LIB_DIR)\*.lib $(LIB_DIR)\*.dll + del $(APP_DIR)\*.obj $(APP_DIR)\*.exe + del $(TEST_DIR)\*.obj $(TEST_DIR)\*.exe + diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..d9716d3 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,50 @@ +## Important Changes ## + +### 1.6.0 ### + +`geoipupdate` is removed from the GeoIP C library. + +Please use the seperate tool [geoipupdate](https://github.com/maxmind/geoipupdate) to download your subscriptions or our +free databases. + +### 1.5.0 ### + +Geoipupdate may be used to download our free databases. + +Put this into the config file /usr/local/etc/GeoIP.conf +to download the free GeoLite databases GeoLiteCountry, GeoLiteCity and GeoLiteASNum + +``` +LicenseKey 000000000000 +UserId 999999 +ProductIds 506 533 517 +``` + +Free users should create symlinks for the GeoIP databases. +For example: + +``` +cd /usr/local/share/GeoIP +ln -s GeoLiteCity.dat GeoIPCity.dat +ln -s GeoLiteCountry.dat GeoIPCountry.dat +ln -s GeoLiteASNum.dat GeoIPASNum.dat +``` + +The lookup functions are thread safe. + +### 1.3.6 ### + +As of version 1.3.6, the GeoIP C library is thread safe, as long as +`GEOIP_CHECK_CACHE` is not used. + +### 1.3.0 ### + +The GeoIP Region database is no longer a pointer but an in-structure array so +test the first byte of region == 0 rather than testing if the region pointer +is `NULL`. + +### 1.1.0 ### + +As of GeoIP 1.1.0 the GeoIP_country_xxx_by_xxx functions return NULL if a +country can not be found. It previously returned `--` or `N/A`. To avoid +segmentation faults, check the return value for `NULL`. diff --git a/README.OSX b/README.OSX new file mode 100644 index 0000000..2cf30a7 --- /dev/null +++ b/README.OSX @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Building OSX fat binaries is easy. +# +# - start in a clean directory. +# - copy the shell script below to a file and edit the file to your needs. +# +# 1.) modify export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc -arch ppc64' +# to include all architectures you need. +# 2.) add whatever you want to the ./configure line. +# 3.) execute the script. +# 4.) do a 'make install' +# +# +# make clean or make distclean before building this +# +# tell systems before leopard that we like to build for 10.5 or higher +# with MACOSX_DEPLOYMENT_TARGET=10.5 +# starting with leopard we have to add -mmacosx-version-min=10.5 +# to the CFLAGS and export MACOSX_DEPLOYMENT_TARGET!? + +## for tiger, leopard and snow leopard you might use this +## export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc -arch ppc64' +## export MACOSX_DEPLOYMENT_TARGET=10.4 +## export LDFLAGS=$GEOIP_ARCH +## export CFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk $GEOIP_ARCH" + +# here we go for leopard and snow leopard +#export GEOIP_ARCH='-arch i386 -arch x86_64 -arch ppc' +#export MACOSX_DEPLOYMENT_TARGET=10.5 +#export LDFLAGS=$GEOIP_ARCH +#export CFLAGS="-g -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk $GEOIP_ARCH" +#./configure --disable-dependency-tracking +#perl -i.bak -pe'/^archive_cmds=/ and !/\bGEOIP_ARCH\b/ and s/-dynamiclib\b/-dynamiclib \\\$(GEOIP_ARCH)/' ./libtool +#make + +# and this is lion with the new xcode +#P=`xcode-select -print-path` +#export GEOIP_ARCH='-arch i386 -arch x86_64' +#export MACOSX_DEPLOYMENT_TARGET=10.7 +#export LDFLAGS=$GEOIP_ARCH +#export CFLAGS="-g -mmacosx-version-min=10.7 -isysroot $P/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $GEOIP_ARCH" +#./configure --disable-dependency-tracking +#make + +# and this is lion with the new xcode +P=`xcode-select -print-path` +export GEOIP_ARCH='-arch x86_64' +export MACOSX_DEPLOYMENT_TARGET=10.9 +export LDFLAGS=$GEOIP_ARCH +export CFLAGS="-g -mmacosx-version-min=10.9 -isysroot $P/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk $GEOIP_ARCH" +./configure --disable-dependency-tracking +make diff --git a/README.dev.md b/README.dev.md new file mode 100644 index 0000000..67deef8 --- /dev/null +++ b/README.dev.md @@ -0,0 +1,35 @@ +## Releasing + +* Make sure https://github.com/github/hub is installed and configured. +* Make sure the `ChangeLog` is up to date. +* Run `dev-bin/release.sh` + +## Ubuntu PPA packages + +0. Switch to the `ubuntu-ppa` branch and merge the release tag from above. + +Release script: + +1. run `dev-bin/ppa-release.sh` + +Manual PPA process: + +1. Type `dch -i` and add the appropriate `debian/changelog` entry. +2. Move tarball created above to a temp directory and + name it `geoip_1.?.?.orig.tar.gz`. +3. Unpack tarball. +4. Copy `debian` directory from Git. (We intentionally do not include it in + the tarball so that we don't interfere with Debian's packaging.) +5. Update `debian/changelog` for the dist you are releasing to, e.g., + precise, trusty, vivid, and prefix the version with the a `~` followed + by the dist name, e.g., `1.6.3-1+maxmind1~trusty`. +6. Run `debuild -S -sa -rfakeroot -k`. (The key may not be necessary + if your .bashrc is appropriately ) +7. Run `lintian` to make sure everything looks sane. +8. Run `dput ppa:maxmind/ppa ../` to + upload. +9. Repeat 4-8 for remaining distributions. + +## Homebrew + +* Update the [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/geoip.rb). diff --git a/README.md b/README.md new file mode 100644 index 0000000..debdfb1 --- /dev/null +++ b/README.md @@ -0,0 +1,248 @@ +# GeoIP Legacy C Library # + +## Important Note ## + +This library is for the GeoIP Legacy format (dat). To read the MaxMind DB +format (mmdb) used by GeoIP2, please see +[libmaxminddb](https://github.com/maxmind/libmaxminddb). + +## Description ## + +The GeoIP Legacy C library enables the user to find geographical and network +information of an IP address. To use this library, you may download our free +GeoLite Legacy Country or City databases. These are updated at the beginning +of every month. The latest versions are available at: + +https://dev.maxmind.com/geoip/legacy/geolite + +We also offer commercial GeoIP Legacy databases with greater accuracy and +additional network information. For more details, see: + +https://www.maxmind.com/en/geolocation_landing + +If you use GeoIP Legacy to block access from high risk countries, you may wish +to use our proxy detection service to block access from known proxy servers to +reduce fraud and abuse. For more details, see: + +https://www.maxmind.com/en/proxy + +## IP Geolocation Usage ## + +IP geolocation is inherently imprecise. Locations are often near the center of +the population. Any location provided by a GeoIP database should not be used to +identify a particular address or household. + +## Installation ## + +### On Ubuntu Using PPA ### + +MaxMind provides a PPA for recent version of Ubuntu. To add the PPA to your +APT sources, run: + + $ sudo add-apt-repository ppa:maxmind/ppa + +Then install the packages by running: + + $ sudo apt update + $ sudo apt install libgeoip1 libgeoip-dev geoip-bin + +### From Source on Unix/Linux ### + +To install, run: + +``` +./configure +make +make check +make install +``` + +If you are using a GitHub checkout, please run the `bootstrap` script first +to set up the build environment. + +The GeoIP Legacy C library relies on GNU make, not on BSD make + +### From Source with Visual Studio (nmake) ### + +To make a static GeoIP.lib, edit the top level Makefile.vc to reflect where +the GeoIP.dat database file should be placed, as well as the locations of the +lib, include, and bin directories for installation. + +To build and install, issue the following commands from a developer console: + +``` +nmake /f Makefile.vc +nmake /f Makefile.vc test +nmake /f Makefile.vc install +``` + +### From Source with MinGW ### + +``` +./configure +make +cp data/GeoIP.dat test/ +make check +``` + +Note that GeoIP.dat file should be placed in the same place as GeoIP-enabled +executable modules. + +## Memory Caching and Other Options ## + +There are five options available: + +* `GEOIP_STANDARD` - Read database from file system. This uses the least + memory. +* `GEOIP_MEMORY_CACHE` - Load database into memory. Provides faster + performance but uses more memory. +* `GEOIP_CHECK_CACHE` - Check for updated database. If database has been + updated, reload file handle and/or memory cache. +* `GEOIP_INDEX_CACHE` - Cache only the the most frequently accessed index + portion of the database, resulting in faster lookups than `GEOIP_STANDARD`, + but less memory usage than `GEOIP_MEMORY_CACHE`. This is useful for larger + databases such as GeoIP Legacy Organization and GeoIP Legacy City. Note: for + GeoIP Legacy Country, Region and Netspeed databases, `GEOIP_INDEX_CACHE` is + equivalent to `GEOIP_MEMORY_CACHE`. +* `GEOIP_MMAP_CACHE` - Load database into mmap shared memory. MMAP is not + available for 32bit Windows. +* `GEOIP_SILENCE` - Disables diagnostic messages to stderr in the library; + error conditions are detectable via the return values. + +These options can be combined using bit operators. For example you can +use both `GEOIP_MEMORY_CACHE` and `GEOIP_CHECK_CACHE by calling`: + +```c +GeoIP_open("/path/to/GeoIP.dat", GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE); +``` + +By default, the city name is returned in the ISO-8859-1 charset. To obtain +the city name in UTF-8 instead, run: + +```c +GeoIP_set_charset(gi, GEOIP_CHARSET_UTF8); +``` + +To get the netmask of the netblock of the last lookup, use +`GeoIP_last_netmask(gi)`. + +## Examples ## + +See the following files for examples of how to use the API: + +``` +test/ + test-geoip.c + test-geoip-region.c + test-geoip-city.c + test-geoip-isp.c + test-geoip-org.c + test-geoip-netspeed.c +``` + +The test-geoip.c program works with both the GeoLite Legacy and GeoIP Legacy +Country databases. The test-geoip-city.c program works with both the GeoLite +Legacy and GeoIP Legacy City databases. The other example programs require the +paid databases available (https://www.maxmind.com/en/geolocation_landing). + +## Troubleshooting ## + +### Autotool Issues ### +In case of trouble building from source with libtool or autotools, update +the generated configuration files by running: + +``` +./bootstrap +``` +or + +``` +autoreconf -vfi +``` +or +``` +aclocal && autoconf && automake --add-missing +``` + +### Threads + +Lookups are thread safe, but libGeoIP does not guard the functions. Do not +drop or change the GeoIP database if other threads might be using the +database. + +The recommended pattern is: + +1. open database with GEOIP_MEMORY_CACHE +2. create_threads(your_thread_entry_function) +3. use the database +4. join_threads +5. close database + +### Thread Safety on Windows ### + +The Windows build is not thread-safe in STANDARD mode because the `pread` is +not thread-safe. + +### Other Build Issues ### + +If you run into trouble building your application with GeoIP Legacy support, +try adding `-fms-extensions` to your `CFLAGS`. If you use Solaris and the +default C compiler, use `-features=extensions` instead. These options enable +unnamed union support to fix problems like: `improper member use: dma_code` or +`'GeoIPRecord' has no member named 'dma_code'`. + +Note that it is recommended that you use GNU make. Also, if you are using +OpenBSD, this library requires OpenBSD 3.1 or greater. + +If you get a "cannot load shared object file: No such file or directory" +error, add the directory `libGeoIP.so` was installed to the `/etc/ld.so.conf` +file and run `ldconfig`. + +#### Solaris #### + +On Solaris, if you get a `ld: fatal: relocations remain against allocatable +but non-writable sections`, try running: + +``` +make clean +./configure --disable-shared +make +``` + +If you get a `ar : command not found` error, make sure that `ar` is in your +path. On Solaris, `ar` is typically found in `/usr/ccs/bin` + + +#### AIX #### + +If you get a `passing argument 3 of 'gethostbyname_r' from incompatible +pointer type` error on AIX, untar a fresh copy of this library and delete the +following two lines from `./configure`: + +``` +#define HAVE_GETHOSTBYNAME_R 1 + +#define GETHOSTBYNAME_R_RETURNS_INT 1 +``` + +then save the configure script and build it as usual: + +``` +./configure +make +sudo make install +``` + +## Bug Tracker ## + +Please report all issues with this code using the +[GitHub issue tracker](https://github.com/maxmind/geoip-api-c/issues). + +If you are having an issue with a MaxMind database that is not specific to +this API, please +[contact MaxMind support](https://www.maxmind.com/en/support). + +## Contributing ## + +To contribute, please submit a pull request on +[GitHub](https://github.com/maxmind/geoip-api-c/). diff --git a/apps/Makefile.am b/apps/Makefile.am new file mode 100644 index 0000000..6e2a49c --- /dev/null +++ b/apps/Makefile.am @@ -0,0 +1,18 @@ +AM_CPPFLAGS = -I$(top_srcdir)/libGeoIP -DSYSCONFDIR=\"$(sysconfdir)\" -Wall + +DEPS = $(top_builddir)/libGeoIP/libGeoIP.la +LDADDS = $(top_builddir)/libGeoIP/libGeoIP.la + +bin_PROGRAMS = geoiplookup geoiplookup6 + +geoiplookup_SOURCES = geoiplookup.c +geoiplookup_LDFLAGS = +geoiplookup_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la + +geoiplookup6_SOURCES = geoiplookup6.c +geoiplookup6_LDFLAGS = +geoiplookup6_DEPENDENCIES = $(top_builddir)/libGeoIP/libGeoIP.la +geoiplookup6_LDADD = $(top_builddir)/libGeoIP/libGeoIP.la + +EXTRA_DIST = Makefile.vc diff --git a/apps/Makefile.vc b/apps/Makefile.vc new file mode 100644 index 0000000..266a931 --- /dev/null +++ b/apps/Makefile.vc @@ -0,0 +1,25 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +LINK = link -nologo + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) + +GEOIPLIB = ..\libGeoIP\GeoIP.lib + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +APPS: geoiplookup.exe + +geoiplookup.exe: geoiplookup.c + $(CC1) -c geoiplookup.c + $(LINK) geoiplookup.obj $(GEOIPLIB) + diff --git a/apps/geoiplookup.c b/apps/geoiplookup.c new file mode 100644 index 0000000..1c412ea --- /dev/null +++ b/apps/geoiplookup.c @@ -0,0 +1,375 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoiplookup.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" +#include "GeoIP_internal.h" + +#if defined(_WIN32) +#ifndef uint32_t +typedef unsigned int uint32_t; +#endif +#endif + +void geoiplookup(GeoIP *gi, char *hostname, int i); + +void usage(void) { + fprintf(stderr, + "Usage: geoiplookup [-h] [-?] [-d custom_dir] [-f " + "custom_file] [-v] [-i] [-l] \n"); +} + +/* extra info used in _say_range_ip */ +int info_flag = 0; + +int main(int argc, char *argv[]) { + char *hostname = NULL; + char *db_info; + GeoIP *gi; + int i; + char *custom_directory = NULL; + char *custom_file = NULL; + int version_flag = 0; + int charset = GEOIP_CHARSET_UTF8; + + if (argc < 2) { + usage(); + exit(1); + } + i = 1; + while (i < argc) { + if (strcmp(argv[i], "-v") == 0) { + version_flag = 1; + } else if (strcmp(argv[i], "-l") == 0) { + charset = GEOIP_CHARSET_ISO_8859_1; + } else if (strcmp(argv[i], "-i") == 0) { + info_flag = 1; + } else if ((strcmp(argv[i], "-?") == 0) || + (strcmp(argv[i], "-h") == 0)) { + usage(); + exit(0); + } else if (strcmp(argv[i], "-f") == 0) { + if ((i + 1) < argc) { + i++; + custom_file = argv[i]; + } + } else if (strcmp(argv[i], "-d") == 0) { + if ((i + 1) < argc) { + i++; + custom_directory = argv[i]; + } + } else { + hostname = argv[i]; + } + i++; + } + if (hostname == NULL) { + usage(); + exit(1); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + _GeoIP_setup_dbfilename(); + + if (custom_file != NULL) { + gi = GeoIP_open(custom_file, GEOIP_STANDARD | GEOIP_SILENCE); + + if (NULL == gi) { + printf("%s not available, skipping...\n", custom_file); + } else { + gi->charset = charset; + i = GeoIP_database_edition(gi); + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", + GeoIPDBDescription[i], + db_info == NULL ? "" : db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } else { + /* iterate through different database types */ + for (i = 0; i < NUM_DB_TYPES; ++i) { + if (GeoIP_db_avail(i)) { + gi = GeoIP_open_type(i, GEOIP_STANDARD | GEOIP_SILENCE); + if (NULL == gi) { + /* Ignore these errors. It's possible + * to use the same database name for + * different databases. + */ + ; + } else { + gi->charset = charset; + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", + GeoIPDBDescription[i], + db_info == NULL ? "" : db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } + } + } + return 0; +} + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +static unsigned long __addr_to_num(const char *addr) { + unsigned int c, octet, t; + unsigned long ipnum; + int i = 3; + + octet = ipnum = 0; + while ((c = *addr++)) { + if (c == '.') { + if (octet > 255) { + return 0; + } + ipnum <<= 8; + ipnum += octet; + i--; + octet = 0; + } else { + t = octet; + octet <<= 3; + octet += t; + octet += t; + c -= '0'; + if (c > 9) { + return 0; + } + octet += c; + } + } + if ((octet > 255) || (i != 0)) { + return 0; + } + ipnum <<= 8; + return ipnum + octet; +} + +/* ptr must be a memory area with at least 16 bytes */ +static char *__num_to_addr_r(unsigned long ipnum, char *ptr) { + char *cur_str; + int octet[4]; + int num_chars_written, i; + + cur_str = ptr; + + for (i = 0; i < 4; i++) { + octet[3 - i] = ipnum % 256; + ipnum >>= 8; + } + + for (i = 0; i < 4; i++) { + num_chars_written = sprintf(cur_str, "%d", octet[i]); + cur_str += num_chars_written; + + if (i < 3) { + cur_str[0] = '.'; + cur_str++; + } + } + + return ptr; +} + +void _say_range_by_ip(GeoIP *gi, uint32_t ipnum) { + unsigned long last_nm, mask, low, hi; + char ipaddr[16]; + char tmp[16]; + char **range; + + if (info_flag == 0) { + return; /* noop unless extra information is requested */ + } + range = GeoIP_range_by_ip(gi, __num_to_addr_r(ipnum, ipaddr)); + if (range == NULL) { + return; + } + + printf(" ipaddr: %s\n", ipaddr); + + printf(" range_by_ip: %s - %s\n", range[0], range[1]); + last_nm = GeoIP_last_netmask(gi); + mask = 0xffffffff << (32 - last_nm); + low = ipnum & mask; + hi = low + (0xffffffff & ~mask); + printf(" network: %s - %s ::%ld\n", + __num_to_addr_r(low, ipaddr), + __num_to_addr_r(hi, tmp), + last_nm); + printf(" ipnum: %u\n", ipnum); + printf(" range_by_num: %lu - %lu\n", + __addr_to_num(range[0]), + __addr_to_num(range[1])); + printf(" network num: %lu - %lu ::%lu\n", low, hi, last_nm); + + GeoIP_range_by_ip_delete(range); +} + +void geoiplookup(GeoIP *gi, char *hostname, int i) { + const char *country_code; + const char *country_name; + const char *domain_name; + const char *asnum_name; + int netspeed; + int country_id; + GeoIPRegion *region; + GeoIPRecord *gir; + const char *org; + uint32_t ipnum; + + ipnum = _GeoIP_lookupaddress(hostname); + if (ipnum == 0) { + printf("%s: can't resolve hostname ( %s )\n", + GeoIPDBDescription[i], + hostname); + } else { + if (GEOIP_DOMAIN_EDITION == i) { + domain_name = GeoIP_name_by_ipnum(gi, ipnum); + if (domain_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], domain_name); + _say_range_by_ip(gi, ipnum); + free((void *)domain_name); + } + } else if (GEOIP_LOCATIONA_EDITION == i || + GEOIP_ACCURACYRADIUS_EDITION == i || + GEOIP_ASNUM_EDITION == i || GEOIP_USERTYPE_EDITION == i || + GEOIP_REGISTRAR_EDITION == i || + GEOIP_NETSPEED_EDITION_REV1 == i || + GEOIP_COUNTRYCONF_EDITION == i || + GEOIP_CITYCONF_EDITION == i || + GEOIP_REGIONCONF_EDITION == i || + GEOIP_POSTALCONF_EDITION == i) { + asnum_name = GeoIP_name_by_ipnum(gi, ipnum); + if (asnum_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], asnum_name); + _say_range_by_ip(gi, ipnum); + free((void *)asnum_name); + } + } else if (GEOIP_COUNTRY_EDITION == i) { + country_id = GeoIP_id_by_ipnum(gi, ipnum); + if (country_id < 0 || country_id >= (int)GeoIP_num_countries()) { + printf("%s: Invalid database\n", GeoIPDBDescription[i]); + return; + } + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + if (country_id == 0) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s\n", + GeoIPDBDescription[i], + country_code, + country_name); + _say_range_by_ip(gi, ipnum); + } + } else if (GEOIP_REGION_EDITION_REV0 == i || + GEOIP_REGION_EDITION_REV1 == i) { + region = GeoIP_region_by_ipnum(gi, ipnum); + if (NULL == region || region->country_code[0] == '\0') { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s\n", + GeoIPDBDescription[i], + region->country_code, + region->region); + _say_range_by_ip(gi, ipnum); + } + if (region) { + GeoIPRegion_delete(region); + } + } else if (GEOIP_CITY_EDITION_REV0 == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %s, %f, %f\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } else if (GEOIP_CITY_EDITION_REV1 == i) { + gir = GeoIP_record_by_ipnum(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %s, %f, %f, %d, %d\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code); + _say_range_by_ip(gi, ipnum); + GeoIPRecord_delete(gir); + } + } else if (GEOIP_ORG_EDITION == i || GEOIP_ISP_EDITION == i) { + org = GeoIP_org_by_ipnum(gi, ipnum); + if (org == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], org); + _say_range_by_ip(gi, ipnum); + free((void *)org); + } + } else if (GEOIP_NETSPEED_EDITION == i) { + netspeed = GeoIP_id_by_ipnum(gi, ipnum); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s: Unknown\n", GeoIPDBDescription[i]); + } else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s: Dialup\n", GeoIPDBDescription[i]); + } else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s: Cable/DSL\n", GeoIPDBDescription[i]); + } else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s: Corporate\n", GeoIPDBDescription[i]); + } + _say_range_by_ip(gi, ipnum); + } + } +} diff --git a/apps/geoiplookup6.c b/apps/geoiplookup6.c new file mode 100644 index 0000000..fe81d98 --- /dev/null +++ b/apps/geoiplookup6.c @@ -0,0 +1,195 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoiplookup.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" +#include "GeoIP_internal.h" +void geoiplookup(GeoIP *gi, char *hostname, int i); + +void usage(void) { + fprintf(stderr, + "Usage: geoiplookup [-h] [-d custom_dir] [-f custom_file] " + "[-v] \n"); +} + +int main(int argc, char *argv[]) { + char *hostname = NULL; + char *db_info; + GeoIP *gi; + int i; + char *custom_directory = NULL; + char *custom_file = NULL; + int version_flag = 0; + + if (argc < 2) { + usage(); + exit(1); + } + i = 1; + while (i < argc) { + if (strcmp(argv[i], "-v") == 0) { + version_flag = 1; + } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) { + usage(); + exit(0); + } else if (strcmp(argv[i], "-f") == 0) { + if ((i + 1) < argc) { + i++; + custom_file = argv[i]; + } + } else if (strcmp(argv[i], "-d") == 0) { + if ((i + 1) < argc) { + i++; + custom_directory = argv[i]; + } + } else { + hostname = argv[i]; + } + i++; + } + if (hostname == NULL) { + usage(); + exit(1); + } + + if (custom_directory != NULL) { + GeoIP_setup_custom_directory(custom_directory); + } + _GeoIP_setup_dbfilename(); + + if (custom_file != NULL) { + gi = GeoIP_open(custom_file, GEOIP_STANDARD | GEOIP_SILENCE); + if (NULL == gi) { + printf("%s not available, skipping...\n", custom_file); + } else { + i = GeoIP_database_edition(gi); + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", + GeoIPDBDescription[i], + db_info == NULL ? "" : db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } else { + /* iterate through different database types */ + for (i = 0; i < NUM_DB_TYPES; ++i) { + if (GeoIP_db_avail(i)) { + gi = GeoIP_open_type(i, GEOIP_STANDARD | GEOIP_SILENCE); + if (NULL == gi) { + /* Ignore these errors. It's possible + * to use the same database name for + * different databases. + */ + ; + } else { + if (version_flag == 1) { + db_info = GeoIP_database_info(gi); + printf("%s: %s\n", GeoIPDBDescription[i], db_info); + free(db_info); + } else { + geoiplookup(gi, hostname, i); + } + } + GeoIP_delete(gi); + } + } + } + return 0; +} + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +void geoiplookup(GeoIP *gi, char *hostname, int i) { + const char *country_code; + const char *country_name; + const char *asnum_name; + int country_id; + GeoIPRecord *gir; + + geoipv6_t ipnum; + ipnum = _GeoIP_lookupaddress_v6(hostname); + if (__GEOIP_V6_IS_NULL(ipnum)) { + printf("%s: can't resolve hostname ( %s )\n", + GeoIPDBDescription[i], + hostname); + } else { + if (GEOIP_LOCATIONA_EDITION_V6 == i || GEOIP_ASNUM_EDITION_V6 == i || + GEOIP_USERTYPE_EDITION_V6 == i || GEOIP_REGISTRAR_EDITION_V6 == i || + GEOIP_DOMAIN_EDITION_V6 == i || GEOIP_ORG_EDITION_V6 == i || + GEOIP_ISP_EDITION_V6 == i || GEOIP_NETSPEED_EDITION_REV1_V6 == i) { + asnum_name = GeoIP_name_by_ipnum_v6(gi, ipnum); + if (asnum_name == NULL) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s\n", GeoIPDBDescription[i], asnum_name); + } + } else if (GEOIP_CITY_EDITION_REV0_V6 == i) { + gir = GeoIP_record_by_ipnum_v6(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %f, %f\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude); + } + } else if (GEOIP_CITY_EDITION_REV1_V6 == i) { + gir = GeoIP_record_by_ipnum_v6(gi, ipnum); + if (NULL == gir) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s, %s, %s, %f, %f, %d, %d\n", + GeoIPDBDescription[i], + gir->country_code, + _mk_NA(gir->region), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code); + } + } else if (GEOIP_COUNTRY_EDITION_V6 == i) { + country_id = GeoIP_id_by_ipnum_v6(gi, ipnum); + if (country_id < 0 || country_id >= (int)GeoIP_num_countries()) { + printf("%s: Invalid database\n", GeoIPDBDescription[i]); + return; + } + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + if (country_id == 0) { + printf("%s: IP Address not found\n", GeoIPDBDescription[i]); + } else { + printf("%s: %s, %s\n", + GeoIPDBDescription[i], + country_code, + country_name); + } + } + } +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..ddeb7ca --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,20 @@ +--- +install: + - '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64' +build_script: + - nmake /f Makefile.vc +notifications: + - incoming_webhook: + secure: 8FZP/RE3nS77Yi5UWOB/DQKCRSJxh/BYrLjVPEAkBG6mRojCz3r2mnla4O/5GwzDr7V6XCpxCP0xo1buCcZRIzRN0ZUWJ5hzEQqW5u7R+vM= + channel: ci + on_build_failure: true + on_build_status_changed: true + on_build_success: true + provider: Slack + - on_build_failure: true + on_build_status_changed: true + on_build_success: false + provider: Email + subject: 'AppVeyor build {{status}}' + to: + - dev-ci@maxmind.com diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..30fc0f9 --- /dev/null +++ b/bootstrap @@ -0,0 +1,19 @@ +#!/bin/sh + +# make sure to use the installed libtool +rm -f ltmain.sh +autoreconf -fiv + +################################################### +# the steps below may help with outdated toolsets + +# disable dependency trackeing for OS X with multiply arch option's +# automake -i --gnu --add-missing + + +#aclocal \ +#&& automake -i --gnu --add-missing \ +#&& autoconf + +#LIBTOOLIZE=$( which libtoolize glibtoolize | head -1 ) +#$LIBTOOLIZE -f diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..28d098c --- /dev/null +++ b/configure.ac @@ -0,0 +1,77 @@ +dnl AM_CONFIG_HEADER(config.h) + +AC_PREREQ([2.63]) +AC_INIT([GeoIP], [1.6.12],[support@maxmind.com],[GeoIP]) +AC_CONFIG_AUX_DIR([.]) +AC_CONFIG_SRCDIR([libGeoIP/GeoIP.c]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE(1.10.0) +AC_GNU_SOURCE +GEOIP_VERSION_INFO=`echo $VERSION | awk -F. '{ printf "%d:%d:%d", $1+$2, $3, $2 }'` +AC_SUBST(GEOIP_VERSION_INFO) + +AC_PROG_CC +AC_PROG_LIBTOOL + +AC_CHECK_TYPE(byte,[AC_DEFINE(HAVE_BYTE_TYPEDEF)],[]) +AC_CHECK_TYPE(ushort,[AC_DEFINE(HAVE_USHORT_TYPEDEF)],[]) +AC_CHECK_TYPE(ulong,[AC_DEFINE(HAVE_ULONG_TYPEDEF)],[]) +AC_CHECK_TYPE(u16,[AC_DEFINE(HAVE_U16_TYPEDEF)],[]) +AC_CHECK_TYPE(u32,[AC_DEFINE(HAVE_U32_TYPEDEF)],[]) + +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T + +AC_C_BIGENDIAN([AC_DEFINE(BIG_ENDIAN_HOST,1)],[AC_DEFINE(LITTLE_ENDIAN_HOST,1)]) + +AC_CHECK_FUNC(getopt, AC_DEFINE(HAVE_GETOPT)) +AC_CHECK_FUNC(gettimeofday, AC_DEFINE(HAVE_GETTIMEOFDAY)) +AC_CHECK_FUNC(pread, AC_DEFINE(HAVE_PREAD)) +AC_CHECK_FUNC(vasprintf, AC_DEFINE(HAVE_VASPRINTF)) +AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF)) +AC_CHECK_FUNC(vsprintf, AC_DEFINE(HAVE_VSPRINTF)) + +AC_CHECK_FUNC(gethostbyname, AC_DEFINE(HAVE_GETHOSTBYNAME), + AC_CHECK_LIB(nsl, gethostbyname, AC_DEFINE(HAVE_GETHOSTBYNAME) + LIBS="${LIBS} -lsocket -lnsl")) + +AC_CHECK_FUNC(gethostbyname_r, [ + AC_DEFINE(HAVE_GETHOSTBYNAME_R) + # We look for the one that returns `int'. + # Hopefully this check is robust enough. + AC_EGREP_HEADER(int.*gethostbyname_r, netdb.h, [ + AC_DEFINE(GETHOSTBYNAME_R_RETURNS_INT)]) + ]) + +AC_CHECK_FUNCS([ memset memchr munmap strrchr socket strchr strdup strstr ]) + +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_MMAP + +AC_ARG_ENABLE([data-files], + AS_HELP_STRING([--disable-data-files], [Install library without installing data files])) + +AS_IF([test "x$enable_data_files" != xno], + AC_SUBST([GEOIP_DB_FILE],[GeoIP.dat])) + +case $host_os in + mingw* ) + # To do: Check for and add -Wl,--high-entropy-va if it's supported. + LDFLAGS="$LDFLAGS -lwsock32 -lws2_32 -Wl,--dynamicbase -Wl,--nxcompat" + ;; +esac + + +AC_OUTPUT([ +Makefile +GeoIP.spec +geoip.pc +libGeoIP/Makefile +apps/Makefile +man/Makefile +test/Makefile +]) diff --git a/data/GeoIP.dat b/data/GeoIP.dat new file mode 100644 index 0000000..a092ad7 Binary files /dev/null and b/data/GeoIP.dat differ diff --git a/dev-bin/clang-format-all.sh b/dev-bin/clang-format-all.sh new file mode 100755 index 0000000..b8bec61 --- /dev/null +++ b/dev-bin/clang-format-all.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +format="clang-format -i -style=file" + +for dir in apps libGeoIP test; do + c_files=`find $dir -maxdepth 1 -name '*.c'` + if [ "$c_files" != "" ]; then + $format $dir/*.c; + fi + + h_files=`find $dir -maxdepth 1 -name '*.h'` + if [ "$h_files" != "" ]; then + $format $dir/*.h; + fi +done diff --git a/dev-bin/release.sh b/dev-bin/release.sh new file mode 100755 index 0000000..ec6ccfa --- /dev/null +++ b/dev-bin/release.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +set -eu -o pipefail + +changelog=$(cat ChangeLog) + +regex='([0-9]+\.[0-9]+\.[0-9]+) ([0-9]{4}-[0-9]{2}-[0-9]{2}) + +((.| +)*) +' + +if [[ ! $changelog =~ $regex ]]; then + echo "Could not find date line in change log!" + exit 1 +fi + +version="${BASH_REMATCH[1]}" +date="${BASH_REMATCH[2]}" +notes="$(echo "${BASH_REMATCH[3]}" | sed -n -e '/^[0-9]\+\.[0-9]\+\.[0-9]\+/,$!p')" + +dist="GeoIP-$version.tar.gz" + +if [[ "$date" != $(date +"%Y-%m-%d") ]]; then + echo "$date is not today!" + exit 1 +fi + +if [ -n "$(git status --porcelain)" ]; then + echo ". is not clean." >&2 + exit 1 +fi + +perl -pi -e "s/(?<=AC_INIT\(\[GeoIP\], \[)(\d+\.\d+\.\d+)(?=])/$version/gsm" configure.ac + +if [ -n "$(git status --porcelain)" ]; then + git add configure.ac + git commit -m "Bumped version to $version" +fi + +./bootstrap +./configure +make +make check +make clean +make dist + +read -p "Push to origin? (y/n) " should_push + +if [ "$should_push" != "y" ]; then + echo "Aborting" + exit 1 +fi + +git push + +message="$version + +$notes" + +hub release create -a "$dist" -m "$message" "v$version" diff --git a/geoip.ico b/geoip.ico new file mode 100644 index 0000000..ac13353 Binary files /dev/null and b/geoip.ico differ diff --git a/geoip.pc.in b/geoip.pc.in new file mode 100644 index 0000000..31b8fff --- /dev/null +++ b/geoip.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@prefix@ +libdir=@libdir@ +includedir=@includedir@ +datadir=@datarootdir@ + +Name: geoip +Description: A non-DNS IP-to-country resolver library. +Version: @VERSION@ +Libs: -L${libdir} -lGeoIP +Cflags: -I${includedir}/ +databasedir=${datadir}/GeoIP diff --git a/get_ver.awk b/get_ver.awk new file mode 100644 index 0000000..0314881 --- /dev/null +++ b/get_ver.awk @@ -0,0 +1,14 @@ +# fetch version number from input file and write them to STDOUT +BEGIN { + while ((getline < ARGV[1]) > 0) { + if (match ($0, /^VERSION=/)) { + split($1, t, "="); + my_ver_str = t[2]; + split(my_ver_str, v, "."); + gsub("[^0-9].*$", "", v[3]); + my_ver = v[1] "," v[2] "," v[3]; + } + } + print "GEOIP_VERSION = " my_ver ""; + print "GEOIP_VERSION_STR = " my_ver_str ""; +} diff --git a/libGeoIP/GeoIP.c b/libGeoIP/GeoIP.c new file mode 100644 index 0000000..587326a --- /dev/null +++ b/libGeoIP/GeoIP.c @@ -0,0 +1,2766 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIP_internal.h" + +static geoipv6_t IPV6_NULL; + +#if defined(_WIN32) +#include + +#ifdef _MSC_VER +#if _MSC_VER < 1900 // VS 2015 supports snprintf +#define snprintf _snprintf +#endif +#if _MSC_VER >= 1400 // VS 2005+ deprecates fileno, lseek and read +#define fileno _fileno +#define read _read +#define lseek _lseek +#endif +#endif +#else +#include +#include +#include +#endif /* defined(_WIN32) */ + +#include +#include +#include +#include +#include +#include /* for fstat */ +#include /* for fstat */ + +#ifdef HAVE_GETTIMEOFDAY +#include /* for gettimeofday */ +#endif + +#ifdef HAVE_STDINT_H +#include /* For uint32_t */ +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "pread.h" +#endif + +#ifdef _UNUSED +#elif defined(__GNUC__) +#define _UNUSED __attribute__((unused)) +#else +#define _UNUSED +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +#define COUNTRY_BEGIN 16776960 +#define LARGE_COUNTRY_BEGIN 16515072 +#define STATE_BEGIN_REV0 16700000 +#define STATE_BEGIN_REV1 16000000 +#define STRUCTURE_INFO_MAX_SIZE 20 +#define DATABASE_INFO_MAX_SIZE 100 +#define MAX_ORG_RECORD_LENGTH 300 +#define US_OFFSET 1 +#define CANADA_OFFSET 677 +#define WORLD_OFFSET 1353 +#define FIPS_RANGE 360 + +#define DEBUG_MSGF(flags, fmt, ...) \ + { \ + if (((flags)&GEOIP_SILENCE) == 0) { \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + } \ + } + +#ifndef HAVE_PREAD +#define pread(fd, buf, count, offset) \ + (lseek(fd, offset, SEEK_SET) == offset ? read(fd, buf, count) : -1) +#endif /* HAVE_PREAD */ + +const char GeoIP_country_code[256][3] = { + "--", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "CW", "AO", + "AQ", "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", + "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", + "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", + "CN", "CO", "CR", "CU", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", + "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", + "FM", "FO", "FR", "SX", "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", + "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", + "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", + "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", + "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", + "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", "MO", + "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", + "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", + "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", + "PW", "PY", "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", + "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", + "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", + "TL", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", + "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "RS", + "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", "AX", "GG", "IM", "JE", "BL", + "MF", "BQ", "SS", "O1"}; + +static const unsigned num_GeoIP_countries = + (unsigned)(sizeof(GeoIP_country_code) / sizeof(GeoIP_country_code[0])); + +const char GeoIP_country_code3[256][4] = { + "--", "AP", "EU", "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "CUW", + "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "AZE", "BIH", "BRB", "BGD", + "BEL", "BFA", "BGR", "BHR", "BDI", "BEN", "BMU", "BRN", "BOL", "BRA", "BHS", + "BTN", "BVT", "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG", "CHE", + "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI", "CUB", "CPV", "CXR", "CYP", + "CZE", "DEU", "DJI", "DNK", "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", + "ERI", "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA", "SXM", "GAB", + "GBR", "GRD", "GEO", "GUF", "GHA", "GIB", "GRL", "GMB", "GIN", "GLP", "GNQ", + "GRC", "SGS", "GTM", "GUM", "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", + "HUN", "IDN", "IRL", "ISR", "IND", "IOT", "IRQ", "IRN", "ISL", "ITA", "JAM", + "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR", "COM", "KNA", "PRK", "KOR", "KWT", + "CYM", "KAZ", "LAO", "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX", + "LVA", "LBY", "MAR", "MCO", "MDA", "MDG", "MHL", "MKD", "MLI", "MMR", "MNG", + "MAC", "MNP", "MTQ", "MRT", "MSR", "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", + "MOZ", "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL", "NRU", + "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG", "PHL", "PAK", "POL", "SPM", + "PCN", "PRI", "PSE", "PRT", "PLW", "PRY", "QAT", "REU", "ROU", "RUS", "RWA", + "SAU", "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM", "SVK", "SLE", + "SMR", "SEN", "SOM", "SUR", "STP", "SLV", "SYR", "SWZ", "TCA", "TCD", "ATF", + "TGO", "THA", "TJK", "TKL", "TKM", "TUN", "TON", "TLS", "TUR", "TTO", "TUV", + "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB", "VAT", "VCT", "VEN", + "VGB", "VIR", "VNM", "VUT", "WLF", "WSM", "YEM", "MYT", "SRB", "ZAF", "ZMB", + "MNE", "ZWE", "A1", "A2", "O1", "ALA", "GGY", "IMN", "JEY", "BLM", "MAF", + "BES", "SSD", "O1"}; + +const char *GeoIP_utf8_country_name[256] = { + "N/A", + "Asia/Pacific Region", + "Europe", + "Andorra", + "United Arab Emirates", + "Afghanistan", + "Antigua and Barbuda", + "Anguilla", + "Albania", + "Armenia", + "Cura" + "\xc3\xa7" + "ao", + "Angola", + "Antarctica", + "Argentina", + "American Samoa", + "Austria", + "Australia", + "Aruba", + "Azerbaijan", + "Bosnia and Herzegovina", + "Barbados", + "Bangladesh", + "Belgium", + "Burkina Faso", + "Bulgaria", + "Bahrain", + "Burundi", + "Benin", + "Bermuda", + "Brunei Darussalam", + "Bolivia", + "Brazil", + "Bahamas", + "Bhutan", + "Bouvet Island", + "Botswana", + "Belarus", + "Belize", + "Canada", + "Cocos (Keeling) Islands", + "Congo, The Democratic Republic of the", + "Central African Republic", + "Congo", + "Switzerland", + "Cote D'Ivoire", + "Cook Islands", + "Chile", + "Cameroon", + "China", + "Colombia", + "Costa Rica", + "Cuba", + "Cape Verde", + "Christmas Island", + "Cyprus", + "Czech Republic", + "Germany", + "Djibouti", + "Denmark", + "Dominica", + "Dominican Republic", + "Algeria", + "Ecuador", + "Estonia", + "Egypt", + "Western Sahara", + "Eritrea", + "Spain", + "Ethiopia", + "Finland", + "Fiji", + "Falkland Islands (Malvinas)", + "Micronesia, Federated States of", + "Faroe Islands", + "France", + "Sint Maarten (Dutch part)", + "Gabon", + "United Kingdom", + "Grenada", + "Georgia", + "French Guiana", + "Ghana", + "Gibraltar", + "Greenland", + "Gambia", + "Guinea", + "Guadeloupe", + "Equatorial Guinea", + "Greece", + "South Georgia and the South Sandwich Islands", + "Guatemala", + "Guam", + "Guinea-Bissau", + "Guyana", + "Hong Kong", + "Heard Island and McDonald Islands", + "Honduras", + "Croatia", + "Haiti", + "Hungary", + "Indonesia", + "Ireland", + "Israel", + "India", + "British Indian Ocean Territory", + "Iraq", + "Iran, Islamic Republic of", + "Iceland", + "Italy", + "Jamaica", + "Jordan", + "Japan", + "Kenya", + "Kyrgyzstan", + "Cambodia", + "Kiribati", + "Comoros", + "Saint Kitts and Nevis", + "Korea, Democratic People's Republic of", + "Korea, Republic of", + "Kuwait", + "Cayman Islands", + "Kazakhstan", + "Lao People's Democratic Republic", + "Lebanon", + "Saint Lucia", + "Liechtenstein", + "Sri Lanka", + "Liberia", + "Lesotho", + "Lithuania", + "Luxembourg", + "Latvia", + "Libya", + "Morocco", + "Monaco", + "Moldova, Republic of", + "Madagascar", + "Marshall Islands", + "Macedonia", + "Mali", + "Myanmar", + "Mongolia", + "Macau", + "Northern Mariana Islands", + "Martinique", + "Mauritania", + "Montserrat", + "Malta", + "Mauritius", + "Maldives", + "Malawi", + "Mexico", + "Malaysia", + "Mozambique", + "Namibia", + "New Caledonia", + "Niger", + "Norfolk Island", + "Nigeria", + "Nicaragua", + "Netherlands", + "Norway", + "Nepal", + "Nauru", + "Niue", + "New Zealand", + "Oman", + "Panama", + "Peru", + "French Polynesia", + "Papua New Guinea", + "Philippines", + "Pakistan", + "Poland", + "Saint Pierre and Miquelon", + "Pitcairn Islands", + "Puerto Rico", + "Palestinian Territory", + "Portugal", + "Palau", + "Paraguay", + "Qatar", + "Reunion", + "Romania", + "Russian Federation", + "Rwanda", + "Saudi Arabia", + "Solomon Islands", + "Seychelles", + "Sudan", + "Sweden", + "Singapore", + "Saint Helena", + "Slovenia", + "Svalbard and Jan Mayen", + "Slovakia", + "Sierra Leone", + "San Marino", + "Senegal", + "Somalia", + "Suriname", + "Sao Tome and Principe", + "El Salvador", + "Syrian Arab Republic", + "Swaziland", + "Turks and Caicos Islands", + "Chad", + "French Southern Territories", + "Togo", + "Thailand", + "Tajikistan", + "Tokelau", + "Turkmenistan", + "Tunisia", + "Tonga", + "Timor-Leste", + "Turkey", + "Trinidad and Tobago", + "Tuvalu", + "Taiwan", + "Tanzania, United Republic of", + "Ukraine", + "Uganda", + "United States Minor Outlying Islands", + "United States", + "Uruguay", + "Uzbekistan", + "Holy See (Vatican City State)", + "Saint Vincent and the Grenadines", + "Venezuela", + "Virgin Islands, British", + "Virgin Islands, U.S.", + "Vietnam", + "Vanuatu", + "Wallis and Futuna", + "Samoa", + "Yemen", + "Mayotte", + "Serbia", + "South Africa", + "Zambia", + "Montenegro", + "Zimbabwe", + "Anonymous Proxy", + "Satellite Provider", + "Other", + "Aland Islands", + "Guernsey", + "Isle of Man", + "Jersey", + "Saint Barthelemy", + "Saint Martin", + "Bonaire, Saint Eustatius and Saba", + "South Sudan", + "Other"}; + +const char *GeoIP_country_name[256] = { + "N/A", + "Asia/Pacific Region", + "Europe", + "Andorra", + "United Arab Emirates", + "Afghanistan", + "Antigua and Barbuda", + "Anguilla", + "Albania", + "Armenia", + "Curacao", + "Angola", + "Antarctica", + "Argentina", + "American Samoa", + "Austria", + "Australia", + "Aruba", + "Azerbaijan", + "Bosnia and Herzegovina", + "Barbados", + "Bangladesh", + "Belgium", + "Burkina Faso", + "Bulgaria", + "Bahrain", + "Burundi", + "Benin", + "Bermuda", + "Brunei Darussalam", + "Bolivia", + "Brazil", + "Bahamas", + "Bhutan", + "Bouvet Island", + "Botswana", + "Belarus", + "Belize", + "Canada", + "Cocos (Keeling) Islands", + "Congo, The Democratic Republic of the", + "Central African Republic", + "Congo", + "Switzerland", + "Cote D'Ivoire", + "Cook Islands", + "Chile", + "Cameroon", + "China", + "Colombia", + "Costa Rica", + "Cuba", + "Cape Verde", + "Christmas Island", + "Cyprus", + "Czech Republic", + "Germany", + "Djibouti", + "Denmark", + "Dominica", + "Dominican Republic", + "Algeria", + "Ecuador", + "Estonia", + "Egypt", + "Western Sahara", + "Eritrea", + "Spain", + "Ethiopia", + "Finland", + "Fiji", + "Falkland Islands (Malvinas)", + "Micronesia, Federated States of", + "Faroe Islands", + "France", + "Sint Maarten (Dutch part)", + "Gabon", + "United Kingdom", + "Grenada", + "Georgia", + "French Guiana", + "Ghana", + "Gibraltar", + "Greenland", + "Gambia", + "Guinea", + "Guadeloupe", + "Equatorial Guinea", + "Greece", + "South Georgia and the South Sandwich Islands", + "Guatemala", + "Guam", + "Guinea-Bissau", + "Guyana", + "Hong Kong", + "Heard Island and McDonald Islands", + "Honduras", + "Croatia", + "Haiti", + "Hungary", + "Indonesia", + "Ireland", + "Israel", + "India", + "British Indian Ocean Territory", + "Iraq", + "Iran, Islamic Republic of", + "Iceland", + "Italy", + "Jamaica", + "Jordan", + "Japan", + "Kenya", + "Kyrgyzstan", + "Cambodia", + "Kiribati", + "Comoros", + "Saint Kitts and Nevis", + "Korea, Democratic People's Republic of", + "Korea, Republic of", + "Kuwait", + "Cayman Islands", + "Kazakhstan", + "Lao People's Democratic Republic", + "Lebanon", + "Saint Lucia", + "Liechtenstein", + "Sri Lanka", + "Liberia", + "Lesotho", + "Lithuania", + "Luxembourg", + "Latvia", + "Libya", + "Morocco", + "Monaco", + "Moldova, Republic of", + "Madagascar", + "Marshall Islands", + "Macedonia", + "Mali", + "Myanmar", + "Mongolia", + "Macau", + "Northern Mariana Islands", + "Martinique", + "Mauritania", + "Montserrat", + "Malta", + "Mauritius", + "Maldives", + "Malawi", + "Mexico", + "Malaysia", + "Mozambique", + "Namibia", + "New Caledonia", + "Niger", + "Norfolk Island", + "Nigeria", + "Nicaragua", + "Netherlands", + "Norway", + "Nepal", + "Nauru", + "Niue", + "New Zealand", + "Oman", + "Panama", + "Peru", + "French Polynesia", + "Papua New Guinea", + "Philippines", + "Pakistan", + "Poland", + "Saint Pierre and Miquelon", + "Pitcairn Islands", + "Puerto Rico", + "Palestinian Territory", + "Portugal", + "Palau", + "Paraguay", + "Qatar", + "Reunion", + "Romania", + "Russian Federation", + "Rwanda", + "Saudi Arabia", + "Solomon Islands", + "Seychelles", + "Sudan", + "Sweden", + "Singapore", + "Saint Helena", + "Slovenia", + "Svalbard and Jan Mayen", + "Slovakia", + "Sierra Leone", + "San Marino", + "Senegal", + "Somalia", + "Suriname", + "Sao Tome and Principe", + "El Salvador", + "Syrian Arab Republic", + "Swaziland", + "Turks and Caicos Islands", + "Chad", + "French Southern Territories", + "Togo", + "Thailand", + "Tajikistan", + "Tokelau", + "Turkmenistan", + "Tunisia", + "Tonga", + "Timor-Leste", + "Turkey", + "Trinidad and Tobago", + "Tuvalu", + "Taiwan", + "Tanzania, United Republic of", + "Ukraine", + "Uganda", + "United States Minor Outlying Islands", + "United States", + "Uruguay", + "Uzbekistan", + "Holy See (Vatican City State)", + "Saint Vincent and the Grenadines", + "Venezuela", + "Virgin Islands, British", + "Virgin Islands, U.S.", + "Vietnam", + "Vanuatu", + "Wallis and Futuna", + "Samoa", + "Yemen", + "Mayotte", + "Serbia", + "South Africa", + "Zambia", + "Montenegro", + "Zimbabwe", + "Anonymous Proxy", + "Satellite Provider", + "Other", + "Aland Islands", + "Guernsey", + "Isle of Man", + "Jersey", + "Saint Barthelemy", + "Saint Martin", + "Bonaire, Saint Eustatius and Saba", + "South Sudan", + "Other"}; + +/* Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe, + North America, Oceania + and South America. */ + +const char GeoIP_country_continent[256][3] = { + "--", "AS", "EU", "EU", "AS", "AS", "NA", "NA", "EU", "AS", "NA", "AF", + "AN", "SA", "OC", "EU", "OC", "NA", "AS", "EU", "NA", "AS", "EU", "AF", + "EU", "AS", "AF", "AF", "NA", "AS", "SA", "SA", "NA", "AS", "AN", "AF", + "EU", "NA", "NA", "AS", "AF", "AF", "AF", "EU", "AF", "OC", "SA", "AF", + "AS", "SA", "NA", "NA", "AF", "AS", "AS", "EU", "EU", "AF", "EU", "NA", + "NA", "AF", "SA", "EU", "AF", "AF", "AF", "EU", "AF", "EU", "OC", "SA", + "OC", "EU", "EU", "NA", "AF", "EU", "NA", "AS", "SA", "AF", "EU", "NA", + "AF", "AF", "NA", "AF", "EU", "AN", "NA", "OC", "AF", "SA", "AS", "AN", + "NA", "EU", "NA", "EU", "AS", "EU", "AS", "AS", "AS", "AS", "AS", "EU", + "EU", "NA", "AS", "AS", "AF", "AS", "AS", "OC", "AF", "NA", "AS", "AS", + "AS", "NA", "AS", "AS", "AS", "NA", "EU", "AS", "AF", "AF", "EU", "EU", + "EU", "AF", "AF", "EU", "EU", "AF", "OC", "EU", "AF", "AS", "AS", "AS", + "OC", "NA", "AF", "NA", "EU", "AF", "AS", "AF", "NA", "AS", "AF", "AF", + "OC", "AF", "OC", "AF", "NA", "EU", "EU", "AS", "OC", "OC", "OC", "AS", + "NA", "SA", "OC", "OC", "AS", "AS", "EU", "NA", "OC", "NA", "AS", "EU", + "OC", "SA", "AS", "AF", "EU", "EU", "AF", "AS", "OC", "AF", "AF", "EU", + "AS", "AF", "EU", "EU", "EU", "AF", "EU", "AF", "AF", "SA", "AF", "NA", + "AS", "AF", "NA", "AF", "AN", "AF", "AS", "AS", "OC", "AS", "AF", "OC", + "AS", "EU", "NA", "OC", "AS", "AF", "EU", "AF", "OC", "NA", "SA", "AS", + "EU", "NA", "SA", "NA", "NA", "AS", "OC", "OC", "OC", "AS", "AF", "EU", + "AF", "AF", "EU", "AF", "--", "--", "--", "EU", "EU", "EU", "EU", "NA", + "NA", "NA", "AF", "--"}; + +static const char *get_db_description(int dbtype) { + const char *ptr; + if (dbtype >= NUM_DB_TYPES || dbtype < 0) { + return "Unknown"; + } + ptr = GeoIPDBDescription[dbtype]; + return ptr == NULL ? "Unknown" : ptr; +} + +geoipv6_t _GeoIP_lookupaddress_v6(const char *host); + +#if defined(_WIN32) +/* http://www.mail-archive.com/users@ipv6.org/msg02107.html */ +static const char * +_GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { + if (af == AF_INET) { + struct sockaddr_in in; + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + memcpy(&in.sin_addr, src, sizeof(struct in_addr)); + getnameinfo((struct sockaddr *)&in, + sizeof(struct sockaddr_in), + dst, + cnt, + NULL, + 0, + NI_NUMERICHOST); + return dst; + } else if (af == AF_INET6) { + struct sockaddr_in6 in; + memset(&in, 0, sizeof(in)); + in.sin6_family = AF_INET6; + memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); + getnameinfo((struct sockaddr *)&in, + sizeof(struct sockaddr_in6), + dst, + cnt, + NULL, + 0, + NI_NUMERICHOST); + return dst; + } + return NULL; +} + +static int _GeoIP_inet_pton(int af, const char *src, void *dst) { + struct addrinfo hints, *res, *ressave; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + + if (getaddrinfo(src, NULL, &hints, &res) != 0) { + return -1; + } + + ressave = res; + + while (res) { + memcpy(dst, res->ai_addr, res->ai_addrlen); + res = res->ai_next; + } + + freeaddrinfo(ressave); + return 0; +} +#else +static int _GeoIP_inet_pton(int af, const char *src, void *dst) { + return inet_pton(af, src, dst); +} +static const char * +_GeoIP_inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { + return inet_ntop(af, src, dst, cnt); +} +#endif /* defined(_WIN32) */ + +int __GEOIP_V6_IS_NULL(geoipv6_t v6) { + int i; + for (i = 0; i < 16; i++) { + if (v6.s6_addr[i]) { + return 0; + } + } + return 1; +} + +void __GEOIP_PREPARE_TEREDO(geoipv6_t *v6) { + int i; + if ((v6->s6_addr[0]) != 0x20) { + return; + } + if ((v6->s6_addr[1]) != 0x01) { + return; + } + if ((v6->s6_addr[2]) != 0x00) { + return; + } + if ((v6->s6_addr[3]) != 0x00) { + return; + } + + for (i = 0; i < 12; i++) { + v6->s6_addr[i] = 0; + } + for (; i < 16; i++) { + v6->s6_addr[i] ^= 0xff; + } +} + +const char *GeoIPDBDescription[NUM_DB_TYPES] = { + NULL, + "GeoIP Country Edition", + "GeoIP City Edition, Rev 1", + "GeoIP Region Edition, Rev 1", + "GeoIP ISP Edition", + "GeoIP Organization Edition", + "GeoIP City Edition, Rev 0", + "GeoIP Region Edition, Rev 0", + "GeoIP Proxy Edition", + "GeoIP ASNum Edition", + "GeoIP Netspeed Edition", + "GeoIP Domain Name Edition", + "GeoIP Country V6 Edition", + "GeoIP LocationID ASCII Edition", + "GeoIP Accuracy Radius Edition", + NULL, + NULL, + "GeoIP Large Country Edition", + "GeoIP Large Country V6 Edition", + NULL, + "GeoIP CCM Edition", + "GeoIP ASNum V6 Edition", + "GeoIP ISP V6 Edition", + "GeoIP Organization V6 Edition", + "GeoIP Domain Name V6 Edition", + "GeoIP LocationID ASCII V6 Edition", + "GeoIP Registrar Edition", + "GeoIP Registrar V6 Edition", + "GeoIP UserType Edition", + "GeoIP UserType V6 Edition", + "GeoIP City Edition V6, Rev 1", + "GeoIP City Edition V6, Rev 0", + "GeoIP Netspeed Edition, Rev 1", + "GeoIP Netspeed Edition V6, Rev1", + "GeoIP Country Confidence Edition", + "GeoIP City Confidence Edition", + "GeoIP Region Confidence Edition", + "GeoIP Postal Confidence Edition", + "GeoIP Accuracy Radius Edition V6"}; + +char *GeoIP_custom_directory = NULL; + +void GeoIP_setup_custom_directory(char *dir) { GeoIP_custom_directory = dir; } + +char *_GeoIP_full_path_to(const char *file_name) { + int len; + char *path = malloc(sizeof(char) * 1024); + + if (GeoIP_custom_directory == NULL) { +#if !defined(_WIN32) + memset(path, 0, sizeof(char) * 1024); + snprintf( + path, sizeof(char) * 1024 - 1, "%s/%s", GEOIPDATADIR, file_name); +#else + char buf[MAX_PATH], *p, *q = NULL; + memset(buf, 0, sizeof(buf)); + len = GetModuleFileNameA(GetModuleHandle(NULL), buf, sizeof(buf) - 1); + for (p = buf + len; p > buf; p--) { + if (*p == '\\') { + if (!q) { + q = p; + } else { + *p = '/'; + } + } + } + *q = 0; + memset(path, 0, sizeof(char) * 1024); + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name); +#endif + } else { + len = strlen(GeoIP_custom_directory); + if (GeoIP_custom_directory[len - 1] != '/') { + snprintf(path, + sizeof(char) * 1024 - 1, + "%s/%s", + GeoIP_custom_directory, + file_name); + } else { + snprintf(path, + sizeof(char) * 1024 - 1, + "%s%s", + GeoIP_custom_directory, + file_name); + } + } + return path; +} + +char **GeoIPDBFileName = NULL; + +void _GeoIP_setup_dbfilename(void) { + if (NULL == GeoIPDBFileName) { + GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES); + memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES); + + GeoIPDBFileName[GEOIP_COUNTRY_EDITION] = + _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV0] = + _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV1] = + _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0] = + _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1] = + _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION] = + _GeoIP_full_path_to("GeoIPISP.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION] = + _GeoIP_full_path_to("GeoIPOrg.dat"); + GeoIPDBFileName[GEOIP_PROXY_EDITION] = + _GeoIP_full_path_to("GeoIPProxy.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION] = + _GeoIP_full_path_to("GeoIPASNum.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION] = + _GeoIP_full_path_to("GeoIPNetSpeed.dat"); + GeoIPDBFileName[GEOIP_DOMAIN_EDITION] = + _GeoIP_full_path_to("GeoIPDomain.dat"); + GeoIPDBFileName[GEOIP_COUNTRY_EDITION_V6] = + _GeoIP_full_path_to("GeoIPv6.dat"); + GeoIPDBFileName[GEOIP_LOCATIONA_EDITION] = + _GeoIP_full_path_to("GeoIPLocA.dat"); + GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION] = + _GeoIP_full_path_to("GeoIPDistance.dat"); + GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION] = + _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_LARGE_COUNTRY_EDITION_V6] = + _GeoIP_full_path_to("GeoIPv6.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION_V6] = + _GeoIP_full_path_to("GeoIPASNumv6.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION_V6] = + _GeoIP_full_path_to("GeoIPISPv6.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION_V6] = + _GeoIP_full_path_to("GeoIPOrgv6.dat"); + GeoIPDBFileName[GEOIP_DOMAIN_EDITION_V6] = + _GeoIP_full_path_to("GeoIPDomainv6.dat"); + GeoIPDBFileName[GEOIP_LOCATIONA_EDITION_V6] = + _GeoIP_full_path_to("GeoIPLocAv6.dat"); + GeoIPDBFileName[GEOIP_REGISTRAR_EDITION] = + _GeoIP_full_path_to("GeoIPRegistrar.dat"); + GeoIPDBFileName[GEOIP_REGISTRAR_EDITION_V6] = + _GeoIP_full_path_to("GeoIPRegistrarv6.dat"); + GeoIPDBFileName[GEOIP_USERTYPE_EDITION] = + _GeoIP_full_path_to("GeoIPUserType.dat"); + GeoIPDBFileName[GEOIP_USERTYPE_EDITION_V6] = + _GeoIP_full_path_to("GeoIPUserTypev6.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0_V6] = + _GeoIP_full_path_to("GeoIPCityv6.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1_V6] = + _GeoIP_full_path_to("GeoIPCityv6.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1] = + _GeoIP_full_path_to("GeoIPNetSpeedCell.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1_V6] = + _GeoIP_full_path_to("GeoIPNetSpeedCellv6.dat"); + GeoIPDBFileName[GEOIP_COUNTRYCONF_EDITION] = + _GeoIP_full_path_to("GeoIPCountryConf.dat"); + GeoIPDBFileName[GEOIP_CITYCONF_EDITION] = + _GeoIP_full_path_to("GeoIPCityConf.dat"); + GeoIPDBFileName[GEOIP_REGIONCONF_EDITION] = + _GeoIP_full_path_to("GeoIPRegionConf.dat"); + GeoIPDBFileName[GEOIP_POSTALCONF_EDITION] = + _GeoIP_full_path_to("GeoIPPostalConf.dat"); + GeoIPDBFileName[GEOIP_ACCURACYRADIUS_EDITION_V6] = + _GeoIP_full_path_to("GeoIPDistancev6.dat"); + } +} + +static int _file_exists(const char *file_name) { + struct stat file_stat; + return (stat(file_name, &file_stat) == 0) ? 1 : 0; +} + +char *_GeoIP_iso_8859_1__utf8(const char *iso) { + signed char c; + char k; + char *p; + char *t = (char *)iso; + int len = 0; + while ((c = *t++)) { + if (c < 0) { + len++; + } + } + len += t - iso; + t = p = malloc(len); + + if (p) { + while ((c = *iso++)) { + if (c < 0) { + k = (char)0xc2; + if (c >= -64) { + k++; + } + *t++ = k; + c &= ~0x40; + } + *t++ = c; + } + *t++ = 0x00; + } + return p; +} + +int GeoIP_is_private_ipnum_v4(unsigned long ipnum) { + return ((ipnum >= 167772160U && ipnum <= 184549375U) || + (ipnum >= 2851995648U && ipnum <= 2852061183U) || + (ipnum >= 2886729728U && ipnum <= 2887778303U) || + (ipnum >= 3232235520U && ipnum <= 3232301055U) || + (ipnum >= 2130706432U && ipnum <= 2147483647U)) + ? 1 + : 0; +} + +int GeoIP_is_private_v4(const char *addr) { + unsigned long ipnum = GeoIP_addr_to_num(addr); + return GeoIP_is_private_ipnum_v4(ipnum); +} + +int GeoIP_db_avail(int type) { + const char *filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + return 0; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (NULL == filePath) { + return 0; + } + return _file_exists(filePath); +} + +static int _database_has_content(int database_type) { + return (database_type != GEOIP_COUNTRY_EDITION && + database_type != GEOIP_PROXY_EDITION && + database_type != GEOIP_NETSPEED_EDITION && + database_type != GEOIP_COUNTRY_EDITION_V6 && + database_type != GEOIP_LARGE_COUNTRY_EDITION && + database_type != GEOIP_LARGE_COUNTRY_EDITION_V6 && + database_type != GEOIP_REGION_EDITION_REV0 && + database_type != GEOIP_REGION_EDITION_REV1) + ? 1 + : 0; +} + +static ssize_t get_index_size(GeoIP *gi, struct stat *buf) { + ssize_t index_size; + unsigned int segment; + + if (!_database_has_content(gi->databaseType)) { + return buf->st_size; + } + + segment = gi->databaseSegments[0]; + index_size = segment * (ssize_t)gi->record_length * 2; + + /* check for overflow in multiplication */ + if (segment != 0 && + index_size / segment != (ssize_t)gi->record_length * 2) { + return -1; + } + + /* Index size should never exceed the size of the file */ + if (index_size > buf->st_size) { + return -1; + } + + return index_size; +} + +static void _setup_segments(GeoIP *gi) { + int i, j, segment_record_length; + unsigned char delim[3]; + unsigned char buf[LARGE_SEGMENT_RECORD_LENGTH]; + off_t offset = gi->size - 3; + int fno = fileno(gi->GeoIPDatabase); + + gi->databaseSegments = NULL; + + /* default to GeoIP Country Edition */ + gi->databaseType = GEOIP_COUNTRY_EDITION; + gi->record_length = STANDARD_RECORD_LENGTH; + + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + if (pread(fno, delim, 3, offset) != 3) { + return; + } + offset += 3; + if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { + if (pread(fno, &gi->databaseType, 1, offset) != 1) { + return; + } + offset++; + if (gi->databaseType >= 106) { + /* backwards compatibility with databases from April 2003 and + * earlier */ + gi->databaseType -= 105; + } + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = STATE_BEGIN_REV0; + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = STATE_BEGIN_REV1; + } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 || + gi->databaseType == GEOIP_CITY_EDITION_REV1 || + gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ORG_EDITION_V6 || + gi->databaseType == GEOIP_DOMAIN_EDITION || + gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ISP_EDITION_V6 || + gi->databaseType == GEOIP_REGISTRAR_EDITION || + gi->databaseType == GEOIP_REGISTRAR_EDITION_V6 || + gi->databaseType == GEOIP_USERTYPE_EDITION || + gi->databaseType == GEOIP_USERTYPE_EDITION_V6 || + gi->databaseType == GEOIP_ASNUM_EDITION || + gi->databaseType == GEOIP_ASNUM_EDITION_V6 || + gi->databaseType == GEOIP_NETSPEED_EDITION_REV1 || + gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6 || + gi->databaseType == GEOIP_LOCATIONA_EDITION || + gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION || + gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION_V6 || + gi->databaseType == GEOIP_CITY_EDITION_REV0_V6 || + gi->databaseType == GEOIP_CITY_EDITION_REV1_V6 || + gi->databaseType == GEOIP_CITYCONF_EDITION || + gi->databaseType == GEOIP_COUNTRYCONF_EDITION || + gi->databaseType == GEOIP_REGIONCONF_EDITION || + gi->databaseType == GEOIP_POSTALCONF_EDITION) { + /* City/Org Editions have two segments, read offset of second + * segment */ + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = 0; + segment_record_length = SEGMENT_RECORD_LENGTH; + + if (pread(fno, buf, segment_record_length, offset) != + segment_record_length) { + free(gi->databaseSegments); + gi->databaseSegments = NULL; + return; + } + + for (j = 0; j < segment_record_length; j++) { + gi->databaseSegments[0] += (buf[j] << (j * 8)); + } + + /* the record_length must be correct from here on */ + if (gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ORG_EDITION_V6 || + gi->databaseType == GEOIP_DOMAIN_EDITION || + gi->databaseType == GEOIP_DOMAIN_EDITION_V6 || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ISP_EDITION_V6) { + gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + offset -= 4; + if (offset < 0) { + gi->databaseSegments = NULL; + return; + } + } + } + if (gi->databaseType == GEOIP_COUNTRY_EDITION || + gi->databaseType == GEOIP_PROXY_EDITION || + gi->databaseType == GEOIP_NETSPEED_EDITION || + gi->databaseType == GEOIP_COUNTRY_EDITION_V6) { + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = COUNTRY_BEGIN; + } else if (gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION || + gi->databaseType == GEOIP_LARGE_COUNTRY_EDITION_V6) { + gi->databaseSegments = malloc(sizeof(unsigned int)); + if (gi->databaseSegments == NULL) { + return; + } + gi->databaseSegments[0] = LARGE_COUNTRY_BEGIN; + } +} + +static void _check_mtime(GeoIP *gi) { + struct stat buf; + ssize_t idx_size; + +#if !defined(_WIN32) + struct timeval t; +#else /* !defined(_WIN32) */ + FILETIME ft; + ULONGLONG t; +#endif /* !defined(_WIN32) */ + + if (gi->flags & GEOIP_CHECK_CACHE) { + +#if !defined(_WIN32) + /* stat only has second granularity, so don't + * call it more than once a second */ + if (0 != gettimeofday(&t, NULL)) { + DEBUG_MSGF( + gi->flags, "Error calling gettimeofday: %s\n", strerror(errno)); + return; + } + + if (t.tv_sec == gi->last_mtime_check) { + return; + } + gi->last_mtime_check = t.tv_sec; + +#else /* !defined(_WIN32) */ + + /* stat only has second granularity, so don't + call it more than once a second */ + GetSystemTimeAsFileTime(&ft); + t = FILETIME_TO_USEC(ft) / 1000 / 1000; + if (t == gi->last_mtime_check) { + return; + } + gi->last_mtime_check = t; + +#endif /* !defined(_WIN32) */ + + if (stat(gi->file_path, &buf) != -1) { + /* make sure that the database file is at least 60 + * seconds untouched. Otherwise we might load the + * database only partly and crash + */ + if (buf.st_mtime != gi->mtime && + (buf.st_mtime + 60 < gi->last_mtime_check)) { + /* GeoIP Database file updated */ + if (gi->flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) { + if (gi->cache && (gi->flags & GEOIP_MMAP_CACHE)) { +#if !defined(_WIN32) + /* MMAP is only avail on UNIX */ + munmap(gi->cache, gi->size); + gi->cache = NULL; +#endif + } else { + /* reload database into memory cache */ + if ((gi->cache = (unsigned char *)realloc( + gi->cache, buf.st_size)) == NULL) { + DEBUG_MSGF(gi->flags, + "Out of memory when reloading %s\n", + gi->file_path); + return; + } + } + } + /* refresh filehandle */ + fclose(gi->GeoIPDatabase); + gi->GeoIPDatabase = fopen(gi->file_path, "rb"); + if (gi->GeoIPDatabase == NULL) { + DEBUG_MSGF(gi->flags, + "Error Opening file %s when reloading\n", + gi->file_path); + return; + } + gi->mtime = buf.st_mtime; + gi->size = buf.st_size; + + if (gi->flags & GEOIP_MMAP_CACHE) { +#if defined(_WIN32) + DEBUG_MSGF(gi->flags, + "GEOIP_MMAP_CACHE is not supported on WIN32\n"); + gi->cache = 0; + return; +#else + gi->cache = mmap(NULL, + buf.st_size, + PROT_READ, + MAP_PRIVATE, + fileno(gi->GeoIPDatabase), + 0); + if (gi->cache == MAP_FAILED) { + + DEBUG_MSGF(gi->flags, + "Error remapping file %s when reloading\n", + gi->file_path); + + gi->cache = NULL; + return; + } +#endif + } else if (gi->flags & GEOIP_MEMORY_CACHE) { + if (pread(fileno(gi->GeoIPDatabase), + gi->cache, + buf.st_size, + 0) != (ssize_t)buf.st_size) { + DEBUG_MSGF(gi->flags, + "Error reading file %s when reloading\n", + gi->file_path); + return; + } + } + + if (gi->databaseSegments != NULL) { + free(gi->databaseSegments); + gi->databaseSegments = NULL; + } + _setup_segments(gi); + if (gi->databaseSegments == NULL) { + DEBUG_MSGF(gi->flags, + "Error reading file %s -- corrupt\n", + gi->file_path); + return; + } + + idx_size = get_index_size(gi, &buf); + if (idx_size < 0) { + DEBUG_MSGF( + gi->flags, "Error file %s -- corrupt\n", gi->file_path); + return; + } + + if (gi->flags & GEOIP_INDEX_CACHE) { + gi->index_cache = (unsigned char *)realloc( + gi->index_cache, sizeof(unsigned char) * idx_size); + if (gi->index_cache != NULL) { + if (pread(fileno(gi->GeoIPDatabase), + gi->index_cache, + idx_size, + 0) != idx_size) { + DEBUG_MSGF( + gi->flags, + "Error reading file %s where reloading\n", + gi->file_path); + return; + } + } + } + } + } + } + return; +} + +#define ADDR_STR_LEN (8 * 4 + 7 + 1) +unsigned int +_GeoIP_seek_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int depth; + char paddr[ADDR_STR_LEN]; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + + const unsigned char *p; + int j; + int fno = fileno(gi->GeoIPDatabase); + + unsigned int record_pair_length = gi->record_length * 2; + + _check_mtime(gi); + if (GeoIP_teredo(gi)) { + __GEOIP_PREPARE_TEREDO(&ipnum); + } + for (depth = 127; depth >= 0; depth--) { + unsigned int byte_offset = record_pair_length * offset; + if (byte_offset > gi->size - record_pair_length) { + /* The pointer is invalid */ + break; + } + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + if (pread( + fno, stack_buffer, record_pair_length, (long)byte_offset) != + record_pair_length) { + break; + } + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)byte_offset; + } else { + buf = gi->index_cache + (long)byte_offset; + } + + if (GEOIP_CHKBIT_V6(depth, ipnum.s6_addr)) { + /* Take the right-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 1 + 0] << (0 * 8)) + (buf[3 * 1 + 1] << (1 * 8)) + + (buf[3 * 1 + 2] << (2 * 8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + + } else { + /* Take the left-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 0 + 0] << (0 * 8)) + (buf[3 * 0 + 1] << (1 * 8)) + + (buf[3 * 0 + 2] << (2 * 8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + } + + if (x >= gi->databaseSegments[0]) { + gi->netmask = gl->netmask = 128 - depth; + return x; + } + offset = x; + } + + /* shouldn't reach here */ + _GeoIP_inet_ntop(AF_INET6, &ipnum.s6_addr[0], paddr, ADDR_STR_LEN); + DEBUG_MSGF(gi->flags, + "Error Traversing Database for ipnum = %s - Perhaps database is " + "corrupt?\n", + paddr); + return 0; +} + +geoipv6_t _GeoIP_addr_to_num_v6(const char *addr) { + geoipv6_t ipnum; + if (1 == _GeoIP_inet_pton(AF_INET6, addr, &ipnum.s6_addr[0])) { + return ipnum; + } + return IPV6_NULL; +} + +unsigned int +_GeoIP_seek_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + int depth; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + + const unsigned char *p; + int j; + int fno = fileno(gi->GeoIPDatabase); + + unsigned int record_pair_length = gi->record_length * 2; + + _check_mtime(gi); + for (depth = 31; depth >= 0; depth--) { + unsigned int byte_offset = record_pair_length * offset; + if (byte_offset > gi->size - record_pair_length) { + /* The pointer is invalid */ + break; + } + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + if (pread(fno, stack_buffer, record_pair_length, byte_offset) != + record_pair_length) { + break; + } + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)byte_offset; + } else { + buf = gi->index_cache + (long)byte_offset; + } + + if (ipnum & (1 << depth)) { + /* Take the right-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 1 + 0] << (0 * 8)) + (buf[3 * 1 + 1] << (1 * 8)) + + (buf[3 * 1 + 2] << (2 * 8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + + } else { + /* Take the left-hand branch */ + if (gi->record_length == 3) { + /* Most common case is completely unrolled and uses constants. + */ + x = (buf[3 * 0 + 0] << (0 * 8)) + (buf[3 * 0 + 1] << (1 * 8)) + + (buf[3 * 0 + 2] << (2 * 8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1 * j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while (--j); + } + } + + if (x >= gi->databaseSegments[0]) { + gi->netmask = gl->netmask = 32 - depth; + return x; + } + offset = x; + } + /* shouldn't reach here */ + DEBUG_MSGF(gi->flags, + "Error Traversing Database for ipnum = %lu - Perhaps database " + "is corrupt?\n", + ipnum); + return 0; +} + +unsigned long GeoIP_addr_to_num(const char *addr) { + unsigned int c, octet, t; + unsigned long ipnum; + int i = 3; + + octet = ipnum = 0; + while ((c = *addr++)) { + if (c == '.') { + if (octet > 255) { + return 0; + } + ipnum <<= 8; + ipnum += octet; + i--; + octet = 0; + } else { + t = octet; + octet <<= 3; + octet += t; + octet += t; + c -= '0'; + if (c > 9) { + return 0; + } + octet += c; + } + } + if ((octet > 255) || (i != 0)) { + return 0; + } + ipnum <<= 8; + return ipnum + octet; +} + +GeoIP *GeoIP_open_type(int type, int flags) { + GeoIP *gi; + const char *filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + printf("Invalid database type %d\n", type); + return NULL; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (filePath == NULL) { + printf("Invalid database type %d\n", type); + return NULL; + } + gi = GeoIP_open(filePath, flags); + + if (gi) { + /* make sure this is the requested database type */ + int database_type = gi->databaseType; + if (database_type > 105) { + database_type -= 105; + } + /* type must match, but we accept org and asnum, + * since domain and *conf database have always the wrong type + * for historical reason. Maybe we fix it at some point. + */ + if (database_type == type || database_type == GEOIP_ASNUM_EDITION || + database_type == GEOIP_ORG_EDITION) { + return gi; + } + GeoIP_delete(gi); + } + + return NULL; +} + +GeoIP *GeoIP_new(int flags) { + GeoIP *gi; + _GeoIP_setup_dbfilename(); + gi = GeoIP_open(GeoIPDBFileName[GEOIP_COUNTRY_EDITION], flags); + return gi; +} + +GeoIP *GeoIP_open(const char *filename, int flags) { + struct stat buf; + ssize_t idx_size; + GeoIP *gi; + size_t len; + + gi = (GeoIP *)calloc(1, sizeof(GeoIP)); + if (gi == NULL) { + return NULL; + } + len = sizeof(char) * (strlen(filename) + 1); + gi->file_path = malloc(len); + if (gi->file_path == NULL) { + free(gi); + return NULL; + } + strncpy(gi->file_path, filename, len); + gi->GeoIPDatabase = fopen(filename, "rb"); + if (gi->GeoIPDatabase == NULL) { + DEBUG_MSGF(flags, "Error Opening file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + DEBUG_MSGF(flags, "Error stating file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + + gi->size = buf.st_size; + if (flags & (GEOIP_MEMORY_CACHE | GEOIP_MMAP_CACHE)) { + gi->mtime = buf.st_mtime; + + /* MMAP added my Peter Shipley */ + if (flags & GEOIP_MMAP_CACHE) { +#if !defined(_WIN32) + gi->cache = mmap(NULL, + buf.st_size, + PROT_READ, + MAP_PRIVATE, + fileno(gi->GeoIPDatabase), + 0); + if (gi->cache == MAP_FAILED) { + DEBUG_MSGF(flags, "Error mmaping file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } +#endif + } else { + gi->cache = + (unsigned char *)malloc(sizeof(unsigned char) * buf.st_size); + + if (gi->cache != NULL) { + if (pread( + fileno(gi->GeoIPDatabase), gi->cache, buf.st_size, 0) != + (ssize_t)buf.st_size) { + DEBUG_MSGF(flags, "Error reading file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + } + } + } else { + if (flags & GEOIP_CHECK_CACHE) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + DEBUG_MSGF(flags, "Error stating file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + gi->mtime = buf.st_mtime; + } + gi->cache = NULL; + } + gi->flags = flags; + gi->charset = GEOIP_CHARSET_ISO_8859_1; + gi->ext_flags = 1U << GEOIP_TEREDO_BIT; + _setup_segments(gi); + if (gi->databaseSegments == NULL) { + DEBUG_MSGF( + gi->flags, "Error reading file %s -- corrupt\n", gi->file_path); + GeoIP_delete(gi); + return NULL; + } + + idx_size = get_index_size(gi, &buf); + + if (idx_size < 0) { + DEBUG_MSGF(gi->flags, "Error file %s -- corrupt\n", gi->file_path); + GeoIP_delete(gi); + return NULL; + } + + if (flags & GEOIP_INDEX_CACHE) { + gi->index_cache = + (unsigned char *)malloc(sizeof(unsigned char) * idx_size); + if (gi->index_cache != NULL) { + if (pread( + fileno(gi->GeoIPDatabase), gi->index_cache, idx_size, 0) != + idx_size) { + DEBUG_MSGF(gi->flags, "Error reading file %s\n", filename); + GeoIP_delete(gi); + return NULL; + } + } + } else { + gi->index_cache = NULL; + } + + gi->last_mtime_check = 0; + + return gi; +} + +void GeoIP_delete(GeoIP *gi) { + if (gi == NULL) { + return; + } + if (gi->GeoIPDatabase != NULL) { + fclose(gi->GeoIPDatabase); + } + if (gi->cache != NULL) { + if (gi->flags & GEOIP_MMAP_CACHE) { +#if !defined(_WIN32) + if (gi->cache) { + munmap(gi->cache, gi->size); + } +#endif + } else { + free(gi->cache); + } + gi->cache = NULL; + } + free(gi->index_cache); + free(gi->file_path); + free(gi->databaseSegments); + free(gi); +} + +const char * +GeoIP_country_code_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char *GeoIP_country_code3_by_name_v6_gl(GeoIP *gi, + const char *name, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code3_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_gl(gi, name, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_v6_gl(gi, name, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char * +GeoIP_country_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_name_gl(gi, name, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +unsigned long _GeoIP_lookupaddress(const char *host) { + unsigned long addr = inet_addr(host); + struct hostent phe2; + struct hostent *phe = &phe2; + char *buf = NULL; +#ifdef HAVE_GETHOSTBYNAME_R + int buflength = 16384; + int herr = 0; +#endif + int result = 0; +#ifdef HAVE_GETHOSTBYNAME_R + buf = malloc(buflength); +#endif + if (addr == INADDR_NONE) { +#ifdef HAVE_GETHOSTBYNAME_R + while (1) { +/* we use gethostbyname_r here because it is thread-safe and gethostbyname is + * not */ +#ifdef GETHOSTBYNAME_R_RETURNS_INT + result = gethostbyname_r(host, &phe2, buf, buflength, &phe, &herr); +#else + phe = gethostbyname_r(host, &phe2, buf, buflength, &herr); +#endif + if (herr != ERANGE) { + break; + } + if (result == 0) { + break; + } + /* double the buffer if the buffer is too small */ + buflength = buflength * 2; + buf = realloc(buf, buflength); + } +#else + /* Some systems do not support gethostbyname_r, such as Mac OS X */ + phe = gethostbyname(host); +#endif + if (!phe || result != 0) { + free(buf); + return 0; + } +#if !defined(_WIN32) + addr = *((in_addr_t *)phe->h_addr_list[0]); +#else + addr = ((IN_ADDR *)phe->h_addr_list[0])->S_un.S_addr; +#endif + } +#ifdef HAVE_GETHOSTBYNAME_R + free(buf); +#endif + return ntohl(addr); +} + +geoipv6_t _GeoIP_lookupaddress_v6(const char *host) { + geoipv6_t ipnum; + int gaierr; + struct addrinfo hints, *aifirst; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + /* hints.ai_flags = AI_V4MAPPED; */ + hints.ai_socktype = SOCK_STREAM; + + if ((gaierr = getaddrinfo(host, NULL, &hints, &aifirst)) != 0) { + /* DEBUG_MSGF("Err: %s (%d %s)\n", host, gaierr, gai_strerror(gaierr)); + */ + return IPV6_NULL; + } + memcpy(ipnum.s6_addr, + ((struct sockaddr_in6 *)aifirst->ai_addr)->sin6_addr.s6_addr, + sizeof(geoipv6_t)); + freeaddrinfo(aifirst); + /* inet_pton(AF_INET6, host, ipnum.s6_addr); */ + + return ipnum; +} + +int GeoIP_id_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + unsigned long ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION)); + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) { + return 0; + } + ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + geoipv6_t ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6 && + gi->databaseType != GEOIP_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION_V6)); + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) { + return 0; + } + + ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +const char * +GeoIP_country_code_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} +const char *GeoIP_country_code3_by_addr_v6_gl(GeoIP *gi, + const char *addr, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code3_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_gl(gi, addr, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_v6_gl(gi, addr, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char * +GeoIP_country_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_addr_gl(gi, addr, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char *GeoIP_country_name_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char * +GeoIP_country_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); + return GeoIP_country_name_by_id(gi, country_id); +} + +const char *GeoIP_country_code_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char * +GeoIP_country_code_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code_by_id(country_id) : NULL; +} + +const char *GeoIP_country_code3_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +const char *GeoIP_country_code3_by_ipnum_v6_gl(GeoIP *gi, + geoipv6_t ipnum, + GeoIPLookup *gl) { + int country_id; + country_id = GeoIP_id_by_ipnum_v6_gl(gi, ipnum, gl); + return (country_id > 0) ? GeoIP_code3_by_id(country_id) : NULL; +} + +int GeoIP_country_id_by_addr_v6_gl(GeoIP *gi, + const char *addr, + GeoIPLookup *gl) { + return GeoIP_id_by_addr_v6_gl(gi, addr, gl); +} + +int GeoIP_country_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + return GeoIP_id_by_addr_gl(gi, addr, gl); +} + +int GeoIP_country_id_by_name_v6_gl(GeoIP *gi, + const char *host, + GeoIPLookup *gl) { + return GeoIP_id_by_name_v6_gl(gi, host, gl); +} + +int GeoIP_country_id_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl) { + return GeoIP_id_by_name_gl(gi, host, gl); +} + +int GeoIP_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + geoipv6_t ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION_V6)); + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION)); + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + int ret; + if (gi->databaseType != GEOIP_COUNTRY_EDITION_V6 && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION_V6)); + return 0; + } + ret = _GeoIP_seek_record_v6_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +int GeoIP_id_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + int ret; + if (ipnum == 0) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_LARGE_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_COUNTRY_EDITION)); + return 0; + } + ret = _GeoIP_seek_record_gl(gi, ipnum, gl) - gi->databaseSegments[0]; + return ret; +} + +char *GeoIP_database_info(GeoIP *gi) { + int i; + unsigned char buf[3]; + char *retval; + int has_structure_info = 0; + off_t offset = gi->size - 3; + int fno; + + if (gi == NULL) { + return NULL; + } + + fno = fileno(gi->GeoIPDatabase); + + _check_mtime(gi); + + /* first get past the database structure information */ + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + if (pread(fno, buf, 3, offset) != 3) { + return NULL; + } + offset += 3; + if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) { + has_structure_info = 1; + break; + } + offset -= 4; + if (offset < 0) { + return NULL; + } + } + if (has_structure_info) { + offset -= 6; + if (offset < 0) { + return NULL; + } + } else { + /* no structure info, must be pre Sep 2002 database, go back to end */ + offset = gi->size - 3; + if (offset < 0) { + return NULL; + } + } + + for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) { + if (pread(fno, buf, 3, offset) != 3) { + return NULL; + } + offset += 3; + if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) { + retval = malloc(sizeof(char) * (i + 1)); + if (retval == NULL) { + return NULL; + } + if (pread(fno, retval, i, offset) != i) { + return NULL; + } + retval[i] = '\0'; + return retval; + } + offset -= 4; + if (offset < 0) { + return NULL; + } + } + return NULL; +} + +/* GeoIP Region Edition functions */ + +void GeoIP_assign_region_by_inetaddr_gl(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *region, + GeoIPLookup *gl) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record_gl(gi, ntohl(inetaddr), gl); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - 1000) / 26 + 65); + region->region[1] = (char)((seek_region - 1000) % 26 + 65); + } else { + const char *code = GeoIP_code_by_id(seek_region); + if (code != NULL) { + memcpy(region->country_code, code, 2); + } + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - US_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - US_OFFSET) % 26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char)((seek_region - CANADA_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - CANADA_OFFSET) % 26 + 65); + } else { + /* Not US or Canada ( cc_id is always cc_id * FIPS_RANGE ) */ + const char *code = + GeoIP_code_by_id((seek_region - WORLD_OFFSET) / FIPS_RANGE); + if (code != NULL) { + /* coverity[dont_call] */ + memcpy(region->country_code, code, 2); + } + } + } +} + +void GeoIP_assign_region_by_inetaddr_v6_gl(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *region, + GeoIPLookup *gl) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record_v6_gl(gi, inetaddr, gl); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - 1000) / 26 + 65); + region->region[1] = (char)((seek_region - 1000) % 26 + 65); + } else { + const char *code = GeoIP_code_by_id(seek_region); + if (code != NULL) { + /* coverity[dont_call] */ + memcpy(region->country_code, code, 2); + } + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char)((seek_region - US_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - US_OFFSET) % 26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char)((seek_region - CANADA_OFFSET) / 26 + 65); + region->region[1] = (char)((seek_region - CANADA_OFFSET) % 26 + 65); + } else { + /* Not US or Canada ( cc_id is always cc_id * FIPS_RANGE ) */ + const char *code = + GeoIP_code_by_id((seek_region - WORLD_OFFSET) / FIPS_RANGE); + if (code != NULL) { + /* coverity[dont_call] */ + memcpy(region->country_code, code, 2); + } + } + } +} + +static GeoIPRegion * +_get_region_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + GeoIPRegion *region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr_gl(gi, htonl(ipnum), region, gl); + } + return region; +} + +static GeoIPRegion * +_get_region_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + GeoIPRegion *region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr_v6_gl(gi, ipnum, region, gl); + } + return region; +} + +GeoIPRegion * +GeoIP_region_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + if (addr == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_region_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (addr == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_region_v6_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + unsigned long ipnum; + if (name == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) { + return NULL; + } + return _get_region_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (name == NULL) { + return NULL; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) { + return NULL; + } + return _get_region_v6_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + return _get_region_gl(gi, ipnum, gl); +} + +GeoIPRegion * +GeoIP_region_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_REGION_EDITION_REV1)); + return NULL; + } + return _get_region_v6_gl(gi, ipnum, gl); +} + +void GeoIPRegion_delete(GeoIPRegion *gir) { free(gir); } + +/* GeoIP Organization, ISP and AS Number Edition private method */ +static char *_get_name_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + unsigned int seek_org; + char buf[MAX_ORG_RECORD_LENGTH]; + char *org_buf, *buf_pointer; + int record_pointer; + size_t len; + + if (gi->databaseType != GEOIP_ORG_EDITION && + gi->databaseType != GEOIP_ISP_EDITION && + gi->databaseType != GEOIP_DOMAIN_EDITION && + gi->databaseType != GEOIP_ASNUM_EDITION && + gi->databaseType != GEOIP_ACCURACYRADIUS_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION_REV1 && + gi->databaseType != GEOIP_USERTYPE_EDITION && + gi->databaseType != GEOIP_REGISTRAR_EDITION && + gi->databaseType != GEOIP_LOCATIONA_EDITION && + gi->databaseType != GEOIP_CITYCONF_EDITION && + gi->databaseType != GEOIP_COUNTRYCONF_EDITION && + gi->databaseType != GEOIP_REGIONCONF_EDITION && + gi->databaseType != GEOIP_POSTALCONF_EDITION) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_ORG_EDITION)); + return NULL; + } + + seek_org = _GeoIP_seek_record_gl(gi, ipnum, gl); + if (seek_org == gi->databaseSegments[0]) { + return NULL; + } + + record_pointer = + seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + if (pread(fileno(gi->GeoIPDatabase), + buf, + MAX_ORG_RECORD_LENGTH, + record_pointer) == -1) { + return NULL; + } + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf); + } else { + len = sizeof(char) * (strlen(buf) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf, len); + } + } else { + buf_pointer = (char *)(gi->cache + (long)record_pointer); + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf_pointer); + } else { + len = sizeof(char) * (strlen(buf_pointer) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf_pointer, len); + } + } + return org_buf; +} + +static char *_get_name_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + unsigned int seek_org; + char buf[MAX_ORG_RECORD_LENGTH + 1]; + char *org_buf, *buf_pointer; + int record_pointer; + size_t len; + + if (gi->databaseType != GEOIP_ORG_EDITION_V6 && + gi->databaseType != GEOIP_ISP_EDITION_V6 && + gi->databaseType != GEOIP_DOMAIN_EDITION_V6 && + gi->databaseType != GEOIP_ASNUM_EDITION_V6 && + gi->databaseType != GEOIP_ACCURACYRADIUS_EDITION_V6 && + gi->databaseType != GEOIP_NETSPEED_EDITION_REV1_V6 && + gi->databaseType != GEOIP_USERTYPE_EDITION_V6 && + gi->databaseType != GEOIP_REGISTRAR_EDITION_V6 && + gi->databaseType != GEOIP_LOCATIONA_EDITION_V6) { + printf("Invalid database type %s, expected %s\n", + get_db_description(gi->databaseType), + get_db_description(GEOIP_ORG_EDITION)); + return NULL; + } + + seek_org = _GeoIP_seek_record_v6_gl(gi, ipnum, gl); + if (seek_org == gi->databaseSegments[0]) { + return NULL; + } + + record_pointer = + seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + if (pread(fileno(gi->GeoIPDatabase), + buf, + MAX_ORG_RECORD_LENGTH, + record_pointer) == -1) { + return NULL; + } + buf[MAX_ORG_RECORD_LENGTH] = 0; + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf); + } else { + len = sizeof(char) * (strlen(buf) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf, len); + } + } else { + buf_pointer = (char *)(gi->cache + (long)record_pointer); + if (gi->charset == GEOIP_CHARSET_UTF8) { + org_buf = _GeoIP_iso_8859_1__utf8((const char *)buf_pointer); + } else { + len = sizeof(char) * (strlen(buf_pointer) + 1); + org_buf = malloc(len); + strncpy(org_buf, buf_pointer, len); + } + } + return org_buf; +} + +char *GeoIP_num_to_addr(unsigned long ipnum) { + char *ret_str; + char *cur_str; + int octet[4]; + int num_chars_written, i; + + ret_str = malloc(sizeof(char) * 16); + cur_str = ret_str; + + for (i = 0; i < 4; i++) { + octet[3 - i] = ipnum % 256; + ipnum >>= 8; + } + + for (i = 0; i < 4; i++) { + num_chars_written = sprintf(cur_str, "%d", octet[i]); + cur_str += num_chars_written; + + if (i < 3) { + cur_str[0] = '.'; + cur_str++; + } + } + + return ret_str; +} + +char **GeoIP_range_by_ip_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + unsigned long left_seek; + unsigned long right_seek; + unsigned long mask; + int orig_netmask; + unsigned int target_value; + char **ret; + GeoIPLookup t; + + if (addr == NULL) { + return NULL; + } + + ret = malloc(sizeof(char *) * 2); + + ipnum = GeoIP_addr_to_num(addr); + target_value = _GeoIP_seek_record_gl(gi, ipnum, gl); + orig_netmask = gl->netmask; + mask = 0xffffffff << (32 - orig_netmask); + left_seek = ipnum & mask; + right_seek = left_seek + (0xffffffff & ~mask); + + while (left_seek != 0 && + target_value == _GeoIP_seek_record_gl(gi, left_seek - 1, &t)) { + + /* Go to beginning of netblock defined by netmask */ + mask = 0xffffffff << (32 - t.netmask); + left_seek = (left_seek - 1) & mask; + } + ret[0] = GeoIP_num_to_addr(left_seek); + + while (right_seek != 0xffffffff && + target_value == _GeoIP_seek_record_gl(gi, right_seek + 1, &t)) { + + /* Go to end of netblock defined by netmask */ + mask = 0xffffffff << (32 - t.netmask); + right_seek = (right_seek + 1) & mask; + right_seek += 0xffffffff & ~mask; + } + ret[1] = GeoIP_num_to_addr(right_seek); + + gi->netmask = orig_netmask; + + return ret; +} +void GeoIP_range_by_ip_delete(char **ptr) { + if (ptr) { + if (ptr[0]) { + free(ptr[0]); + } + if (ptr[1]) { + free(ptr[1]); + } + free(ptr); + } +} + +char *GeoIP_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + return _get_name_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + return _get_name_v6_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + unsigned long ipnum; + if (addr == NULL) { + return NULL; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_name_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (addr == NULL) { + return NULL; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_name_v6_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_name_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + unsigned long ipnum; + if (name == NULL) { + return NULL; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) { + return NULL; + } + return _get_name_gl(gi, ipnum, gl); +} + +char *GeoIP_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl) { + geoipv6_t ipnum; + if (name == NULL) { + return NULL; + } + ipnum = _GeoIP_lookupaddress_v6(name); + if (__GEOIP_V6_IS_NULL(ipnum)) { + return NULL; + } + return _get_name_v6_gl(gi, ipnum, gl); +} + +unsigned char GeoIP_database_edition(GeoIP *gi) { return gi->databaseType; } + +int GeoIP_enable_teredo(GeoIP *gi, int true_false) { + unsigned int mask = (1U << GEOIP_TEREDO_BIT); + int b = (gi->ext_flags & mask) ? 1 : 0; + gi->ext_flags &= ~mask; + if (true_false) { + gi->ext_flags |= true_false; + } + return b; +} + +int GeoIP_teredo(GeoIP *gi) { + unsigned int mask = (1U << GEOIP_TEREDO_BIT); + return (gi->ext_flags & mask) ? 1 : 0; +} + +int GeoIP_charset(GeoIP *gi) { return gi->charset; } + +int GeoIP_set_charset(GeoIP *gi, int charset) { + int old_charset = gi->charset; + gi->charset = charset; + return old_charset; +} + +/** return two letter country code */ +const char *GeoIP_code_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_code[id]; +} + +/** return three letter country code */ +const char *GeoIP_code3_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_code3[id]; +} + +/** return full name of country in utf8 or iso-8859-1 */ +const char *GeoIP_country_name_by_id(GeoIP *gi, int id) { + /* return NULL also even for index 0 for backward compatibility */ + if (id <= 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + return (gi->charset == GEOIP_CHARSET_UTF8) ? GeoIP_utf8_country_name[id] + : GeoIP_country_name[id]; +} + +/** return full name of country in iso-8859-1 */ +const char *GeoIP_name_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_name[id]; +} + +/** return continent of country */ +const char *GeoIP_continent_by_id(int id) { + if (id < 0 || id >= (int)num_GeoIP_countries) { + return NULL; + } + + return GeoIP_country_continent[id]; +} + +/** return id by country code **/ +int GeoIP_id_by_code(const char *country) { + unsigned i; + + for (i = 0; i < num_GeoIP_countries; ++i) { + if (strcmp(country, GeoIP_country_code[i]) == 0) { + return i; + } + } + + return 0; +} + +unsigned GeoIP_num_countries(void) { return num_GeoIP_countries; } + +const char *GeoIP_lib_version(void) { return PACKAGE_VERSION; } + +int GeoIP_cleanup(void) { + int i, result = 0; + char **tmpGeoIPDBFileName = GeoIPDBFileName; + + GeoIPDBFileName = NULL; + + if (tmpGeoIPDBFileName) { + for (i = 0; i < NUM_DB_TYPES; i++) { + if (tmpGeoIPDBFileName[i]) { + free(tmpGeoIPDBFileName[i]); + } + } + + free(tmpGeoIPDBFileName); + result = 1; + } + + return result; +} diff --git a/libGeoIP/GeoIP.h b/libGeoIP/GeoIP.h new file mode 100644 index 0000000..2852595 --- /dev/null +++ b/libGeoIP/GeoIP.h @@ -0,0 +1,444 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.h + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIP_H +#define GEOIP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#if !defined(_WIN32) +#include +#include +#include +#else /* !defined(_WIN32) */ +#include +#include +#define FILETIME_TO_USEC(ft) \ + (((unsigned __int64)ft.dwHighDateTime << 32 | ft.dwLowDateTime) / 10) +#endif /* !defined(_WIN32) */ + +#include +#include +#include +#include /* for fstat */ +#include /* for fstat */ + +#define SEGMENT_RECORD_LENGTH 3 +#define LARGE_SEGMENT_RECORD_LENGTH 4 +#define STANDARD_RECORD_LENGTH 3 +#define ORG_RECORD_LENGTH 4 +#define MAX_RECORD_LENGTH 4 +#define NUM_DB_TYPES (38 + 1) + +/* 128 bit address in network order */ +typedef struct in6_addr geoipv6_t; + +#define GEOIP_CHKBIT_V6(bit, ptr) \ + (ptr[((127UL - bit) >> 3)] & (1UL << (~(127 - bit) & 7))) + +typedef struct GeoIPTag { + FILE *GeoIPDatabase; + char *file_path; + unsigned char *cache; + unsigned char *index_cache; + unsigned int *databaseSegments; + char databaseType; + time_t mtime; + int flags; + off_t size; + char record_length; + int charset; /* 0 iso-8859-1 1 utf8 */ + int record_iter; /* used in GeoIP_next_record */ + int netmask; /* netmask of last lookup - set using depth in + _GeoIP_seek_record */ + time_t last_mtime_check; + off_t dyn_seg_size; /* currently only used by the cityconfidence database */ + unsigned int ext_flags; /* bit 0 teredo support enabled */ +} GeoIP; + +typedef struct GeoIPLookup { int netmask; } GeoIPLookup; + +typedef enum { GEOIP_TEREDO_BIT = 0 } GeoIPExtFlags; + +typedef enum { + GEOIP_CHARSET_ISO_8859_1 = 0, + GEOIP_CHARSET_UTF8 = 1 +} GeoIPCharset; + +typedef struct GeoIPRegionTag { + char country_code[3]; + char region[3]; +} GeoIPRegion; + +typedef enum { + GEOIP_STANDARD = 0, + GEOIP_MEMORY_CACHE = 1, + GEOIP_CHECK_CACHE = 2, + GEOIP_INDEX_CACHE = 4, + GEOIP_MMAP_CACHE = 8, + GEOIP_SILENCE = 16, +} GeoIPOptions; + +typedef enum { + GEOIP_COUNTRY_EDITION = 1, + GEOIP_REGION_EDITION_REV0 = 7, + GEOIP_CITY_EDITION_REV0 = 6, + GEOIP_ORG_EDITION = 5, + GEOIP_ISP_EDITION = 4, + GEOIP_CITY_EDITION_REV1 = 2, + GEOIP_REGION_EDITION_REV1 = 3, + GEOIP_PROXY_EDITION = 8, + GEOIP_ASNUM_EDITION = 9, + GEOIP_NETSPEED_EDITION = 10, + GEOIP_DOMAIN_EDITION = 11, + GEOIP_COUNTRY_EDITION_V6 = 12, + GEOIP_LOCATIONA_EDITION = 13, + GEOIP_ACCURACYRADIUS_EDITION = 14, + GEOIP_CITYCONFIDENCE_EDITION = 15, /* unsupported */ + GEOIP_CITYCONFIDENCEDIST_EDITION = 16, /* unsupported */ + GEOIP_LARGE_COUNTRY_EDITION = 17, + GEOIP_LARGE_COUNTRY_EDITION_V6 = 18, + GEOIP_CITYCONFIDENCEDIST_ISP_ORG_EDITION = + 19, /* unused, but gaps are not allowed */ + GEOIP_CCM_COUNTRY_EDITION = 20, /* unused, but gaps are not allowed */ + GEOIP_ASNUM_EDITION_V6 = 21, + GEOIP_ISP_EDITION_V6 = 22, + GEOIP_ORG_EDITION_V6 = 23, + GEOIP_DOMAIN_EDITION_V6 = 24, + GEOIP_LOCATIONA_EDITION_V6 = 25, + GEOIP_REGISTRAR_EDITION = 26, + GEOIP_REGISTRAR_EDITION_V6 = 27, + GEOIP_USERTYPE_EDITION = 28, + GEOIP_USERTYPE_EDITION_V6 = 29, + GEOIP_CITY_EDITION_REV1_V6 = 30, + GEOIP_CITY_EDITION_REV0_V6 = 31, + GEOIP_NETSPEED_EDITION_REV1 = 32, + GEOIP_NETSPEED_EDITION_REV1_V6 = 33, + GEOIP_COUNTRYCONF_EDITION = 34, + GEOIP_CITYCONF_EDITION = 35, + GEOIP_REGIONCONF_EDITION = 36, + GEOIP_POSTALCONF_EDITION = 37, + GEOIP_ACCURACYRADIUS_EDITION_V6 = 38 +} GeoIPDBTypes; + +typedef enum { + GEOIP_ANON_PROXY = 1, + GEOIP_HTTP_X_FORWARDED_FOR_PROXY = 2, + GEOIP_HTTP_CLIENT_IP_PROXY = 3, +} GeoIPProxyTypes; + +typedef enum { + GEOIP_UNKNOWN_SPEED = 0, + GEOIP_DIALUP_SPEED = 1, + GEOIP_CABLEDSL_SPEED = 2, + GEOIP_CORPORATE_SPEED = 3, +} GeoIPNetspeedValues; + +#if defined(_WIN32) && !defined(__MINGW32__) +#ifdef GEOIP_EXPORTS +#define GEOIP_API __declspec(dllexport) +#define GEOIP_DATA __declspec(dllexport) +#else +#define GEOIP_DATA __declspec(dllimport) +#define GEOIP_API +#endif /* GEOIP_EXPORTS */ +#else +#define GEOIP_API +#define GEOIP_DATA +#endif + +extern char **GeoIPDBFileName; +extern GEOIP_DATA const char *GeoIPDBDescription[NUM_DB_TYPES]; +extern GEOIP_DATA const char *GeoIPCountryDBFileName; +extern GEOIP_DATA const char *GeoIPRegionDBFileName; +extern GEOIP_DATA const char *GeoIPCityDBFileName; +extern GEOIP_DATA const char *GeoIPOrgDBFileName; +extern GEOIP_DATA const char *GeoIPISPDBFileName; +extern GEOIP_DATA const char *GeoIPLocationADBFileName; +extern GEOIP_DATA const char *GeoIPAccuracyRadiusFileName; +extern GEOIP_DATA const char *GeoIPCityConfidenceFileName; +extern char *GeoIP_custom_directory; + +/* Warning: do not use those arrays as doing so may break your + * program with newer GeoIP versions */ +extern GEOIP_DATA const char GeoIP_country_code[256][3]; +extern GEOIP_DATA const char GeoIP_country_code3[256][4]; +extern GEOIP_DATA const char *GeoIP_country_name[256]; +extern GEOIP_DATA const char *GeoIP_utf8_country_name[256]; +extern GEOIP_DATA const char GeoIP_country_continent[256][3]; + +GEOIP_API void GeoIP_setup_custom_directory(char *dir); +GEOIP_API GeoIP *GeoIP_open_type(int type, int flags); +GEOIP_API GeoIP *GeoIP_new(int flags); +GEOIP_API GeoIP *GeoIP_open(const char *filename, int flags); +/* + * WARNING: GeoIP_db_avail() checks for the existence of a database + * file but does not check that it has the requested database revision. + * For database types which have more than one revision (including Region, + * City, and Cityv6), this can lead to unexpected results. Check the + * return value of GeoIP_open_type() to find out whether a particular + * database type is really available. + */ +GEOIP_API int GeoIP_db_avail(int type); +GEOIP_API void GeoIP_delete(GeoIP *gi); + +GEOIP_API const char * +GeoIP_country_code_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API const char *GeoIP_country_code3_by_ipnum_gl(GeoIP *gi, + unsigned long ipnum, + GeoIPLookup *gl); + +/* */ +GEOIP_API const char * +GeoIP_country_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); + +GEOIP_API const char * +GeoIP_country_code_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_code3_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API const char * +GeoIP_country_name_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); + +GEOIP_API int GeoIP_id_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API int GeoIP_id_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API int +GeoIP_id_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); + +GEOIP_API int +GeoIP_id_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API int +GeoIP_id_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API int +GeoIP_id_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); + +GEOIP_API GeoIPRegion * +GeoIP_region_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); + +GEOIP_API GeoIPRegion * +GeoIP_region_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_name_v6_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); +GEOIP_API GeoIPRegion * +GeoIP_region_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); + +/* Warning - don't call this after GeoIP_assign_region_by_inetaddr calls */ +GEOIP_API void GeoIPRegion_delete(GeoIPRegion *gir); + +GEOIP_API void GeoIP_assign_region_by_inetaddr_gl(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *gir, + GeoIPLookup *gl); +GEOIP_API void GeoIP_assign_region_by_inetaddr_v6_gl(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *gir, + GeoIPLookup *gl); + +/* Used to query GeoIP Organization, ISP and AS Number databases */ +GEOIP_API char * +GeoIP_name_by_ipnum_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_addr_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_name_gl(GeoIP *gi, const char *host, GeoIPLookup *gl); + +GEOIP_API char * +GeoIP_name_by_ipnum_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_addr_v6_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API char * +GeoIP_name_by_name_v6_gl(GeoIP *gi, const char *name, GeoIPLookup *gl); + +/** return two letter country code */ +GEOIP_API const char *GeoIP_code_by_id(int id); + +/** return three letter country code */ +GEOIP_API const char *GeoIP_code3_by_id(int id); + +/** return full name of country in utf8 or iso-8859-1 */ +GEOIP_API const char *GeoIP_country_name_by_id(GeoIP *gi, int id); + +/** return full name of country */ +GEOIP_API const char *GeoIP_name_by_id(int id); + +/** return continent of country */ +GEOIP_API const char *GeoIP_continent_by_id(int id); + +/** return id by country code **/ +GEOIP_API int GeoIP_id_by_code(const char *country); + +/** return return number of known countries */ +GEOIP_API unsigned GeoIP_num_countries(void); + +GEOIP_API char *GeoIP_database_info(GeoIP *gi); +GEOIP_API unsigned char GeoIP_database_edition(GeoIP *gi); + +GEOIP_API int GeoIP_charset(GeoIP *gi); +GEOIP_API int GeoIP_set_charset(GeoIP *gi, int charset); +GEOIP_API int GeoIP_enable_teredo(GeoIP *gi, int true_false); +GEOIP_API int GeoIP_teredo(GeoIP *gi); + +GEOIP_API char ** +GeoIP_range_by_ip_gl(GeoIP *gi, const char *addr, GeoIPLookup *gl); +GEOIP_API void GeoIP_range_by_ip_delete(char **ptr); + +/* Convert region code to region name */ +GEOIP_API const char *GeoIP_region_name_by_code(const char *country_code, + const char *region_code); + +/* Get timezone from country and region code */ +GEOIP_API const char * +GeoIP_time_zone_by_country_and_region(const char *country_code, + const char *region_code); + +/* some v4 helper functions as of 1.4.7 exported to the public API */ +GEOIP_API unsigned long GeoIP_addr_to_num(const char *addr); +GEOIP_API char *GeoIP_num_to_addr(unsigned long ipnum); + +/* Internal function -- convert iso to utf8; return a malloced utf8 string. */ +char *_GeoIP_iso_8859_1__utf8(const char *iso); + +/* Cleans up memory used to hold file name paths. Returns 1 if successful; + * otherwise 0. + * */ +GEOIP_API int GeoIP_cleanup(void); + +/* Returns the library version in use. Helpful if you're loading dynamically. */ +GEOIP_API const char *GeoIP_lib_version(void); + +/* deprecated */ +GEOIP_API const char *GeoIP_country_code_by_addr(GeoIP *gi, const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name(GeoIP *gi, const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr(GeoIP *gi, const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name(GeoIP *gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr(GeoIP *gi, const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name(GeoIP *gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_ipnum(GeoIP *gi, + unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum(GeoIP *gi, + unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum(GeoIP *gi, + unsigned long ipnum); + +GEOIP_API const char *GeoIP_country_name_by_ipnum_v6(GeoIP *gi, + geoipv6_t ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum_v6(GeoIP *gi, + geoipv6_t ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum_v6(GeoIP *gi, + geoipv6_t ipnum); + +GEOIP_API const char *GeoIP_country_code_by_addr_v6(GeoIP *gi, + const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name_v6(GeoIP *gi, + const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr_v6(GeoIP *gi, + const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name_v6(GeoIP *gi, + const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr_v6(GeoIP *gi, + const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name_v6(GeoIP *gi, + const char *host); + +GEOIP_API int GeoIP_id_by_addr(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_id_by_name(GeoIP *gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum(GeoIP *gi, unsigned long ipnum); + +GEOIP_API int GeoIP_id_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_id_by_name_v6(GeoIP *gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); + +GEOIP_API GeoIPRegion *GeoIP_region_by_addr(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRegion *GeoIP_region_by_name(GeoIP *gi, const char *host); +GEOIP_API GeoIPRegion *GeoIP_region_by_ipnum(GeoIP *gi, unsigned long ipnum); + +GEOIP_API GeoIPRegion *GeoIP_region_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRegion *GeoIP_region_by_name_v6(GeoIP *gi, const char *host); +GEOIP_API GeoIPRegion *GeoIP_region_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); + +GEOIP_API void GeoIP_assign_region_by_inetaddr(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *gir); +GEOIP_API void GeoIP_assign_region_by_inetaddr_v6(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *gir); + +GEOIP_API char *GeoIP_name_by_ipnum(GeoIP *gi, unsigned long ipnum); +GEOIP_API char *GeoIP_name_by_addr(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name(GeoIP *gi, const char *host); + +GEOIP_API char *GeoIP_name_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); +GEOIP_API char *GeoIP_name_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name_v6(GeoIP *gi, const char *name); + +/** GeoIP_last_netmask is deprecated - it is not thread safe */ +GEOIP_API int GeoIP_last_netmask(GeoIP *gi); +GEOIP_API char **GeoIP_range_by_ip(GeoIP *gi, const char *addr); + +/* Deprecated - for backwards compatibility only */ +GEOIP_API int GeoIP_country_id_by_addr(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_country_id_by_name(GeoIP *gi, const char *host); +GEOIP_API char *GeoIP_org_by_addr(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name(GeoIP *gi, const char *host); +GEOIP_API char *GeoIP_org_by_ipnum(GeoIP *gi, unsigned long ipnum); + +GEOIP_API int GeoIP_country_id_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_org_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); +GEOIP_API char *GeoIP_org_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name_v6(GeoIP *gi, const char *name); + +/* End deprecated */ + +# +#ifdef __cplusplus +} +#endif + +#endif /* GEOIP_H */ diff --git a/libGeoIP/GeoIPCity.c b/libGeoIP/GeoIPCity.c new file mode 100644 index 0000000..543f829 --- /dev/null +++ b/libGeoIP/GeoIPCity.c @@ -0,0 +1,330 @@ + +/* + * GeoIPCity.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIPCity.h" +#include "GeoIP.h" +#include "GeoIP_internal.h" +#if !defined(_WIN32) +#include +#include /* For ntohl */ +#include +#else +#include +#include + +#if defined(_MSC_VER) && \ + _MSC_VER >= 1400 // VS 2005+ deprecates fileno, lseek and read +#define fileno _fileno +#define read _read +#define lseek _lseek +#endif +#endif +#include /* For uint32_t */ +#ifdef HAVE_STDINT_H +#include /* For uint32_t */ +#endif + +#if defined(_WIN32) && !defined(__MINGW32__) +#include "pread.h" +#endif + +#ifndef HAVE_PREAD +#define pread(fd, buf, count, offset) \ + (lseek(fd, offset, SEEK_SET) == offset ? read(fd, buf, count) : -1) +#endif /* HAVE_PREAD */ + +static const int FULL_RECORD_LENGTH = 50; + +static GeoIPRecord * +_extract_record(GeoIP *gi, unsigned int seek_record, int *next_record_ptr) { + int record_pointer; + unsigned char *record_buf = NULL; + unsigned char *begin_record_buf = NULL; + GeoIPRecord *record; + int str_length = 0; + int j; + double latitude = 0, longitude = 0; + int metroarea_combo = 0; + int bytes_read = 0; + if (seek_record == gi->databaseSegments[0]) { + return NULL; + } + + record = malloc(sizeof(GeoIPRecord)); + memset(record, 0, sizeof(GeoIPRecord)); + record->charset = gi->charset; + + record_pointer = + seek_record + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + begin_record_buf = record_buf = + malloc(sizeof(unsigned char) * FULL_RECORD_LENGTH); + bytes_read = pread(fileno(gi->GeoIPDatabase), + record_buf, + FULL_RECORD_LENGTH, + record_pointer); + if (bytes_read <= 0) { + /* eof or other error */ + free(begin_record_buf); + free(record); + return NULL; + } + } else { + if (gi->size <= record_pointer) { + /* record does not exist in the cache */ + free(record); + return NULL; + } + record_buf = gi->cache + (long)record_pointer; + } + + /* get country */ + record->continent_code = (char *)GeoIP_country_continent[record_buf[0]]; + record->country_code = (char *)GeoIP_country_code[record_buf[0]]; + record->country_code3 = (char *)GeoIP_country_code3[record_buf[0]]; + record->country_name = (char *)GeoIP_country_name_by_id(gi, record_buf[0]); + record_buf++; + + /* get region */ + while (record_buf[str_length] != '\0') { + str_length++; + } + if (str_length > 0) { + record->region = malloc(str_length + 1); + strncpy(record->region, (char *)record_buf, str_length + 1); + } + record_buf += str_length + 1; + str_length = 0; + + /* get city */ + while (record_buf[str_length] != '\0') { + str_length++; + } + if (str_length > 0) { + if (gi->charset == GEOIP_CHARSET_UTF8) { + record->city = _GeoIP_iso_8859_1__utf8((const char *)record_buf); + } else { + record->city = malloc(str_length + 1); + strncpy(record->city, (const char *)record_buf, str_length + 1); + } + } + record_buf += (str_length + 1); + str_length = 0; + + /* get postal code */ + while (record_buf[str_length] != '\0') { + str_length++; + } + if (str_length > 0) { + record->postal_code = malloc(str_length + 1); + strncpy(record->postal_code, (char *)record_buf, str_length + 1); + } + record_buf += (str_length + 1); + + /* get latitude */ + for (j = 0; j < 3; ++j) { + latitude += (record_buf[j] << (j * 8)); + } + record->latitude = (float)(latitude / 10000 - 180); + record_buf += 3; + + /* get longitude */ + for (j = 0; j < 3; ++j) { + longitude += (record_buf[j] << (j * 8)); + } + record->longitude = (float)(longitude / 10000 - 180); + + /* + * get area code and metro code for post April 2002 databases and for US + * locations + */ + if (gi->databaseType == GEOIP_CITY_EDITION_REV1 || + gi->databaseType == GEOIP_CITY_EDITION_REV1_V6) { + if (!strcmp(record->country_code, "US")) { + record_buf += 3; + for (j = 0; j < 3; ++j) { + metroarea_combo += (record_buf[j] << (j * 8)); + } + record->metro_code = metroarea_combo / 1000; + record->area_code = metroarea_combo % 1000; + } + } + + if (begin_record_buf != NULL) { + free(begin_record_buf); + } + + /* Used for GeoIP_next_record */ + if (next_record_ptr != NULL) { + *next_record_ptr = seek_record + record_buf - begin_record_buf + 3; + } + + return record; +} + +static GeoIPRecord * +_get_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl) { + unsigned int seek_record; + GeoIPRecord *r; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0 && + gi->databaseType != GEOIP_CITY_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return NULL; + } + + seek_record = _GeoIP_seek_record_gl(gi, ipnum, gl); + r = _extract_record(gi, seek_record, NULL); + if (r) { + r->netmask = gl->netmask; + } + return r; +} + +static GeoIPRecord *_get_record(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return _get_record_gl(gi, ipnum, &gl); +} + +static GeoIPRecord * +_get_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl) { + GeoIPRecord *r; + unsigned int seek_record; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0_V6 && + gi->databaseType != GEOIP_CITY_EDITION_REV1_V6) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1_V6]); + return NULL; + } + + seek_record = _GeoIP_seek_record_v6_gl(gi, ipnum, gl); + r = _extract_record(gi, seek_record, NULL); + if (r) { + r->netmask = gl->netmask; + } + return r; +} + +static GeoIPRecord *_get_record_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return _get_record_v6_gl(gi, ipnum, &gl); +} + +GeoIPRecord *GeoIP_record_by_ipnum(GeoIP *gi, unsigned long ipnum) { + return _get_record(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + return _get_record_v6(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_addr(GeoIP *gi, const char *addr) { + unsigned long ipnum; + GeoIPLookup gl; + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _get_record_gl(gi, ipnum, &gl); +} + +GeoIPRecord *GeoIP_record_by_addr_v6(GeoIP *gi, const char *addr) { + geoipv6_t ipnum; + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _get_record_v6(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_name(GeoIP *gi, const char *name) { + unsigned long ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress(name); + return _get_record(gi, ipnum); +} + +GeoIPRecord *GeoIP_record_by_name_v6(GeoIP *gi, const char *name) { + geoipv6_t ipnum; + if (name == NULL) { + return 0; + } + ipnum = _GeoIP_lookupaddress_v6(name); + return _get_record_v6(gi, ipnum); +} + +int GeoIP_record_id_by_addr(GeoIP *gi, const char *addr) { + unsigned long ipnum; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0 && + gi->databaseType != GEOIP_CITY_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + if (addr == NULL) { + return 0; + } + ipnum = GeoIP_addr_to_num(addr); + return _GeoIP_seek_record(gi, ipnum); +} + +int GeoIP_record_id_by_addr_v6(GeoIP *gi, const char *addr) { + geoipv6_t ipnum; + if (gi->databaseType != GEOIP_CITY_EDITION_REV0_V6 && + gi->databaseType != GEOIP_CITY_EDITION_REV1_V6) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]); + return 0; + } + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num_v6(addr); + return _GeoIP_seek_record_v6(gi, ipnum); +} + +int GeoIP_init_record_iter(GeoIP *gi) { return gi->databaseSegments[0] + 1; } + +int GeoIP_next_record(GeoIP *gi, GeoIPRecord **gir, int *record_iter) { + if (gi->cache != NULL) { + printf("GeoIP_next_record not supported in memory cache mode\n"); + return 1; + } + *gir = _extract_record(gi, *record_iter, record_iter); + return 0; +} + +void GeoIPRecord_delete(GeoIPRecord *gir) { + if (gir == NULL) { + return; + } + free(gir->region); + free(gir->city); + free(gir->postal_code); + free(gir); +} diff --git a/libGeoIP/GeoIPCity.h b/libGeoIP/GeoIPCity.h new file mode 100644 index 0000000..259fd1e --- /dev/null +++ b/libGeoIP/GeoIPCity.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIPCity.h + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef GEOIPCITY_H +#define GEOIPCITY_H + +#include "GeoIP.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GEOIP_UNKNOWN_CONF (0x7f) + +typedef struct GeoIPRecordTag { + char *country_code; + char *country_code3; + char *country_name; + char *region; + char *city; + char *postal_code; + float latitude; + float longitude; + union { + int metro_code; /* metro_code is an alias for dma_code */ + int dma_code; + }; + int area_code; + int charset; + char *continent_code; + int netmask; +} GeoIPRecord; + +GEOIP_API GeoIPRecord *GeoIP_record_by_ipnum(GeoIP *gi, unsigned long ipnum); +GEOIP_API GeoIPRecord *GeoIP_record_by_addr(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRecord *GeoIP_record_by_name(GeoIP *gi, const char *host); + +GEOIP_API GeoIPRecord *GeoIP_record_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum); +GEOIP_API GeoIPRecord *GeoIP_record_by_addr_v6(GeoIP *gi, const char *addr); +GEOIP_API GeoIPRecord *GeoIP_record_by_name_v6(GeoIP *gi, const char *host); + +GEOIP_API int GeoIP_record_id_by_addr(GeoIP *gi, const char *addr); +GEOIP_API int GeoIP_record_id_by_addr_v6(GeoIP *gi, const char *addr); + +GEOIP_API int GeoIP_init_record_iter(GeoIP *gi); +/* returns 0 on success, 1 on failure */ +GEOIP_API int GeoIP_next_record(GeoIP *gi, GeoIPRecord **gir, int *record_iter); + +GEOIP_API void GeoIPRecord_delete(GeoIPRecord *gir); + +#ifdef __cplusplus +} +#endif + +#endif /* GEOIPCITY_H */ diff --git a/libGeoIP/GeoIP_deprecated.c b/libGeoIP/GeoIP_deprecated.c new file mode 100644 index 0000000..aae3685 --- /dev/null +++ b/libGeoIP/GeoIP_deprecated.c @@ -0,0 +1,248 @@ + +#include "GeoIP_internal.h" + +char *GeoIP_org_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_gl(gi, ipnum, &gl); +} + +char *GeoIP_org_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +char *GeoIP_org_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_gl(gi, addr, &gl); +} + +char *GeoIP_org_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_v6_gl(gi, addr, &gl); +} + +char *GeoIP_org_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_gl(gi, name, &gl); +} + +char *GeoIP_org_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_v6_gl(gi, name, &gl); +} + +int GeoIP_last_netmask(GeoIP *gi) { return gi->netmask; } + +unsigned int _GeoIP_seek_record_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return _GeoIP_seek_record_v6_gl(gi, ipnum, &gl); +} + +unsigned int _GeoIP_seek_record(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return _GeoIP_seek_record_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_code_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code_by_name_gl(gi, name, &gl); +} + +const char *GeoIP_country_code3_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code3_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_code3_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_code3_by_name_gl(gi, name, &gl); +} + +const char *GeoIP_country_name_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_name_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_name_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_country_name_by_name_gl(gi, name, &gl); +} + +int GeoIP_id_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_id_by_name_gl(gi, name, &gl); +} +int GeoIP_id_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_id_by_name_v6_gl(gi, name, &gl); +} + +const char *GeoIP_country_code_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code_by_addr_v6_gl(gi, addr, &gl); +} +const char *GeoIP_country_code_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code_by_addr_gl(gi, addr, &gl); +} + +const char *GeoIP_country_code3_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code3_by_addr_v6_gl(gi, addr, &gl); +} + +const char *GeoIP_country_code3_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_code3_by_addr_gl(gi, addr, &gl); +} + +const char *GeoIP_country_name_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_name_by_addr_v6_gl(gi, addr, &gl); +} +const char *GeoIP_country_name_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_country_name_by_addr_gl(gi, addr, &gl); +} + +const char *GeoIP_country_name_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_country_name_by_ipnum_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_name_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_country_name_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_country_code_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_country_code_by_ipnum_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code3_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_country_code3_by_ipnum_gl(gi, ipnum, &gl); +} + +const char *GeoIP_country_code3_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_country_code3_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +int GeoIP_country_id_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_v6_gl(gi, addr, &gl); +} + +int GeoIP_country_id_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_gl(gi, addr, &gl); +} +int GeoIP_country_id_by_name_v6(GeoIP *gi, const char *host) { + GeoIPLookup gl; + return GeoIP_id_by_name_v6_gl(gi, host, &gl); +} +int GeoIP_country_id_by_name(GeoIP *gi, const char *host) { + GeoIPLookup gl; + return GeoIP_id_by_name_gl(gi, host, &gl); +} +int GeoIP_id_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_v6_gl(gi, addr, &gl); +} +int GeoIP_id_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_id_by_addr_gl(gi, addr, &gl); +} + +int GeoIP_id_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_id_by_ipnum_v6_gl(gi, ipnum, &gl); +} +int GeoIP_id_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_id_by_ipnum_gl(gi, ipnum, &gl); +} +void GeoIP_assign_region_by_inetaddr(GeoIP *gi, + unsigned long inetaddr, + GeoIPRegion *region) { + GeoIPLookup gl; + GeoIP_assign_region_by_inetaddr_gl(gi, inetaddr, region, &gl); +} + +void GeoIP_assign_region_by_inetaddr_v6(GeoIP *gi, + geoipv6_t inetaddr, + GeoIPRegion *region) { + GeoIPLookup gl; + GeoIP_assign_region_by_inetaddr_v6_gl(gi, inetaddr, region, &gl); +} + +GeoIPRegion *GeoIP_region_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_region_by_addr_gl(gi, addr, &gl); +} +GeoIPRegion *GeoIP_region_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_region_by_addr_v6_gl(gi, addr, &gl); +} + +GeoIPRegion *GeoIP_region_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_region_by_name_gl(gi, name, &gl); +} +GeoIPRegion *GeoIP_region_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_region_by_name_v6_gl(gi, name, &gl); +} + +GeoIPRegion *GeoIP_region_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_region_by_ipnum_gl(gi, ipnum, &gl); +} +GeoIPRegion *GeoIP_region_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_region_by_ipnum_v6_gl(gi, ipnum, &gl); +} + +char **GeoIP_range_by_ip(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_range_by_ip_gl(gi, addr, &gl); +} + +char *GeoIP_name_by_ipnum(GeoIP *gi, unsigned long ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_gl(gi, ipnum, &gl); +} +char *GeoIP_name_by_ipnum_v6(GeoIP *gi, geoipv6_t ipnum) { + GeoIPLookup gl; + return GeoIP_name_by_ipnum_v6_gl(gi, ipnum, &gl); +} +char *GeoIP_name_by_addr(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_gl(gi, addr, &gl); +} +char *GeoIP_name_by_addr_v6(GeoIP *gi, const char *addr) { + GeoIPLookup gl; + return GeoIP_name_by_addr_v6_gl(gi, addr, &gl); +} + +char *GeoIP_name_by_name(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_gl(gi, name, &gl); +} + +char *GeoIP_name_by_name_v6(GeoIP *gi, const char *name) { + GeoIPLookup gl; + return GeoIP_name_by_name_v6_gl(gi, name, &gl); +} diff --git a/libGeoIP/GeoIP_internal.h b/libGeoIP/GeoIP_internal.h new file mode 100644 index 0000000..2c96587 --- /dev/null +++ b/libGeoIP/GeoIP_internal.h @@ -0,0 +1,23 @@ +#ifndef GEOIP_INTERNAL_H +#define GEOIP_INTERNAL_H + +#include "GeoIP.h" + +GEOIP_API unsigned int +_GeoIP_seek_record_gl(GeoIP *gi, unsigned long ipnum, GeoIPLookup *gl); +GEOIP_API unsigned int +_GeoIP_seek_record_v6_gl(GeoIP *gi, geoipv6_t ipnum, GeoIPLookup *gl); +GEOIP_API geoipv6_t _GeoIP_addr_to_num_v6(const char *addr); + +GEOIP_API unsigned long _GeoIP_lookupaddress(const char *host); +GEOIP_API geoipv6_t _GeoIP_lookupaddress_v6(const char *host); +GEOIP_API int __GEOIP_V6_IS_NULL(geoipv6_t v6); + +GEOIP_API void _GeoIP_setup_dbfilename(void); +GEOIP_API char *_GeoIP_full_path_to(const char *file_name); + +/* deprecated */ +GEOIP_API unsigned int _GeoIP_seek_record(GeoIP *gi, unsigned long ipnum); +GEOIP_API unsigned int _GeoIP_seek_record_v6(GeoIP *gi, geoipv6_t ipnum); + +#endif diff --git a/libGeoIP/Makefile.am b/libGeoIP/Makefile.am new file mode 100644 index 0000000..f85cd00 --- /dev/null +++ b/libGeoIP/Makefile.am @@ -0,0 +1,19 @@ +lib_LTLIBRARIES = libGeoIP.la + +EXTRA_DIST = Makefile.vc GeoIP_internal.h pread.c pread.h + +AM_CPPFLAGS = -DGEOIPDATADIR=\"$(pkgdatadir)\" -Wall + +libGeoIP_la_SOURCES = GeoIP.c GeoIP_deprecated.c GeoIPCity.c regionName.c timeZone.c +include_HEADERS = GeoIP.h GeoIPCity.h + +libGeoIP_la_LDFLAGS = -no-undefined -version-info @GEOIP_VERSION_INFO@ + +GeoIP.lo GeoIP.o: GeoIP.c GeoIP_deprecated.c GeoIP.h + +GeoIPCity.lo GeoIPCity.o: GeoIPCity.c GeoIP.h + +regionName.lo regionName.o: regionName.c + +timeZone.lo timeZone.o: timeZone.c + diff --git a/libGeoIP/Makefile.vc b/libGeoIP/Makefile.vc new file mode 100644 index 0000000..157e014 --- /dev/null +++ b/libGeoIP/Makefile.vc @@ -0,0 +1,47 @@ +#NMAKE makefile for Windows developers. +##Produces a static library (GeoIP.lib). +#Produces a DLL (GeoIP.dll) and library (GeoIP.lib). + +COMPILER=cl + +CFLAGS=-DWIN32 -DGEOIP_EXPORTS -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DGEOIPDATADIR=\"$(GEOIPDATADIR)\" -DPACKAGE_VERSION=\"1.6.3\" + +LINKER=link + +LDFLAGS=/DLL /nologo /subsystem:console + +LD1 = $(LINKER) $(LDFLAGS) + +OBJS=GeoIP.obj GeoIPCity.obj GeoIP_deprecated.obj regionName.obj timeZone.obj pread.obj + +EXTRA_LIBS= ws2_32.lib + +AR=lib + +#GeoIP.lib: GeoIP.obj GeoIPCity.obj regionName.obj md5.obj timeZone.obj +# $(AR) -nologo $(OBJS) $(EXTRA_LIBS) /OUT:GeoIP.lib + +GeoIP.dll GeoIP.lib: $(OBJS) + $(LD1) $(OBJS) $(EXTRA_LIBS) /out:GeoIP.dll /implib:GeoIP.lib + +GeoIP.obj: GeoIP.c + $(CC1) -c GeoIP.c $(GEOIPINC) + +GeoIPCity.obj: GeoIPCity.c + $(CC1) -c GeoIPCity.c $(GEOIPINC) + +GeoIP_deprecated.obj: GeoIP_deprecated.c + $(CC1) -c GeoIP_deprecated.c $(GEOIPINC) + +regionName.obj: regionName.c + $(CC1) -c regionName.c $(GEOIPINC) + +timeZone.obj: timeZone.c + $(CC1) -c timeZone.c $(GEOIPINC) + +pread.obj: pread.c + $(CC1) -c pread.c $(GEOIPINC) diff --git a/libGeoIP/pread.c b/libGeoIP/pread.c new file mode 100644 index 0000000..ae5f462 --- /dev/null +++ b/libGeoIP/pread.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "pread.h" + +static CRITICAL_SECTION preadsc; + +/* http://stackoverflow.com/a/2390626/1392778 */ + +#ifdef _MSC_VER +#pragma section(".CRT$XCU", read) +#define INITIALIZER2_(f, p) \ + static void __cdecl f(void); \ + __declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = f; \ + __pragma(comment(linker, "/include:" p #f "_")) static void __cdecl f(void) +#ifdef _WIN64 +#define INITIALIZER(f) INITIALIZER2_(f, "") +#else +#define INITIALIZER(f) INITIALIZER2_(f, "_") +#endif +#elif defined(__GNUC__) +#define INITIALIZER(f) \ + static void f(void) __attribute__((constructor)); \ + static void f(void) +#endif + +#ifdef _WIN64 +int pread(int fd, void *buf, unsigned int nbyte, __int64 offset) { + int cc = -1; + __int64 prev = (__int64)-1L; + + EnterCriticalSection(&preadsc); + prev = _lseeki64(fd, 0L, SEEK_CUR); + if (prev == (__int64)-1L) { + goto done; + } + if (_lseeki64(fd, offset, SEEK_SET) != offset) { + goto done; + } + cc = _read(fd, buf, nbyte); + +done: + if (prev != (__int64)-1L) { + (void)_lseeki64(fd, prev, SEEK_SET); + } + LeaveCriticalSection(&preadsc); + + return cc; +} +#else +int pread(int fd, void *buf, unsigned int nbyte, long offset) { + int cc = -1; + long prev = -1L; + + EnterCriticalSection(&preadsc); + prev = _lseek(fd, 0L, SEEK_CUR); + if (prev == -1L) { + goto done; + } + if (_lseek(fd, offset, SEEK_SET) != offset) { + goto done; + } + cc = _read(fd, buf, nbyte); + +done: + if (prev != -1L) { + (void)_lseek(fd, prev, SEEK_SET); + } + LeaveCriticalSection(&preadsc); + + return cc; +} +#endif + +static void deinitialize(void) { DeleteCriticalSection(&preadsc); } + +INITIALIZER(initialize) { + InitializeCriticalSection(&preadsc); + atexit(deinitialize); +} diff --git a/libGeoIP/pread.h b/libGeoIP/pread.h new file mode 100644 index 0000000..4e48949 --- /dev/null +++ b/libGeoIP/pread.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef _WIN64 +typedef __int64 ssize_t; + +int pread(int fd, void *buf, unsigned int nbyte, __int64 offset); +#else +typedef int ssize_t; + +int pread(int fd, void *buf, unsigned int nbyte, long offset); +#endif + +#define HAVE_PREAD diff --git a/libGeoIP/regionName.c b/libGeoIP/regionName.c new file mode 100644 index 0000000..60f6260 --- /dev/null +++ b/libGeoIP/regionName.c @@ -0,0 +1,10197 @@ +#include "GeoIP.h" +#include +#include + +static const char *get_region_name_AD(int region_code) { + switch (region_code) { + case 3: + return "Encamp"; + case 4: + return "La Massana"; + case 5: + return "Ordino"; + case 6: + return "Sant Julia de Loria"; + case 7: + return "Andorra la Vella"; + case 8: + return "Escaldes-Engordany"; + default: + return NULL; + } +} + +static const char *get_region_name_AE(int region_code) { + switch (region_code) { + case 1: + return "Abu Dhabi"; + case 2: + return "Ajman"; + case 3: + return "Dubai"; + case 4: + return "Fujairah"; + case 5: + return "Ras Al Khaimah"; + case 6: + return "Sharjah"; + case 7: + return "Umm Al Quwain"; + default: + return NULL; + } +} + +static const char *get_region_name_AF(int region_code) { + switch (region_code) { + case 1: + return "Badakhshan"; + case 2: + return "Badghis"; + case 3: + return "Baghlan"; + case 5: + return "Bamian"; + case 6: + return "Farah"; + case 7: + return "Faryab"; + case 8: + return "Ghazni"; + case 9: + return "Ghowr"; + case 10: + return "Helmand"; + case 11: + return "Herat"; + case 13: + return "Kabol"; + case 14: + return "Kapisa"; + case 17: + return "Lowgar"; + case 18: + return "Nangarhar"; + case 19: + return "Nimruz"; + case 23: + return "Kandahar"; + case 24: + return "Kondoz"; + case 26: + return "Takhar"; + case 27: + return "Vardak"; + case 28: + return "Zabol"; + case 29: + return "Paktika"; + case 30: + return "Balkh"; + case 31: + return "Jowzjan"; + case 32: + return "Samangan"; + case 33: + return "Sar-e Pol"; + case 34: + return "Konar"; + case 35: + return "Laghman"; + case 36: + return "Paktia"; + case 37: + return "Khowst"; + case 38: + return "Nurestan"; + case 39: + return "Oruzgan"; + case 40: + return "Parvan"; + case 41: + return "Daykondi"; + case 42: + return "Panjshir"; + default: + return NULL; + } +} + +static const char *get_region_name_AG(int region_code) { + switch (region_code) { + case 1: + return "Barbuda"; + case 3: + return "Saint George"; + case 4: + return "Saint John"; + case 5: + return "Saint Mary"; + case 6: + return "Saint Paul"; + case 7: + return "Saint Peter"; + case 8: + return "Saint Philip"; + case 9: + return "Redonda"; + default: + return NULL; + } +} + +static const char *get_region_name_AL(int region_code) { + switch (region_code) { + case 40: + return "Berat"; + case 41: + return "Diber"; + case 42: + return "Durres"; + case 43: + return "Elbasan"; + case 44: + return "Fier"; + case 45: + return "Gjirokaster"; + case 46: + return "Korce"; + case 47: + return "Kukes"; + case 48: + return "Lezhe"; + case 49: + return "Shkoder"; + case 50: + return "Tirane"; + case 51: + return "Vlore"; + default: + return NULL; + } +} + +static const char *get_region_name_AM(int region_code) { + switch (region_code) { + case 1: + return "Aragatsotn"; + case 2: + return "Ararat"; + case 3: + return "Armavir"; + case 4: + return "Geghark'unik'"; + case 5: + return "Kotayk'"; + case 6: + return "Lorri"; + case 7: + return "Shirak"; + case 8: + return "Syunik'"; + case 9: + return "Tavush"; + case 10: + return "Vayots' Dzor"; + case 11: + return "Yerevan"; + default: + return NULL; + } +} + +static const char *get_region_name_AO(int region_code) { + switch (region_code) { + case 1: + return "Benguela"; + case 2: + return "Bie"; + case 3: + return "Cabinda"; + case 4: + return "Cuando Cubango"; + case 5: + return "Cuanza Norte"; + case 6: + return "Cuanza Sul"; + case 7: + return "Cunene"; + case 8: + return "Huambo"; + case 9: + return "Huila"; + case 12: + return "Malanje"; + case 13: + return "Namibe"; + case 14: + return "Moxico"; + case 15: + return "Uige"; + case 16: + return "Zaire"; + case 17: + return "Lunda Norte"; + case 18: + return "Lunda Sul"; + case 19: + return "Bengo"; + case 20: + return "Luanda"; + default: + return NULL; + } +} + +static const char *get_region_name_AR(int region_code) { + switch (region_code) { + case 1: + return "Buenos Aires"; + case 2: + return "Catamarca"; + case 3: + return "Chaco"; + case 4: + return "Chubut"; + case 5: + return "Cordoba"; + case 6: + return "Corrientes"; + case 7: + return "Distrito Federal"; + case 8: + return "Entre Rios"; + case 9: + return "Formosa"; + case 10: + return "Jujuy"; + case 11: + return "La Pampa"; + case 12: + return "La Rioja"; + case 13: + return "Mendoza"; + case 14: + return "Misiones"; + case 15: + return "Neuquen"; + case 16: + return "Rio Negro"; + case 17: + return "Salta"; + case 18: + return "San Juan"; + case 19: + return "San Luis"; + case 20: + return "Santa Cruz"; + case 21: + return "Santa Fe"; + case 22: + return "Santiago del Estero"; + case 23: + return "Tierra del Fuego"; + case 24: + return "Tucuman"; + default: + return NULL; + } +} + +static const char *get_region_name_AT(int region_code) { + switch (region_code) { + case 1: + return "Burgenland"; + case 2: + return "Karnten"; + case 3: + return "Niederosterreich"; + case 4: + return "Oberosterreich"; + case 5: + return "Salzburg"; + case 6: + return "Steiermark"; + case 7: + return "Tirol"; + case 8: + return "Vorarlberg"; + case 9: + return "Wien"; + default: + return NULL; + } +} + +static const char *get_region_name_AU(int region_code) { + switch (region_code) { + case 1: + return "Australian Capital Territory"; + case 2: + return "New South Wales"; + case 3: + return "Northern Territory"; + case 4: + return "Queensland"; + case 5: + return "South Australia"; + case 6: + return "Tasmania"; + case 7: + return "Victoria"; + case 8: + return "Western Australia"; + default: + return NULL; + } +} + +static const char *get_region_name_AZ(int region_code) { + switch (region_code) { + case 1: + return "Abseron"; + case 2: + return "Agcabadi"; + case 3: + return "Agdam"; + case 4: + return "Agdas"; + case 5: + return "Agstafa"; + case 6: + return "Agsu"; + case 7: + return "Ali Bayramli"; + case 8: + return "Astara"; + case 9: + return "Baki"; + case 10: + return "Balakan"; + case 11: + return "Barda"; + case 12: + return "Beylaqan"; + case 13: + return "Bilasuvar"; + case 14: + return "Cabrayil"; + case 15: + return "Calilabad"; + case 16: + return "Daskasan"; + case 17: + return "Davaci"; + case 18: + return "Fuzuli"; + case 19: + return "Gadabay"; + case 20: + return "Ganca"; + case 21: + return "Goranboy"; + case 22: + return "Goycay"; + case 23: + return "Haciqabul"; + case 24: + return "Imisli"; + case 25: + return "Ismayilli"; + case 26: + return "Kalbacar"; + case 27: + return "Kurdamir"; + case 28: + return "Lacin"; + case 29: + return "Lankaran"; + case 30: + return "Lankaran"; + case 31: + return "Lerik"; + case 32: + return "Masalli"; + case 33: + return "Mingacevir"; + case 34: + return "Naftalan"; + case 35: + return "Naxcivan"; + case 36: + return "Neftcala"; + case 37: + return "Oguz"; + case 38: + return "Qabala"; + case 39: + return "Qax"; + case 40: + return "Qazax"; + case 41: + return "Qobustan"; + case 42: + return "Quba"; + case 43: + return "Qubadli"; + case 44: + return "Qusar"; + case 45: + return "Saatli"; + case 46: + return "Sabirabad"; + case 47: + return "Saki"; + case 48: + return "Saki"; + case 49: + return "Salyan"; + case 50: + return "Samaxi"; + case 51: + return "Samkir"; + case 52: + return "Samux"; + case 53: + return "Siyazan"; + case 54: + return "Sumqayit"; + case 55: + return "Susa"; + case 56: + return "Susa"; + case 57: + return "Tartar"; + case 58: + return "Tovuz"; + case 59: + return "Ucar"; + case 60: + return "Xacmaz"; + case 61: + return "Xankandi"; + case 62: + return "Xanlar"; + case 63: + return "Xizi"; + case 64: + return "Xocali"; + case 65: + return "Xocavand"; + case 66: + return "Yardimli"; + case 67: + return "Yevlax"; + case 68: + return "Yevlax"; + case 69: + return "Zangilan"; + case 70: + return "Zaqatala"; + case 71: + return "Zardab"; + default: + return NULL; + } +} + +static const char *get_region_name_BA(int region_code) { + switch (region_code) { + case 1: + return "Federation of Bosnia and Herzegovina"; + case 3: + return "Brcko District"; + case 2: + return "Republika Srpska"; + default: + return NULL; + } +} + +static const char *get_region_name_BB(int region_code) { + switch (region_code) { + case 1: + return "Christ Church"; + case 2: + return "Saint Andrew"; + case 3: + return "Saint George"; + case 4: + return "Saint James"; + case 5: + return "Saint John"; + case 6: + return "Saint Joseph"; + case 7: + return "Saint Lucy"; + case 8: + return "Saint Michael"; + case 9: + return "Saint Peter"; + case 10: + return "Saint Philip"; + case 11: + return "Saint Thomas"; + default: + return NULL; + } +} + +static const char *get_region_name_BD(int region_code) { + switch (region_code) { + case 81: + return "Dhaka"; + case 82: + return "Khulna"; + case 83: + return "Rajshahi"; + case 84: + return "Chittagong"; + case 85: + return "Barisal"; + case 86: + return "Sylhet"; + case 87: + return "Rangpur"; + default: + return NULL; + } +} + +static const char *get_region_name_BE(int region_code) { + switch (region_code) { + case 1: + return "Antwerpen"; + case 3: + return "Hainaut"; + case 4: + return "Liege"; + case 5: + return "Limburg"; + case 6: + return "Luxembourg"; + case 7: + return "Namur"; + case 8: + return "Oost-Vlaanderen"; + case 9: + return "West-Vlaanderen"; + case 10: + return "Brabant Wallon"; + case 11: + return "Brussels Hoofdstedelijk Gewest"; + case 12: + return "Vlaams-Brabant"; + case 13: + return "Flanders"; + case 14: + return "Wallonia"; + default: + return NULL; + } +} + +static const char *get_region_name_BF(int region_code) { + switch (region_code) { + case 15: + return "Bam"; + case 19: + return "Boulkiemde"; + case 20: + return "Ganzourgou"; + case 21: + return "Gnagna"; + case 28: + return "Kouritenga"; + case 33: + return "Oudalan"; + case 34: + return "Passore"; + case 36: + return "Sanguie"; + case 40: + return "Soum"; + case 42: + return "Tapoa"; + case 44: + return "Zoundweogo"; + case 45: + return "Bale"; + case 46: + return "Banwa"; + case 47: + return "Bazega"; + case 48: + return "Bougouriba"; + case 49: + return "Boulgou"; + case 50: + return "Gourma"; + case 51: + return "Houet"; + case 52: + return "Ioba"; + case 53: + return "Kadiogo"; + case 54: + return "Kenedougou"; + case 55: + return "Komoe"; + case 56: + return "Komondjari"; + case 57: + return "Kompienga"; + case 58: + return "Kossi"; + case 59: + return "Koulpelogo"; + case 60: + return "Kourweogo"; + case 61: + return "Leraba"; + case 62: + return "Loroum"; + case 63: + return "Mouhoun"; + case 64: + return "Namentenga"; + case 65: + return "Naouri"; + case 66: + return "Nayala"; + case 67: + return "Noumbiel"; + case 68: + return "Oubritenga"; + case 69: + return "Poni"; + case 70: + return "Sanmatenga"; + case 71: + return "Seno"; + case 72: + return "Sissili"; + case 73: + return "Sourou"; + case 74: + return "Tuy"; + case 75: + return "Yagha"; + case 76: + return "Yatenga"; + case 77: + return "Ziro"; + case 78: + return "Zondoma"; + default: + return NULL; + } +} + +static const char *get_region_name_BG(int region_code) { + switch (region_code) { + case 33: + return "Mikhaylovgrad"; + case 38: + return "Blagoevgrad"; + case 39: + return "Burgas"; + case 40: + return "Dobrich"; + case 41: + return "Gabrovo"; + case 42: + return "Grad Sofiya"; + case 43: + return "Khaskovo"; + case 44: + return "Kurdzhali"; + case 45: + return "Kyustendil"; + case 46: + return "Lovech"; + case 47: + return "Montana"; + case 48: + return "Pazardzhik"; + case 49: + return "Pernik"; + case 50: + return "Pleven"; + case 51: + return "Plovdiv"; + case 52: + return "Razgrad"; + case 53: + return "Ruse"; + case 54: + return "Shumen"; + case 55: + return "Silistra"; + case 56: + return "Sliven"; + case 57: + return "Smolyan"; + case 58: + return "Sofiya"; + case 59: + return "Stara Zagora"; + case 60: + return "Turgovishte"; + case 61: + return "Varna"; + case 62: + return "Veliko Turnovo"; + case 63: + return "Vidin"; + case 64: + return "Vratsa"; + case 65: + return "Yambol"; + default: + return NULL; + } +} + +static const char *get_region_name_BH(int region_code) { + switch (region_code) { + case 1: + return "Al Hadd"; + case 2: + return "Al Manamah"; + case 5: + return "Jidd Hafs"; + case 6: + return "Sitrah"; + case 8: + return "Al Mintaqah al Gharbiyah"; + case 9: + return "Mintaqat Juzur Hawar"; + case 10: + return "Al Mintaqah ash Shamaliyah"; + case 11: + return "Al Mintaqah al Wusta"; + case 12: + return "Madinat"; + case 13: + return "Ar Rifa"; + case 14: + return "Madinat Hamad"; + case 15: + return "Al Muharraq"; + case 16: + return "Al Asimah"; + case 17: + return "Al Janubiyah"; + case 18: + return "Ash Shamaliyah"; + case 19: + return "Al Wusta"; + default: + return NULL; + } +} + +static const char *get_region_name_BI(int region_code) { + switch (region_code) { + case 2: + return "Bujumbura"; + case 9: + return "Bubanza"; + case 10: + return "Bururi"; + case 11: + return "Cankuzo"; + case 12: + return "Cibitoke"; + case 13: + return "Gitega"; + case 14: + return "Karuzi"; + case 15: + return "Kayanza"; + case 16: + return "Kirundo"; + case 17: + return "Makamba"; + case 18: + return "Muyinga"; + case 19: + return "Ngozi"; + case 20: + return "Rutana"; + case 21: + return "Ruyigi"; + case 22: + return "Muramvya"; + case 23: + return "Mwaro"; + default: + return NULL; + } +} + +static const char *get_region_name_BJ(int region_code) { + switch (region_code) { + case 7: + return "Alibori"; + case 8: + return "Atakora"; + case 9: + return "Atlanyique"; + case 10: + return "Borgou"; + case 11: + return "Collines"; + case 12: + return "Kouffo"; + case 13: + return "Donga"; + case 14: + return "Littoral"; + case 15: + return "Mono"; + case 16: + return "Oueme"; + case 17: + return "Plateau"; + case 18: + return "Zou"; + default: + return NULL; + } +} + +static const char *get_region_name_BM(int region_code) { + switch (region_code) { + case 1: + return "Devonshire"; + case 2: + return "Hamilton"; + case 3: + return "Hamilton"; + case 4: + return "Paget"; + case 5: + return "Pembroke"; + case 6: + return "Saint George"; + case 7: + return "Saint George's"; + case 8: + return "Sandys"; + case 9: + return "Smiths"; + case 10: + return "Southampton"; + case 11: + return "Warwick"; + default: + return NULL; + } +} + +static const char *get_region_name_BN(int region_code) { + switch (region_code) { + case 7: + return "Alibori"; + case 8: + return "Belait"; + case 9: + return "Brunei and Muara"; + case 10: + return "Temburong"; + case 11: + return "Collines"; + case 12: + return "Kouffo"; + case 13: + return "Donga"; + case 14: + return "Littoral"; + case 15: + return "Tutong"; + case 16: + return "Oueme"; + case 17: + return "Plateau"; + case 18: + return "Zou"; + default: + return NULL; + } +} + +static const char *get_region_name_BO(int region_code) { + switch (region_code) { + case 1: + return "Chuquisaca"; + case 2: + return "Cochabamba"; + case 3: + return "El Beni"; + case 4: + return "La Paz"; + case 5: + return "Oruro"; + case 6: + return "Pando"; + case 7: + return "Potosi"; + case 8: + return "Santa Cruz"; + case 9: + return "Tarija"; + default: + return NULL; + } +} + +static const char *get_region_name_BR(int region_code) { + switch (region_code) { + case 1: + return "Acre"; + case 2: + return "Alagoas"; + case 3: + return "Amapa"; + case 4: + return "Amazonas"; + case 5: + return "Bahia"; + case 6: + return "Ceara"; + case 7: + return "Distrito Federal"; + case 8: + return "Espirito Santo"; + case 11: + return "Mato Grosso do Sul"; + case 13: + return "Maranhao"; + case 14: + return "Mato Grosso"; + case 15: + return "Minas Gerais"; + case 16: + return "Para"; + case 17: + return "Paraiba"; + case 18: + return "Parana"; + case 20: + return "Piaui"; + case 21: + return "Rio de Janeiro"; + case 22: + return "Rio Grande do Norte"; + case 23: + return "Rio Grande do Sul"; + case 24: + return "Rondonia"; + case 25: + return "Roraima"; + case 26: + return "Santa Catarina"; + case 27: + return "Sao Paulo"; + case 28: + return "Sergipe"; + case 29: + return "Goias"; + case 30: + return "Pernambuco"; + case 31: + return "Tocantins"; + default: + return NULL; + } +} + +static const char *get_region_name_BS(int region_code) { + switch (region_code) { + case 5: + return "Bimini"; + case 6: + return "Cat Island"; + case 10: + return "Exuma"; + case 13: + return "Inagua"; + case 15: + return "Long Island"; + case 16: + return "Mayaguana"; + case 18: + return "Ragged Island"; + case 22: + return "Harbour Island"; + case 23: + return "New Providence"; + case 24: + return "Acklins and Crooked Islands"; + case 25: + return "Freeport"; + case 26: + return "Fresh Creek"; + case 27: + return "Governor's Harbour"; + case 28: + return "Green Turtle Cay"; + case 29: + return "High Rock"; + case 30: + return "Kemps Bay"; + case 31: + return "Marsh Harbour"; + case 32: + return "Nichollstown and Berry Islands"; + case 33: + return "Rock Sound"; + case 34: + return "Sandy Point"; + case 35: + return "San Salvador and Rum Cay"; + default: + return NULL; + } +} + +static const char *get_region_name_BT(int region_code) { + switch (region_code) { + case 5: + return "Bumthang"; + case 6: + return "Chhukha"; + case 7: + return "Chirang"; + case 8: + return "Daga"; + case 9: + return "Geylegphug"; + case 10: + return "Ha"; + case 11: + return "Lhuntshi"; + case 12: + return "Mongar"; + case 13: + return "Paro"; + case 14: + return "Pemagatsel"; + case 15: + return "Punakha"; + case 16: + return "Samchi"; + case 17: + return "Samdrup"; + case 18: + return "Shemgang"; + case 19: + return "Tashigang"; + case 20: + return "Thimphu"; + case 21: + return "Tongsa"; + case 22: + return "Wangdi Phodrang"; + default: + return NULL; + } +} + +static const char *get_region_name_BW(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 3: + return "Ghanzi"; + case 4: + return "Kgalagadi"; + case 5: + return "Kgatleng"; + case 6: + return "Kweneng"; + case 8: + return "North-East"; + case 9: + return "South-East"; + case 10: + return "Southern"; + case 11: + return "North-West"; + default: + return NULL; + } +} + +static const char *get_region_name_BY(int region_code) { + switch (region_code) { + case 1: + return "Brestskaya Voblasts'"; + case 2: + return "Homyel'skaya Voblasts'"; + case 3: + return "Hrodzyenskaya Voblasts'"; + case 4: + return "Minsk"; + case 5: + return "Minskaya Voblasts'"; + case 6: + return "Mahilyowskaya Voblasts'"; + case 7: + return "Vitsyebskaya Voblasts'"; + default: + return NULL; + } +} + +static const char *get_region_name_BZ(int region_code) { + switch (region_code) { + case 1: + return "Belize"; + case 2: + return "Cayo"; + case 3: + return "Corozal"; + case 4: + return "Orange Walk"; + case 5: + return "Stann Creek"; + case 6: + return "Toledo"; + default: + return NULL; + } +} + +static const char *get_region_name_CA(int region_code) { + switch (region_code) { + case 849: + return "Alberta"; + case 893: + return "British Columbia"; + case 1365: + return "Manitoba"; + case 1408: + return "New Brunswick"; + case 1418: + return "Newfoundland"; + case 1425: + return "Nova Scotia"; + case 1426: + return "Northwest Territories"; + case 1427: + return "Nunavut"; + case 1463: + return "Ontario"; + case 1497: + return "Prince Edward Island"; + case 1538: + return "Quebec"; + case 1632: + return "Saskatchewan"; + case 1899: + return "Yukon Territory"; + default: + return NULL; + } +} + +static const char *get_region_name_CD(int region_code) { + switch (region_code) { + case 1: + return "Bandundu"; + case 2: + return "Equateur"; + case 4: + return "Kasai-Oriental"; + case 5: + return "Katanga"; + case 6: + return "Kinshasa"; + case 8: + return "Bas-Congo"; + case 9: + return "Orientale"; + case 10: + return "Maniema"; + case 11: + return "Nord-Kivu"; + case 12: + return "Sud-Kivu"; + default: + return NULL; + } +} + +static const char *get_region_name_CF(int region_code) { + switch (region_code) { + case 1: + return "Bamingui-Bangoran"; + case 2: + return "Basse-Kotto"; + case 3: + return "Haute-Kotto"; + case 4: + return "Mambere-Kadei"; + case 5: + return "Haut-Mbomou"; + case 6: + return "Kemo"; + case 7: + return "Lobaye"; + case 8: + return "Mbomou"; + case 9: + return "Nana-Mambere"; + case 11: + return "Ouaka"; + case 12: + return "Ouham"; + case 13: + return "Ouham-Pende"; + case 14: + return "Cuvette-Ouest"; + case 15: + return "Nana-Grebizi"; + case 16: + return "Sangha-Mbaere"; + case 17: + return "Ombella-Mpoko"; + case 18: + return "Bangui"; + default: + return NULL; + } +} + +static const char *get_region_name_CG(int region_code) { + switch (region_code) { + case 1: + return "Bouenza"; + case 4: + return "Kouilou"; + case 5: + return "Lekoumou"; + case 6: + return "Likouala"; + case 7: + return "Niari"; + case 8: + return "Plateaux"; + case 10: + return "Sangha"; + case 11: + return "Pool"; + case 12: + return "Brazzaville"; + case 13: + return "Cuvette"; + case 14: + return "Cuvette-Ouest"; + default: + return NULL; + } +} + +static const char *get_region_name_CH(int region_code) { + switch (region_code) { + case 1: + return "Aargau"; + case 2: + return "Ausser-Rhoden"; + case 3: + return "Basel-Landschaft"; + case 4: + return "Basel-Stadt"; + case 5: + return "Bern"; + case 6: + return "Fribourg"; + case 7: + return "Geneve"; + case 8: + return "Glarus"; + case 9: + return "Graubunden"; + case 10: + return "Inner-Rhoden"; + case 11: + return "Luzern"; + case 12: + return "Neuchatel"; + case 13: + return "Nidwalden"; + case 14: + return "Obwalden"; + case 15: + return "Sankt Gallen"; + case 16: + return "Schaffhausen"; + case 17: + return "Schwyz"; + case 18: + return "Solothurn"; + case 19: + return "Thurgau"; + case 20: + return "Ticino"; + case 21: + return "Uri"; + case 22: + return "Valais"; + case 23: + return "Vaud"; + case 24: + return "Zug"; + case 25: + return "Zurich"; + case 26: + return "Jura"; + default: + return NULL; + } +} + +static const char *get_region_name_CI(int region_code) { + switch (region_code) { + case 74: + return "Agneby"; + case 75: + return "Bafing"; + case 76: + return "Bas-Sassandra"; + case 77: + return "Denguele"; + case 78: + return "Dix-Huit Montagnes"; + case 79: + return "Fromager"; + case 80: + return "Haut-Sassandra"; + case 81: + return "Lacs"; + case 82: + return "Lagunes"; + case 83: + return "Marahoue"; + case 84: + return "Moyen-Cavally"; + case 85: + return "Moyen-Comoe"; + case 86: + return "N'zi-Comoe"; + case 87: + return "Savanes"; + case 88: + return "Sud-Bandama"; + case 89: + return "Sud-Comoe"; + case 90: + return "Vallee du Bandama"; + case 91: + return "Worodougou"; + case 92: + return "Zanzan"; + default: + return NULL; + } +} + +static const char *get_region_name_CL(int region_code) { + switch (region_code) { + case 1: + return "Valparaiso"; + case 2: + return "Aisen del General Carlos Ibanez del Campo"; + case 3: + return "Antofagasta"; + case 4: + return "Araucania"; + case 5: + return "Atacama"; + case 6: + return "Bio-Bio"; + case 7: + return "Coquimbo"; + case 8: + return "Libertador General Bernardo O'Higgins"; + case 9: + return "Los Lagos"; + case 10: + return "Magallanes y de la Antartica Chilena"; + case 11: + return "Maule"; + case 12: + return "Region Metropolitana"; + case 13: + return "Tarapaca"; + case 14: + return "Los Lagos"; + case 15: + return "Tarapaca"; + case 16: + return "Arica y Parinacota"; + case 17: + return "Los Rios"; + default: + return NULL; + } +} + +static const char *get_region_name_CM(int region_code) { + switch (region_code) { + case 4: + return "Est"; + case 5: + return "Littoral"; + case 7: + return "Nord-Ouest"; + case 8: + return "Ouest"; + case 9: + return "Sud-Ouest"; + case 10: + return "Adamaoua"; + case 11: + return "Centre"; + case 12: + return "Extreme-Nord"; + case 13: + return "Nord"; + case 14: + return "Sud"; + default: + return NULL; + } +} + +static const char *get_region_name_CN(int region_code) { + switch (region_code) { + case 1: + return "Anhui"; + case 2: + return "Zhejiang"; + case 3: + return "Jiangxi"; + case 4: + return "Jiangsu"; + case 5: + return "Jilin"; + case 6: + return "Qinghai"; + case 7: + return "Fujian"; + case 8: + return "Heilongjiang"; + case 9: + return "Henan"; + case 10: + return "Hebei"; + case 11: + return "Hunan"; + case 12: + return "Hubei"; + case 13: + return "Xinjiang"; + case 14: + return "Xizang"; + case 15: + return "Gansu"; + case 16: + return "Guangxi"; + case 18: + return "Guizhou"; + case 19: + return "Liaoning"; + case 20: + return "Nei Mongol"; + case 21: + return "Ningxia"; + case 22: + return "Beijing"; + case 23: + return "Shanghai"; + case 24: + return "Shanxi"; + case 25: + return "Shandong"; + case 26: + return "Shaanxi"; + case 28: + return "Tianjin"; + case 29: + return "Yunnan"; + case 30: + return "Guangdong"; + case 31: + return "Hainan"; + case 32: + return "Sichuan"; + case 33: + return "Chongqing"; + default: + return NULL; + } +} + +static const char *get_region_name_CO(int region_code) { + switch (region_code) { + case 1: + return "Amazonas"; + case 2: + return "Antioquia"; + case 3: + return "Arauca"; + case 4: + return "Atlantico"; + case 8: + return "Caqueta"; + case 9: + return "Cauca"; + case 10: + return "Cesar"; + case 11: + return "Choco"; + case 12: + return "Cordoba"; + case 14: + return "Guaviare"; + case 15: + return "Guainia"; + case 16: + return "Huila"; + case 17: + return "La Guajira"; + case 19: + return "Meta"; + case 20: + return "Narino"; + case 21: + return "Norte de Santander"; + case 22: + return "Putumayo"; + case 23: + return "Quindio"; + case 24: + return "Risaralda"; + case 25: + return "San Andres y Providencia"; + case 26: + return "Santander"; + case 27: + return "Sucre"; + case 28: + return "Tolima"; + case 29: + return "Valle del Cauca"; + case 30: + return "Vaupes"; + case 31: + return "Vichada"; + case 32: + return "Casanare"; + case 33: + return "Cundinamarca"; + case 34: + return "Distrito Especial"; + case 35: + return "Bolivar"; + case 36: + return "Boyaca"; + case 37: + return "Caldas"; + case 38: + return "Magdalena"; + default: + return NULL; + } +} + +static const char *get_region_name_CR(int region_code) { + switch (region_code) { + case 1: + return "Alajuela"; + case 2: + return "Cartago"; + case 3: + return "Guanacaste"; + case 4: + return "Heredia"; + case 6: + return "Limon"; + case 7: + return "Puntarenas"; + case 8: + return "San Jose"; + default: + return NULL; + } +} + +static const char *get_region_name_CU(int region_code) { + switch (region_code) { + case 1: + return "Pinar del Rio"; + case 2: + return "Ciudad de la Habana"; + case 3: + return "Matanzas"; + case 4: + return "Isla de la Juventud"; + case 5: + return "Camaguey"; + case 7: + return "Ciego de Avila"; + case 8: + return "Cienfuegos"; + case 9: + return "Granma"; + case 10: + return "Guantanamo"; + case 11: + return "La Habana"; + case 12: + return "Holguin"; + case 13: + return "Las Tunas"; + case 14: + return "Sancti Spiritus"; + case 15: + return "Santiago de Cuba"; + case 16: + return "Villa Clara"; + default: + return NULL; + } +} + +static const char *get_region_name_CV(int region_code) { + switch (region_code) { + case 1: + return "Boa Vista"; + case 2: + return "Brava"; + case 4: + return "Maio"; + case 5: + return "Paul"; + case 7: + return "Ribeira Grande"; + case 8: + return "Sal"; + case 10: + return "Sao Nicolau"; + case 11: + return "Sao Vicente"; + case 13: + return "Mosteiros"; + case 14: + return "Praia"; + case 15: + return "Santa Catarina"; + case 16: + return "Santa Cruz"; + case 17: + return "Sao Domingos"; + case 18: + return "Sao Filipe"; + case 19: + return "Sao Miguel"; + case 20: + return "Tarrafal"; + default: + return NULL; + } +} + +static const char *get_region_name_CY(int region_code) { + switch (region_code) { + case 1: + return "Famagusta"; + case 2: + return "Kyrenia"; + case 3: + return "Larnaca"; + case 4: + return "Nicosia"; + case 5: + return "Limassol"; + case 6: + return "Paphos"; + default: + return NULL; + } +} + +static const char *get_region_name_CZ(int region_code) { + switch (region_code) { + case 52: + return "Hlavni mesto Praha"; + case 78: + return "Jihomoravsky kraj"; + case 79: + return "Jihocesky kraj"; + case 80: + return "Vysocina"; + case 81: + return "Karlovarsky kraj"; + case 82: + return "Kralovehradecky kraj"; + case 83: + return "Liberecky kraj"; + case 84: + return "Olomoucky kraj"; + case 85: + return "Moravskoslezsky kraj"; + case 86: + return "Pardubicky kraj"; + case 87: + return "Plzensky kraj"; + case 88: + return "Stredocesky kraj"; + case 89: + return "Ustecky kraj"; + case 90: + return "Zlinsky kraj"; + default: + return NULL; + } +} + +static const char *get_region_name_DE(int region_code) { + switch (region_code) { + case 1: + return "Baden-Wurttemberg"; + case 2: + return "Bayern"; + case 3: + return "Bremen"; + case 4: + return "Hamburg"; + case 5: + return "Hessen"; + case 6: + return "Niedersachsen"; + case 7: + return "Nordrhein-Westfalen"; + case 8: + return "Rheinland-Pfalz"; + case 9: + return "Saarland"; + case 10: + return "Schleswig-Holstein"; + case 11: + return "Brandenburg"; + case 12: + return "Mecklenburg-Vorpommern"; + case 13: + return "Sachsen"; + case 14: + return "Sachsen-Anhalt"; + case 15: + return "Thuringen"; + case 16: + return "Berlin"; + default: + return NULL; + } +} + +static const char *get_region_name_DJ(int region_code) { + switch (region_code) { + case 1: + return "Ali Sabieh"; + case 4: + return "Obock"; + case 5: + return "Tadjoura"; + case 6: + return "Dikhil"; + case 7: + return "Djibouti"; + case 8: + return "Arta"; + default: + return NULL; + } +} + +static const char *get_region_name_DK(int region_code) { + switch (region_code) { + case 17: + return "Hovedstaden"; + case 18: + return "Midtjylland"; + case 19: + return "Nordjylland"; + case 20: + return "Sjelland"; + case 21: + return "Syddanmark"; + default: + return NULL; + } +} + +static const char *get_region_name_DM(int region_code) { + switch (region_code) { + case 2: + return "Saint Andrew"; + case 3: + return "Saint David"; + case 4: + return "Saint George"; + case 5: + return "Saint John"; + case 6: + return "Saint Joseph"; + case 7: + return "Saint Luke"; + case 8: + return "Saint Mark"; + case 9: + return "Saint Patrick"; + case 10: + return "Saint Paul"; + case 11: + return "Saint Peter"; + default: + return NULL; + } +} + +static const char *get_region_name_DO(int region_code) { + switch (region_code) { + case 1: + return "Azua"; + case 2: + return "Baoruco"; + case 3: + return "Barahona"; + case 4: + return "Dajabon"; + case 5: + return "Distrito Nacional"; + case 6: + return "Duarte"; + case 8: + return "Espaillat"; + case 9: + return "Independencia"; + case 10: + return "La Altagracia"; + case 11: + return "Elias Pina"; + case 12: + return "La Romana"; + case 14: + return "Maria Trinidad Sanchez"; + case 15: + return "Monte Cristi"; + case 16: + return "Pedernales"; + case 17: + return "Peravia"; + case 18: + return "Puerto Plata"; + case 19: + return "Salcedo"; + case 20: + return "Samana"; + case 21: + return "Sanchez Ramirez"; + case 23: + return "San Juan"; + case 24: + return "San Pedro De Macoris"; + case 25: + return "Santiago"; + case 26: + return "Santiago Rodriguez"; + case 27: + return "Valverde"; + case 28: + return "El Seibo"; + case 29: + return "Hato Mayor"; + case 30: + return "La Vega"; + case 31: + return "Monsenor Nouel"; + case 32: + return "Monte Plata"; + case 33: + return "San Cristobal"; + case 34: + return "Distrito Nacional"; + case 35: + return "Peravia"; + case 36: + return "San Jose de Ocoa"; + case 37: + return "Santo Domingo"; + default: + return NULL; + } +} + +static const char *get_region_name_DZ(int region_code) { + switch (region_code) { + case 1: + return "Alger"; + case 3: + return "Batna"; + case 4: + return "Constantine"; + case 6: + return "Medea"; + case 7: + return "Mostaganem"; + case 9: + return "Oran"; + case 10: + return "Saida"; + case 12: + return "Setif"; + case 13: + return "Tiaret"; + case 14: + return "Tizi Ouzou"; + case 15: + return "Tlemcen"; + case 18: + return "Bejaia"; + case 19: + return "Biskra"; + case 20: + return "Blida"; + case 21: + return "Bouira"; + case 22: + return "Djelfa"; + case 23: + return "Guelma"; + case 24: + return "Jijel"; + case 25: + return "Laghouat"; + case 26: + return "Mascara"; + case 27: + return "M'sila"; + case 29: + return "Oum el Bouaghi"; + case 30: + return "Sidi Bel Abbes"; + case 31: + return "Skikda"; + case 33: + return "Tebessa"; + case 34: + return "Adrar"; + case 35: + return "Ain Defla"; + case 36: + return "Ain Temouchent"; + case 37: + return "Annaba"; + case 38: + return "Bechar"; + case 39: + return "Bordj Bou Arreridj"; + case 40: + return "Boumerdes"; + case 41: + return "Chlef"; + case 42: + return "El Bayadh"; + case 43: + return "El Oued"; + case 44: + return "El Tarf"; + case 45: + return "Ghardaia"; + case 46: + return "Illizi"; + case 47: + return "Khenchela"; + case 48: + return "Mila"; + case 49: + return "Naama"; + case 50: + return "Ouargla"; + case 51: + return "Relizane"; + case 52: + return "Souk Ahras"; + case 53: + return "Tamanghasset"; + case 54: + return "Tindouf"; + case 55: + return "Tipaza"; + case 56: + return "Tissemsilt"; + default: + return NULL; + } +} + +static const char *get_region_name_EC(int region_code) { + switch (region_code) { + case 1: + return "Galapagos"; + case 2: + return "Azuay"; + case 3: + return "Bolivar"; + case 4: + return "Canar"; + case 5: + return "Carchi"; + case 6: + return "Chimborazo"; + case 7: + return "Cotopaxi"; + case 8: + return "El Oro"; + case 9: + return "Esmeraldas"; + case 10: + return "Guayas"; + case 11: + return "Imbabura"; + case 12: + return "Loja"; + case 13: + return "Los Rios"; + case 14: + return "Manabi"; + case 15: + return "Morona-Santiago"; + case 17: + return "Pastaza"; + case 18: + return "Pichincha"; + case 19: + return "Tungurahua"; + case 20: + return "Zamora-Chinchipe"; + case 22: + return "Sucumbios"; + case 23: + return "Napo"; + case 24: + return "Orellana"; + default: + return NULL; + } +} + +static const char *get_region_name_EE(int region_code) { + switch (region_code) { + case 1: + return "Harjumaa"; + case 2: + return "Hiiumaa"; + case 3: + return "Ida-Virumaa"; + case 4: + return "Jarvamaa"; + case 5: + return "Jogevamaa"; + case 6: + return "Kohtla-Jarve"; + case 7: + return "Laanemaa"; + case 8: + return "Laane-Virumaa"; + case 9: + return "Narva"; + case 10: + return "Parnu"; + case 11: + return "Parnumaa"; + case 12: + return "Polvamaa"; + case 13: + return "Raplamaa"; + case 14: + return "Saaremaa"; + case 15: + return "Sillamae"; + case 16: + return "Tallinn"; + case 17: + return "Tartu"; + case 18: + return "Tartumaa"; + case 19: + return "Valgamaa"; + case 20: + return "Viljandimaa"; + case 21: + return "Vorumaa"; + default: + return NULL; + } +} + +static const char *get_region_name_EG(int region_code) { + switch (region_code) { + case 1: + return "Ad Daqahliyah"; + case 2: + return "Al Bahr al Ahmar"; + case 3: + return "Al Buhayrah"; + case 4: + return "Al Fayyum"; + case 5: + return "Al Gharbiyah"; + case 6: + return "Al Iskandariyah"; + case 7: + return "Al Isma'iliyah"; + case 8: + return "Al Jizah"; + case 9: + return "Al Minufiyah"; + case 10: + return "Al Minya"; + case 11: + return "Al Qahirah"; + case 12: + return "Al Qalyubiyah"; + case 13: + return "Al Wadi al Jadid"; + case 14: + return "Ash Sharqiyah"; + case 15: + return "As Suways"; + case 16: + return "Aswan"; + case 17: + return "Asyut"; + case 18: + return "Bani Suwayf"; + case 19: + return "Bur Sa'id"; + case 20: + return "Dumyat"; + case 21: + return "Kafr ash Shaykh"; + case 22: + return "Matruh"; + case 23: + return "Qina"; + case 24: + return "Suhaj"; + case 26: + return "Janub Sina'"; + case 27: + return "Shamal Sina'"; + case 28: + return "Al Uqsur"; + default: + return NULL; + } +} + +static const char *get_region_name_ER(int region_code) { + switch (region_code) { + case 1: + return "Anseba"; + case 2: + return "Debub"; + case 3: + return "Debubawi K'eyih Bahri"; + case 4: + return "Gash Barka"; + case 5: + return "Ma'akel"; + case 6: + return "Semenawi K'eyih Bahri"; + default: + return NULL; + } +} + +static const char *get_region_name_ES(int region_code) { + switch (region_code) { + case 7: + return "Islas Baleares"; + case 27: + return "La Rioja"; + case 29: + return "Madrid"; + case 31: + return "Murcia"; + case 32: + return "Navarra"; + case 34: + return "Asturias"; + case 39: + return "Cantabria"; + case 51: + return "Andalucia"; + case 52: + return "Aragon"; + case 53: + return "Canarias"; + case 54: + return "Castilla-La Mancha"; + case 55: + return "Castilla y Leon"; + case 56: + return "Catalonia"; + case 57: + return "Extremadura"; + case 58: + return "Galicia"; + case 59: + return "Pais Vasco"; + case 60: + return "Comunidad Valenciana"; + default: + return NULL; + } +} + +static const char *get_region_name_ET(int region_code) { + switch (region_code) { + case 44: + return "Adis Abeba"; + case 45: + return "Afar"; + case 46: + return "Amara"; + case 47: + return "Binshangul Gumuz"; + case 48: + return "Dire Dawa"; + case 49: + return "Gambela Hizboch"; + case 50: + return "Hareri Hizb"; + case 51: + return "Oromiya"; + case 52: + return "Sumale"; + case 53: + return "Tigray"; + case 54: + return "YeDebub Biheroch Bihereseboch na Hizboch"; + default: + return NULL; + } +} + +static const char *get_region_name_FI(int region_code) { + switch (region_code) { + case 1: + return "Aland"; + case 6: + return "Lapland"; + case 8: + return "Oulu"; + case 13: + return "Southern Finland"; + case 14: + return "Eastern Finland"; + case 15: + return "Western Finland"; + default: + return NULL; + } +} + +static const char *get_region_name_FJ(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 2: + return "Eastern"; + case 3: + return "Northern"; + case 4: + return "Rotuma"; + case 5: + return "Western"; + default: + return NULL; + } +} + +static const char *get_region_name_FM(int region_code) { + switch (region_code) { + case 1: + return "Kosrae"; + case 2: + return "Pohnpei"; + case 3: + return "Chuuk"; + case 4: + return "Yap"; + default: + return NULL; + } +} + +static const char *get_region_name_FR(int region_code) { + switch (region_code) { + case 97: + return "Aquitaine"; + case 98: + return "Auvergne"; + case 99: + return "Basse-Normandie"; + case 832: + return "Bourgogne"; + case 833: + return "Bretagne"; + case 834: + return "Centre"; + case 835: + return "Champagne-Ardenne"; + case 836: + return "Corse"; + case 837: + return "Franche-Comte"; + case 838: + return "Haute-Normandie"; + case 839: + return "Ile-de-France"; + case 840: + return "Languedoc-Roussillon"; + case 875: + return "Limousin"; + case 876: + return "Lorraine"; + case 877: + return "Midi-Pyrenees"; + case 878: + return "Nord-Pas-de-Calais"; + case 879: + return "Pays de la Loire"; + case 880: + return "Picardie"; + case 881: + return "Poitou-Charentes"; + case 882: + return "Provence-Alpes-Cote d'Azur"; + case 883: + return "Rhone-Alpes"; + case 918: + return "Alsace"; + default: + return NULL; + } +} + +static const char *get_region_name_GA(int region_code) { + switch (region_code) { + case 1: + return "Estuaire"; + case 2: + return "Haut-Ogooue"; + case 3: + return "Moyen-Ogooue"; + case 4: + return "Ngounie"; + case 5: + return "Nyanga"; + case 6: + return "Ogooue-Ivindo"; + case 7: + return "Ogooue-Lolo"; + case 8: + return "Ogooue-Maritime"; + case 9: + return "Woleu-Ntem"; + default: + return NULL; + } +} + +static const char *get_region_name_GB(int region_code) { + switch (region_code) { + case 832: + return "Barking and Dagenham"; + case 833: + return "Barnet"; + case 834: + return "Barnsley"; + case 835: + return "Bath and North East Somerset"; + case 836: + return "Bedfordshire"; + case 837: + return "Bexley"; + case 838: + return "Birmingham"; + case 839: + return "Blackburn with Darwen"; + case 840: + return "Blackpool"; + case 875: + return "Bolton"; + case 876: + return "Bournemouth"; + case 877: + return "Bracknell Forest"; + case 878: + return "Bradford"; + case 879: + return "Brent"; + case 880: + return "Brighton and Hove"; + case 881: + return "Bristol, City of"; + case 882: + return "Bromley"; + case 883: + return "Buckinghamshire"; + case 918: + return "Bury"; + case 919: + return "Calderdale"; + case 920: + return "Cambridgeshire"; + case 921: + return "Camden"; + case 922: + return "Cheshire"; + case 923: + return "Cornwall"; + case 924: + return "Coventry"; + case 925: + return "Croydon"; + case 926: + return "Cumbria"; + case 961: + return "Darlington"; + case 962: + return "Derby"; + case 963: + return "Derbyshire"; + case 964: + return "Devon"; + case 965: + return "Doncaster"; + case 966: + return "Dorset"; + case 967: + return "Dudley"; + case 968: + return "Durham"; + case 969: + return "Ealing"; + case 1004: + return "East Riding of Yorkshire"; + case 1005: + return "East Sussex"; + case 1006: + return "Enfield"; + case 1007: + return "Essex"; + case 1008: + return "Gateshead"; + case 1009: + return "Gloucestershire"; + case 1010: + return "Greenwich"; + case 1011: + return "Hackney"; + case 1012: + return "Halton"; + case 1047: + return "Hammersmith and Fulham"; + case 1048: + return "Hampshire"; + case 1049: + return "Haringey"; + case 1050: + return "Harrow"; + case 1051: + return "Hartlepool"; + case 1052: + return "Havering"; + case 1053: + return "Herefordshire"; + case 1054: + return "Hertford"; + case 1055: + return "Hillingdon"; + case 1090: + return "Hounslow"; + case 1091: + return "Isle of Wight"; + case 1092: + return "Islington"; + case 1093: + return "Kensington and Chelsea"; + case 1094: + return "Kent"; + case 1095: + return "Kingston upon Hull, City of"; + case 1096: + return "Kingston upon Thames"; + case 1097: + return "Kirklees"; + case 1098: + return "Knowsley"; + case 1133: + return "Lambeth"; + case 1134: + return "Lancashire"; + case 1135: + return "Leeds"; + case 1136: + return "Leicester"; + case 1137: + return "Leicestershire"; + case 1138: + return "Lewisham"; + case 1139: + return "Lincolnshire"; + case 1140: + return "Liverpool"; + case 1141: + return "London, City of"; + case 1176: + return "Luton"; + case 1177: + return "Manchester"; + case 1178: + return "Medway"; + case 1179: + return "Merton"; + case 1180: + return "Middlesbrough"; + case 1181: + return "Milton Keynes"; + case 1182: + return "Newcastle upon Tyne"; + case 1183: + return "Newham"; + case 1184: + return "Norfolk"; + case 1219: + return "Northamptonshire"; + case 1220: + return "North East Lincolnshire"; + case 1221: + return "North Lincolnshire"; + case 1222: + return "North Somerset"; + case 1223: + return "North Tyneside"; + case 1224: + return "Northumberland"; + case 1225: + return "North Yorkshire"; + case 1226: + return "Nottingham"; + case 1227: + return "Nottinghamshire"; + case 1262: + return "Oldham"; + case 1263: + return "Oxfordshire"; + case 1264: + return "Peterborough"; + case 1265: + return "Plymouth"; + case 1266: + return "Poole"; + case 1267: + return "Portsmouth"; + case 1268: + return "Reading"; + case 1269: + return "Redbridge"; + case 1270: + return "Redcar and Cleveland"; + case 1305: + return "Richmond upon Thames"; + case 1306: + return "Rochdale"; + case 1307: + return "Rotherham"; + case 1308: + return "Rutland"; + case 1309: + return "Salford"; + case 1310: + return "Shropshire"; + case 1311: + return "Sandwell"; + case 1312: + return "Sefton"; + case 1313: + return "Sheffield"; + case 1348: + return "Slough"; + case 1349: + return "Solihull"; + case 1350: + return "Somerset"; + case 1351: + return "Southampton"; + case 1352: + return "Southend-on-Sea"; + case 1353: + return "South Gloucestershire"; + case 1354: + return "South Tyneside"; + case 1355: + return "Southwark"; + case 1356: + return "Staffordshire"; + case 1391: + return "St. Helens"; + case 1392: + return "Stockport"; + case 1393: + return "Stockton-on-Tees"; + case 1394: + return "Stoke-on-Trent"; + case 1395: + return "Suffolk"; + case 1396: + return "Sunderland"; + case 1397: + return "Surrey"; + case 1398: + return "Sutton"; + case 1399: + return "Swindon"; + case 1434: + return "Tameside"; + case 1435: + return "Telford and Wrekin"; + case 1436: + return "Thurrock"; + case 1437: + return "Torbay"; + case 1438: + return "Tower Hamlets"; + case 1439: + return "Trafford"; + case 1440: + return "Wakefield"; + case 1441: + return "Walsall"; + case 1442: + return "Waltham Forest"; + case 1477: + return "Wandsworth"; + case 1478: + return "Warrington"; + case 1479: + return "Warwickshire"; + case 1480: + return "West Berkshire"; + case 1481: + return "Westminster"; + case 1482: + return "West Sussex"; + case 1483: + return "Wigan"; + case 1484: + return "Wiltshire"; + case 1485: + return "Windsor and Maidenhead"; + case 1520: + return "Wirral"; + case 1521: + return "Wokingham"; + case 1522: + return "Wolverhampton"; + case 1523: + return "Worcestershire"; + case 1524: + return "York"; + case 1525: + return "Antrim"; + case 1526: + return "Ards"; + case 1527: + return "Armagh"; + case 1528: + return "Ballymena"; + case 1563: + return "Ballymoney"; + case 1564: + return "Banbridge"; + case 1565: + return "Belfast"; + case 1566: + return "Carrickfergus"; + case 1567: + return "Castlereagh"; + case 1568: + return "Coleraine"; + case 1569: + return "Cookstown"; + case 1570: + return "Craigavon"; + case 1571: + return "Down"; + case 1606: + return "Dungannon"; + case 1607: + return "Fermanagh"; + case 1608: + return "Larne"; + case 1609: + return "Limavady"; + case 1610: + return "Lisburn"; + case 1611: + return "Derry"; + case 1612: + return "Magherafelt"; + case 1613: + return "Moyle"; + case 1614: + return "Newry and Mourne"; + case 1649: + return "Newtownabbey"; + case 1650: + return "North Down"; + case 1651: + return "Omagh"; + case 1652: + return "Strabane"; + case 1653: + return "Aberdeen City"; + case 1654: + return "Aberdeenshire"; + case 1655: + return "Angus"; + case 1656: + return "Argyll and Bute"; + case 1657: + return "Scottish Borders, The"; + case 1692: + return "Clackmannanshire"; + case 1693: + return "Dumfries and Galloway"; + case 1694: + return "Dundee City"; + case 1695: + return "East Ayrshire"; + case 1696: + return "East Dunbartonshire"; + case 1697: + return "East Lothian"; + case 1698: + return "East Renfrewshire"; + case 1699: + return "Edinburgh, City of"; + case 1700: + return "Falkirk"; + case 1735: + return "Fife"; + case 1736: + return "Glasgow City"; + case 1737: + return "Highland"; + case 1738: + return "Inverclyde"; + case 1739: + return "Midlothian"; + case 1740: + return "Moray"; + case 1741: + return "North Ayrshire"; + case 1742: + return "North Lanarkshire"; + case 1743: + return "Orkney"; + case 1778: + return "Perth and Kinross"; + case 1779: + return "Renfrewshire"; + case 1780: + return "Shetland Islands"; + case 1781: + return "South Ayrshire"; + case 1782: + return "South Lanarkshire"; + case 1783: + return "Stirling"; + case 1784: + return "West Dunbartonshire"; + case 1785: + return "Eilean Siar"; + case 1786: + return "West Lothian"; + case 1821: + return "Isle of Anglesey"; + case 1822: + return "Blaenau Gwent"; + case 1823: + return "Bridgend"; + case 1824: + return "Caerphilly"; + case 1825: + return "Cardiff"; + case 1826: + return "Ceredigion"; + case 1827: + return "Carmarthenshire"; + case 1828: + return "Conwy"; + case 1829: + return "Denbighshire"; + case 1864: + return "Flintshire"; + case 1865: + return "Gwynedd"; + case 1866: + return "Merthyr Tydfil"; + case 1867: + return "Monmouthshire"; + case 1868: + return "Neath Port Talbot"; + case 1869: + return "Newport"; + case 1870: + return "Pembrokeshire"; + case 1871: + return "Powys"; + case 1872: + return "Rhondda Cynon Taff"; + case 1907: + return "Swansea"; + case 1908: + return "Torfaen"; + case 1909: + return "Vale of Glamorgan, The"; + case 1910: + return "Wrexham"; + case 1911: + return "Bedfordshire"; + case 1912: + return "Central Bedfordshire"; + case 1913: + return "Cheshire East"; + case 1914: + return "Cheshire West and Chester"; + case 1915: + return "Isles of Scilly"; + default: + return NULL; + } +} + +static const char *get_region_name_GD(int region_code) { + switch (region_code) { + case 1: + return "Saint Andrew"; + case 2: + return "Saint David"; + case 3: + return "Saint George"; + case 4: + return "Saint John"; + case 5: + return "Saint Mark"; + case 6: + return "Saint Patrick"; + default: + return NULL; + } +} + +static const char *get_region_name_GE(int region_code) { + switch (region_code) { + case 1: + return "Abashis Raioni"; + case 2: + return "Abkhazia"; + case 3: + return "Adigenis Raioni"; + case 4: + return "Ajaria"; + case 5: + return "Akhalgoris Raioni"; + case 6: + return "Akhalk'alak'is Raioni"; + case 7: + return "Akhalts'ikhis Raioni"; + case 8: + return "Akhmetis Raioni"; + case 9: + return "Ambrolauris Raioni"; + case 10: + return "Aspindzis Raioni"; + case 11: + return "Baghdat'is Raioni"; + case 12: + return "Bolnisis Raioni"; + case 13: + return "Borjomis Raioni"; + case 14: + return "Chiat'ura"; + case 15: + return "Ch'khorotsqus Raioni"; + case 16: + return "Ch'okhatauris Raioni"; + case 17: + return "Dedop'listsqaros Raioni"; + case 18: + return "Dmanisis Raioni"; + case 19: + return "Dushet'is Raioni"; + case 20: + return "Gardabanis Raioni"; + case 21: + return "Gori"; + case 22: + return "Goris Raioni"; + case 23: + return "Gurjaanis Raioni"; + case 24: + return "Javis Raioni"; + case 25: + return "K'arelis Raioni"; + case 26: + return "Kaspis Raioni"; + case 27: + return "Kharagaulis Raioni"; + case 28: + return "Khashuris Raioni"; + case 29: + return "Khobis Raioni"; + case 30: + return "Khonis Raioni"; + case 31: + return "K'ut'aisi"; + case 32: + return "Lagodekhis Raioni"; + case 33: + return "Lanch'khut'is Raioni"; + case 34: + return "Lentekhis Raioni"; + case 35: + return "Marneulis Raioni"; + case 36: + return "Martvilis Raioni"; + case 37: + return "Mestiis Raioni"; + case 38: + return "Mts'khet'is Raioni"; + case 39: + return "Ninotsmindis Raioni"; + case 40: + return "Onis Raioni"; + case 41: + return "Ozurget'is Raioni"; + case 42: + return "P'ot'i"; + case 43: + return "Qazbegis Raioni"; + case 44: + return "Qvarlis Raioni"; + case 45: + return "Rust'avi"; + case 46: + return "Sach'kheris Raioni"; + case 47: + return "Sagarejos Raioni"; + case 48: + return "Samtrediis Raioni"; + case 49: + return "Senakis Raioni"; + case 50: + return "Sighnaghis Raioni"; + case 51: + return "T'bilisi"; + case 52: + return "T'elavis Raioni"; + case 53: + return "T'erjolis Raioni"; + case 54: + return "T'et'ritsqaros Raioni"; + case 55: + return "T'ianet'is Raioni"; + case 56: + return "Tqibuli"; + case 57: + return "Ts'ageris Raioni"; + case 58: + return "Tsalenjikhis Raioni"; + case 59: + return "Tsalkis Raioni"; + case 60: + return "Tsqaltubo"; + case 61: + return "Vanis Raioni"; + case 62: + return "Zestap'onis Raioni"; + case 63: + return "Zugdidi"; + case 64: + return "Zugdidis Raioni"; + default: + return NULL; + } +} + +static const char *get_region_name_GH(int region_code) { + switch (region_code) { + case 1: + return "Greater Accra"; + case 2: + return "Ashanti"; + case 3: + return "Brong-Ahafo"; + case 4: + return "Central"; + case 5: + return "Eastern"; + case 6: + return "Northern"; + case 8: + return "Volta"; + case 9: + return "Western"; + case 10: + return "Upper East"; + case 11: + return "Upper West"; + default: + return NULL; + } +} + +static const char *get_region_name_GL(int region_code) { + switch (region_code) { + case 1: + return "Nordgronland"; + case 2: + return "Ostgronland"; + case 3: + return "Vestgronland"; + default: + return NULL; + } +} + +static const char *get_region_name_GM(int region_code) { + switch (region_code) { + case 1: + return "Banjul"; + case 2: + return "Lower River"; + case 3: + return "Central River"; + case 4: + return "Upper River"; + case 5: + return "Western"; + case 7: + return "North Bank"; + default: + return NULL; + } +} + +static const char *get_region_name_GN(int region_code) { + switch (region_code) { + case 1: + return "Beyla"; + case 2: + return "Boffa"; + case 3: + return "Boke"; + case 4: + return "Conakry"; + case 5: + return "Dabola"; + case 6: + return "Dalaba"; + case 7: + return "Dinguiraye"; + case 9: + return "Faranah"; + case 10: + return "Forecariah"; + case 11: + return "Fria"; + case 12: + return "Gaoual"; + case 13: + return "Gueckedou"; + case 15: + return "Kerouane"; + case 16: + return "Kindia"; + case 17: + return "Kissidougou"; + case 18: + return "Koundara"; + case 19: + return "Kouroussa"; + case 21: + return "Macenta"; + case 22: + return "Mali"; + case 23: + return "Mamou"; + case 25: + return "Pita"; + case 27: + return "Telimele"; + case 28: + return "Tougue"; + case 29: + return "Yomou"; + case 30: + return "Coyah"; + case 31: + return "Dubreka"; + case 32: + return "Kankan"; + case 33: + return "Koubia"; + case 34: + return "Labe"; + case 35: + return "Lelouma"; + case 36: + return "Lola"; + case 37: + return "Mandiana"; + case 38: + return "Nzerekore"; + case 39: + return "Siguiri"; + default: + return NULL; + } +} + +static const char *get_region_name_GQ(int region_code) { + switch (region_code) { + case 3: + return "Annobon"; + case 4: + return "Bioko Norte"; + case 5: + return "Bioko Sur"; + case 6: + return "Centro Sur"; + case 7: + return "Kie-Ntem"; + case 8: + return "Litoral"; + case 9: + return "Wele-Nzas"; + default: + return NULL; + } +} + +static const char *get_region_name_GR(int region_code) { + switch (region_code) { + case 1: + return "Evros"; + case 2: + return "Rodhopi"; + case 3: + return "Xanthi"; + case 4: + return "Drama"; + case 5: + return "Serrai"; + case 6: + return "Kilkis"; + case 7: + return "Pella"; + case 8: + return "Florina"; + case 9: + return "Kastoria"; + case 10: + return "Grevena"; + case 11: + return "Kozani"; + case 12: + return "Imathia"; + case 13: + return "Thessaloniki"; + case 14: + return "Kavala"; + case 15: + return "Khalkidhiki"; + case 16: + return "Pieria"; + case 17: + return "Ioannina"; + case 18: + return "Thesprotia"; + case 19: + return "Preveza"; + case 20: + return "Arta"; + case 21: + return "Larisa"; + case 22: + return "Trikala"; + case 23: + return "Kardhitsa"; + case 24: + return "Magnisia"; + case 25: + return "Kerkira"; + case 26: + return "Levkas"; + case 27: + return "Kefallinia"; + case 28: + return "Zakinthos"; + case 29: + return "Fthiotis"; + case 30: + return "Evritania"; + case 31: + return "Aitolia kai Akarnania"; + case 32: + return "Fokis"; + case 33: + return "Voiotia"; + case 34: + return "Evvoia"; + case 35: + return "Attiki"; + case 36: + return "Argolis"; + case 37: + return "Korinthia"; + case 38: + return "Akhaia"; + case 39: + return "Ilia"; + case 40: + return "Messinia"; + case 41: + return "Arkadhia"; + case 42: + return "Lakonia"; + case 43: + return "Khania"; + case 44: + return "Rethimni"; + case 45: + return "Iraklion"; + case 46: + return "Lasithi"; + case 47: + return "Dhodhekanisos"; + case 48: + return "Samos"; + case 49: + return "Kikladhes"; + case 50: + return "Khios"; + case 51: + return "Lesvos"; + default: + return NULL; + } +} + +static const char *get_region_name_GT(int region_code) { + switch (region_code) { + case 1: + return "Alta Verapaz"; + case 2: + return "Baja Verapaz"; + case 3: + return "Chimaltenango"; + case 4: + return "Chiquimula"; + case 5: + return "El Progreso"; + case 6: + return "Escuintla"; + case 7: + return "Guatemala"; + case 8: + return "Huehuetenango"; + case 9: + return "Izabal"; + case 10: + return "Jalapa"; + case 11: + return "Jutiapa"; + case 12: + return "Peten"; + case 13: + return "Quetzaltenango"; + case 14: + return "Quiche"; + case 15: + return "Retalhuleu"; + case 16: + return "Sacatepequez"; + case 17: + return "San Marcos"; + case 18: + return "Santa Rosa"; + case 19: + return "Solola"; + case 20: + return "Suchitepequez"; + case 21: + return "Totonicapan"; + case 22: + return "Zacapa"; + default: + return NULL; + } +} + +static const char *get_region_name_GW(int region_code) { + switch (region_code) { + case 1: + return "Bafata"; + case 2: + return "Quinara"; + case 4: + return "Oio"; + case 5: + return "Bolama"; + case 6: + return "Cacheu"; + case 7: + return "Tombali"; + case 10: + return "Gabu"; + case 11: + return "Bissau"; + case 12: + return "Biombo"; + default: + return NULL; + } +} + +static const char *get_region_name_GY(int region_code) { + switch (region_code) { + case 10: + return "Barima-Waini"; + case 11: + return "Cuyuni-Mazaruni"; + case 12: + return "Demerara-Mahaica"; + case 13: + return "East Berbice-Corentyne"; + case 14: + return "Essequibo Islands-West Demerara"; + case 15: + return "Mahaica-Berbice"; + case 16: + return "Pomeroon-Supenaam"; + case 17: + return "Potaro-Siparuni"; + case 18: + return "Upper Demerara-Berbice"; + case 19: + return "Upper Takutu-Upper Essequibo"; + default: + return NULL; + } +} + +static const char *get_region_name_HN(int region_code) { + switch (region_code) { + case 1: + return "Atlantida"; + case 2: + return "Choluteca"; + case 3: + return "Colon"; + case 4: + return "Comayagua"; + case 5: + return "Copan"; + case 6: + return "Cortes"; + case 7: + return "El Paraiso"; + case 8: + return "Francisco Morazan"; + case 9: + return "Gracias a Dios"; + case 10: + return "Intibuca"; + case 11: + return "Islas de la Bahia"; + case 12: + return "La Paz"; + case 13: + return "Lempira"; + case 14: + return "Ocotepeque"; + case 15: + return "Olancho"; + case 16: + return "Santa Barbara"; + case 17: + return "Valle"; + case 18: + return "Yoro"; + default: + return NULL; + } +} + +static const char *get_region_name_HR(int region_code) { + switch (region_code) { + case 1: + return "Bjelovarsko-Bilogorska"; + case 2: + return "Brodsko-Posavska"; + case 3: + return "Dubrovacko-Neretvanska"; + case 4: + return "Istarska"; + case 5: + return "Karlovacka"; + case 6: + return "Koprivnicko-Krizevacka"; + case 7: + return "Krapinsko-Zagorska"; + case 8: + return "Licko-Senjska"; + case 9: + return "Medimurska"; + case 10: + return "Osjecko-Baranjska"; + case 11: + return "Pozesko-Slavonska"; + case 12: + return "Primorsko-Goranska"; + case 13: + return "Sibensko-Kninska"; + case 14: + return "Sisacko-Moslavacka"; + case 15: + return "Splitsko-Dalmatinska"; + case 16: + return "Varazdinska"; + case 17: + return "Viroviticko-Podravska"; + case 18: + return "Vukovarsko-Srijemska"; + case 19: + return "Zadarska"; + case 20: + return "Zagrebacka"; + case 21: + return "Grad Zagreb"; + default: + return NULL; + } +} + +static const char *get_region_name_HT(int region_code) { + switch (region_code) { + case 3: + return "Nord-Ouest"; + case 6: + return "Artibonite"; + case 7: + return "Centre"; + case 9: + return "Nord"; + case 10: + return "Nord-Est"; + case 11: + return "Ouest"; + case 12: + return "Sud"; + case 13: + return "Sud-Est"; + case 14: + return "Grand' Anse"; + case 15: + return "Nippes"; + default: + return NULL; + } +} + +static const char *get_region_name_HU(int region_code) { + switch (region_code) { + case 1: + return "Bacs-Kiskun"; + case 2: + return "Baranya"; + case 3: + return "Bekes"; + case 4: + return "Borsod-Abauj-Zemplen"; + case 5: + return "Budapest"; + case 6: + return "Csongrad"; + case 7: + return "Debrecen"; + case 8: + return "Fejer"; + case 9: + return "Gyor-Moson-Sopron"; + case 10: + return "Hajdu-Bihar"; + case 11: + return "Heves"; + case 12: + return "Komarom-Esztergom"; + case 13: + return "Miskolc"; + case 14: + return "Nograd"; + case 15: + return "Pecs"; + case 16: + return "Pest"; + case 17: + return "Somogy"; + case 18: + return "Szabolcs-Szatmar-Bereg"; + case 19: + return "Szeged"; + case 20: + return "Jasz-Nagykun-Szolnok"; + case 21: + return "Tolna"; + case 22: + return "Vas"; + case 23: + return "Veszprem"; + case 24: + return "Zala"; + case 25: + return "Gyor"; + case 26: + return "Bekescsaba"; + case 27: + return "Dunaujvaros"; + case 28: + return "Eger"; + case 29: + return "Hodmezovasarhely"; + case 30: + return "Kaposvar"; + case 31: + return "Kecskemet"; + case 32: + return "Nagykanizsa"; + case 33: + return "Nyiregyhaza"; + case 34: + return "Sopron"; + case 35: + return "Szekesfehervar"; + case 36: + return "Szolnok"; + case 37: + return "Szombathely"; + case 38: + return "Tatabanya"; + case 39: + return "Veszprem"; + case 40: + return "Zalaegerszeg"; + case 41: + return "Salgotarjan"; + case 42: + return "Szekszard"; + case 43: + return "Erd"; + default: + return NULL; + } +} + +static const char *get_region_name_ID(int region_code) { + switch (region_code) { + case 1: + return "Aceh"; + case 2: + return "Bali"; + case 3: + return "Bengkulu"; + case 4: + return "Jakarta Raya"; + case 5: + return "Jambi"; + case 7: + return "Jawa Tengah"; + case 8: + return "Jawa Timur"; + case 10: + return "Yogyakarta"; + case 11: + return "Kalimantan Barat"; + case 12: + return "Kalimantan Selatan"; + case 13: + return "Kalimantan Tengah"; + case 14: + return "Kalimantan Timur"; + case 15: + return "Lampung"; + case 17: + return "Nusa Tenggara Barat"; + case 18: + return "Nusa Tenggara Timur"; + case 21: + return "Sulawesi Tengah"; + case 22: + return "Sulawesi Tenggara"; + case 24: + return "Sumatera Barat"; + case 26: + return "Sumatera Utara"; + case 28: + return "Maluku"; + case 29: + return "Maluku Utara"; + case 30: + return "Jawa Barat"; + case 31: + return "Sulawesi Utara"; + case 32: + return "Sumatera Selatan"; + case 33: + return "Banten"; + case 34: + return "Gorontalo"; + case 35: + return "Kepulauan Bangka Belitung"; + case 36: + return "Papua"; + case 37: + return "Riau"; + case 38: + return "Sulawesi Selatan"; + case 39: + return "Irian Jaya Barat"; + case 40: + return "Kepulauan Riau"; + case 41: + return "Sulawesi Barat"; + default: + return NULL; + } +} + +static const char *get_region_name_IE(int region_code) { + switch (region_code) { + case 1: + return "Carlow"; + case 2: + return "Cavan"; + case 3: + return "Clare"; + case 4: + return "Cork"; + case 6: + return "Donegal"; + case 7: + return "Dublin"; + case 10: + return "Galway"; + case 11: + return "Kerry"; + case 12: + return "Kildare"; + case 13: + return "Kilkenny"; + case 14: + return "Leitrim"; + case 15: + return "Laois"; + case 16: + return "Limerick"; + case 18: + return "Longford"; + case 19: + return "Louth"; + case 20: + return "Mayo"; + case 21: + return "Meath"; + case 22: + return "Monaghan"; + case 23: + return "Offaly"; + case 24: + return "Roscommon"; + case 25: + return "Sligo"; + case 26: + return "Tipperary"; + case 27: + return "Waterford"; + case 29: + return "Westmeath"; + case 30: + return "Wexford"; + case 31: + return "Wicklow"; + default: + return NULL; + } +} + +static const char *get_region_name_IL(int region_code) { + switch (region_code) { + case 1: + return "HaDarom"; + case 2: + return "HaMerkaz"; + case 3: + return "HaZafon"; + case 4: + return "Hefa"; + case 5: + return "Tel Aviv"; + case 6: + return "Yerushalayim"; + default: + return NULL; + } +} + +static const char *get_region_name_IN(int region_code) { + switch (region_code) { + case 1: + return "Andaman and Nicobar Islands"; + case 2: + return "Andhra Pradesh"; + case 3: + return "Assam"; + case 5: + return "Chandigarh"; + case 6: + return "Dadra and Nagar Haveli"; + case 7: + return "Delhi"; + case 9: + return "Gujarat"; + case 10: + return "Haryana"; + case 11: + return "Himachal Pradesh"; + case 12: + return "Jammu and Kashmir"; + case 13: + return "Kerala"; + case 14: + return "Lakshadweep"; + case 16: + return "Maharashtra"; + case 17: + return "Manipur"; + case 18: + return "Meghalaya"; + case 19: + return "Karnataka"; + case 20: + return "Nagaland"; + case 21: + return "Orissa"; + case 22: + return "Puducherry"; + case 23: + return "Punjab"; + case 24: + return "Rajasthan"; + case 25: + return "Tamil Nadu"; + case 26: + return "Tripura"; + case 28: + return "West Bengal"; + case 29: + return "Sikkim"; + case 30: + return "Arunachal Pradesh"; + case 31: + return "Mizoram"; + case 32: + return "Daman and Diu"; + case 33: + return "Goa"; + case 34: + return "Bihar"; + case 35: + return "Madhya Pradesh"; + case 36: + return "Uttar Pradesh"; + case 37: + return "Chhattisgarh"; + case 38: + return "Jharkhand"; + case 39: + return "Uttarakhand"; + default: + return NULL; + } +} + +static const char *get_region_name_IQ(int region_code) { + switch (region_code) { + case 1: + return "Al Anbar"; + case 2: + return "Al Basrah"; + case 3: + return "Al Muthanna"; + case 4: + return "Al Qadisiyah"; + case 5: + return "As Sulaymaniyah"; + case 6: + return "Babil"; + case 7: + return "Baghdad"; + case 8: + return "Dahuk"; + case 9: + return "Dhi Qar"; + case 10: + return "Diyala"; + case 11: + return "Arbil"; + case 12: + return "Karbala'"; + case 13: + return "At Ta'mim"; + case 14: + return "Maysan"; + case 15: + return "Ninawa"; + case 16: + return "Wasit"; + case 17: + return "An Najaf"; + case 18: + return "Salah ad Din"; + default: + return NULL; + } +} + +static const char *get_region_name_IR(int region_code) { + switch (region_code) { + case 1: + return "Azarbayjan-e Bakhtari"; + case 3: + return "Chahar Mahall va Bakhtiari"; + case 4: + return "Sistan va Baluchestan"; + case 5: + return "Kohkiluyeh va Buyer Ahmadi"; + case 7: + return "Fars"; + case 8: + return "Gilan"; + case 9: + return "Hamadan"; + case 10: + return "Ilam"; + case 11: + return "Hormozgan"; + case 12: + return "Kerman"; + case 13: + return "Bakhtaran"; + case 15: + return "Khuzestan"; + case 16: + return "Kordestan"; + case 17: + return "Mazandaran"; + case 18: + return "Semnan Province"; + case 19: + return "Markazi"; + case 21: + return "Zanjan"; + case 22: + return "Bushehr"; + case 23: + return "Lorestan"; + case 24: + return "Markazi"; + case 25: + return "Semnan"; + case 26: + return "Tehran"; + case 27: + return "Zanjan"; + case 28: + return "Esfahan"; + case 29: + return "Kerman"; + case 30: + return "Khorasan"; + case 31: + return "Yazd"; + case 32: + return "Ardabil"; + case 33: + return "East Azarbaijan"; + case 34: + return "Markazi"; + case 35: + return "Mazandaran"; + case 36: + return "Zanjan"; + case 37: + return "Golestan"; + case 38: + return "Qazvin"; + case 39: + return "Qom"; + case 40: + return "Yazd"; + case 41: + return "Khorasan-e Janubi"; + case 42: + return "Khorasan-e Razavi"; + case 43: + return "Khorasan-e Shemali"; + case 44: + return "Alborz"; + default: + return NULL; + } +} + +static const char *get_region_name_IS(int region_code) { + switch (region_code) { + case 3: + return "Arnessysla"; + case 5: + return "Austur-Hunavatnssysla"; + case 6: + return "Austur-Skaftafellssysla"; + case 7: + return "Borgarfjardarsysla"; + case 9: + return "Eyjafjardarsysla"; + case 10: + return "Gullbringusysla"; + case 15: + return "Kjosarsysla"; + case 17: + return "Myrasysla"; + case 20: + return "Nordur-Mulasysla"; + case 21: + return "Nordur-Tingeyjarsysla"; + case 23: + return "Rangarvallasysla"; + case 28: + return "Skagafjardarsysla"; + case 29: + return "Snafellsnes- og Hnappadalssysla"; + case 30: + return "Strandasysla"; + case 31: + return "Sudur-Mulasysla"; + case 32: + return "Sudur-Tingeyjarsysla"; + case 34: + return "Vestur-Bardastrandarsysla"; + case 35: + return "Vestur-Hunavatnssysla"; + case 36: + return "Vestur-Isafjardarsysla"; + case 37: + return "Vestur-Skaftafellssysla"; + case 38: + return "Austurland"; + case 39: + return "Hofuoborgarsvaoio"; + case 40: + return "Norourland Eystra"; + case 41: + return "Norourland Vestra"; + case 42: + return "Suourland"; + case 43: + return "Suournes"; + case 44: + return "Vestfiroir"; + case 45: + return "Vesturland"; + default: + return NULL; + } +} + +static const char *get_region_name_IT(int region_code) { + switch (region_code) { + case 1: + return "Abruzzi"; + case 2: + return "Basilicata"; + case 3: + return "Calabria"; + case 4: + return "Campania"; + case 5: + return "Emilia-Romagna"; + case 6: + return "Friuli-Venezia Giulia"; + case 7: + return "Lazio"; + case 8: + return "Liguria"; + case 9: + return "Lombardia"; + case 10: + return "Marche"; + case 11: + return "Molise"; + case 12: + return "Piemonte"; + case 13: + return "Puglia"; + case 14: + return "Sardegna"; + case 15: + return "Sicilia"; + case 16: + return "Toscana"; + case 17: + return "Trentino-Alto Adige"; + case 18: + return "Umbria"; + case 19: + return "Valle d'Aosta"; + case 20: + return "Veneto"; + default: + return NULL; + } +} + +static const char *get_region_name_JM(int region_code) { + switch (region_code) { + case 1: + return "Clarendon"; + case 2: + return "Hanover"; + case 4: + return "Manchester"; + case 7: + return "Portland"; + case 8: + return "Saint Andrew"; + case 9: + return "Saint Ann"; + case 10: + return "Saint Catherine"; + case 11: + return "Saint Elizabeth"; + case 12: + return "Saint James"; + case 13: + return "Saint Mary"; + case 14: + return "Saint Thomas"; + case 15: + return "Trelawny"; + case 16: + return "Westmoreland"; + case 17: + return "Kingston"; + default: + return NULL; + } +} + +static const char *get_region_name_JO(int region_code) { + switch (region_code) { + case 2: + return "Al Balqa'"; + case 9: + return "Al Karak"; + case 12: + return "At Tafilah"; + case 15: + return "Al Mafraq"; + case 16: + return "Amman"; + case 17: + return "Az Zaraqa"; + case 18: + return "Irbid"; + case 19: + return "Ma'an"; + case 20: + return "Ajlun"; + case 21: + return "Al Aqabah"; + case 22: + return "Jarash"; + case 23: + return "Madaba"; + default: + return NULL; + } +} + +static const char *get_region_name_JP(int region_code) { + switch (region_code) { + case 1: + return "Aichi"; + case 2: + return "Akita"; + case 3: + return "Aomori"; + case 4: + return "Chiba"; + case 5: + return "Ehime"; + case 6: + return "Fukui"; + case 7: + return "Fukuoka"; + case 8: + return "Fukushima"; + case 9: + return "Gifu"; + case 10: + return "Gumma"; + case 11: + return "Hiroshima"; + case 12: + return "Hokkaido"; + case 13: + return "Hyogo"; + case 14: + return "Ibaraki"; + case 15: + return "Ishikawa"; + case 16: + return "Iwate"; + case 17: + return "Kagawa"; + case 18: + return "Kagoshima"; + case 19: + return "Kanagawa"; + case 20: + return "Kochi"; + case 21: + return "Kumamoto"; + case 22: + return "Kyoto"; + case 23: + return "Mie"; + case 24: + return "Miyagi"; + case 25: + return "Miyazaki"; + case 26: + return "Nagano"; + case 27: + return "Nagasaki"; + case 28: + return "Nara"; + case 29: + return "Niigata"; + case 30: + return "Oita"; + case 31: + return "Okayama"; + case 32: + return "Osaka"; + case 33: + return "Saga"; + case 34: + return "Saitama"; + case 35: + return "Shiga"; + case 36: + return "Shimane"; + case 37: + return "Shizuoka"; + case 38: + return "Tochigi"; + case 39: + return "Tokushima"; + case 40: + return "Tokyo"; + case 41: + return "Tottori"; + case 42: + return "Toyama"; + case 43: + return "Wakayama"; + case 44: + return "Yamagata"; + case 45: + return "Yamaguchi"; + case 46: + return "Yamanashi"; + case 47: + return "Okinawa"; + default: + return NULL; + } +} + +static const char *get_region_name_KE(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 2: + return "Coast"; + case 3: + return "Eastern"; + case 5: + return "Nairobi Area"; + case 6: + return "North-Eastern"; + case 7: + return "Nyanza"; + case 8: + return "Rift Valley"; + case 9: + return "Western"; + default: + return NULL; + } +} + +static const char *get_region_name_KG(int region_code) { + switch (region_code) { + case 1: + return "Bishkek"; + case 2: + return "Chuy"; + case 3: + return "Jalal-Abad"; + case 4: + return "Naryn"; + case 5: + return "Osh"; + case 6: + return "Talas"; + case 7: + return "Ysyk-Kol"; + case 8: + return "Osh"; + case 9: + return "Batken"; + default: + return NULL; + } +} + +static const char *get_region_name_KH(int region_code) { + switch (region_code) { + case 1: + return "Batdambang"; + case 2: + return "Kampong Cham"; + case 3: + return "Kampong Chhnang"; + case 4: + return "Kampong Speu"; + case 5: + return "Kampong Thum"; + case 6: + return "Kampot"; + case 7: + return "Kandal"; + case 8: + return "Koh Kong"; + case 9: + return "Kracheh"; + case 10: + return "Mondulkiri"; + case 11: + return "Phnum Penh"; + case 12: + return "Pursat"; + case 13: + return "Preah Vihear"; + case 14: + return "Prey Veng"; + case 15: + return "Ratanakiri Kiri"; + case 16: + return "Siem Reap"; + case 17: + return "Stung Treng"; + case 18: + return "Svay Rieng"; + case 19: + return "Takeo"; + case 22: + return "Phnum Penh"; + case 23: + return "Ratanakiri"; + case 25: + return "Banteay Meanchey"; + case 28: + return "Preah Seihanu"; + case 29: + return "Batdambang"; + case 30: + return "Pailin"; + default: + return NULL; + } +} + +static const char *get_region_name_KI(int region_code) { + switch (region_code) { + case 1: + return "Gilbert Islands"; + case 2: + return "Line Islands"; + case 3: + return "Phoenix Islands"; + default: + return NULL; + } +} + +static const char *get_region_name_KM(int region_code) { + switch (region_code) { + case 1: + return "Anjouan"; + case 2: + return "Grande Comore"; + case 3: + return "Moheli"; + default: + return NULL; + } +} + +static const char *get_region_name_KN(int region_code) { + switch (region_code) { + case 1: + return "Christ Church Nichola Town"; + case 2: + return "Saint Anne Sandy Point"; + case 3: + return "Saint George Basseterre"; + case 4: + return "Saint George Gingerland"; + case 5: + return "Saint James Windward"; + case 6: + return "Saint John Capisterre"; + case 7: + return "Saint John Figtree"; + case 8: + return "Saint Mary Cayon"; + case 9: + return "Saint Paul Capisterre"; + case 10: + return "Saint Paul Charlestown"; + case 11: + return "Saint Peter Basseterre"; + case 12: + return "Saint Thomas Lowland"; + case 13: + return "Saint Thomas Middle Island"; + case 15: + return "Trinity Palmetto Point"; + default: + return NULL; + } +} + +static const char *get_region_name_KP(int region_code) { + switch (region_code) { + case 1: + return "Chagang-do"; + case 3: + return "Hamgyong-namdo"; + case 6: + return "Hwanghae-namdo"; + case 7: + return "Hwanghae-bukto"; + case 8: + return "Kaesong-si"; + case 9: + return "Kangwon-do"; + case 11: + return "P'yongan-bukto"; + case 12: + return "P'yongyang-si"; + case 13: + return "Yanggang-do"; + case 14: + return "Namp'o-si"; + case 15: + return "P'yongan-namdo"; + case 17: + return "Hamgyong-bukto"; + case 18: + return "Najin Sonbong-si"; + default: + return NULL; + } +} + +static const char *get_region_name_KR(int region_code) { + switch (region_code) { + case 1: + return "Cheju-do"; + case 3: + return "Cholla-bukto"; + case 5: + return "Ch'ungch'ong-bukto"; + case 6: + return "Kangwon-do"; + case 10: + return "Pusan-jikhalsi"; + case 11: + return "Seoul-t'ukpyolsi"; + case 12: + return "Inch'on-jikhalsi"; + case 13: + return "Kyonggi-do"; + case 14: + return "Kyongsang-bukto"; + case 15: + return "Taegu-jikhalsi"; + case 16: + return "Cholla-namdo"; + case 17: + return "Ch'ungch'ong-namdo"; + case 18: + return "Kwangju-jikhalsi"; + case 19: + return "Taejon-jikhalsi"; + case 20: + return "Kyongsang-namdo"; + case 21: + return "Ulsan-gwangyoksi"; + default: + return NULL; + } +} + +static const char *get_region_name_KW(int region_code) { + switch (region_code) { + case 1: + return "Al Ahmadi"; + case 2: + return "Al Kuwayt"; + case 5: + return "Al Jahra"; + case 7: + return "Al Farwaniyah"; + case 8: + return "Hawalli"; + case 9: + return "Mubarak al Kabir"; + default: + return NULL; + } +} + +static const char *get_region_name_KY(int region_code) { + switch (region_code) { + case 1: + return "Creek"; + case 2: + return "Eastern"; + case 3: + return "Midland"; + case 4: + return "South Town"; + case 5: + return "Spot Bay"; + case 6: + return "Stake Bay"; + case 7: + return "West End"; + case 8: + return "Western"; + default: + return NULL; + } +} + +static const char *get_region_name_KZ(int region_code) { + switch (region_code) { + case 1: + return "Almaty"; + case 2: + return "Almaty City"; + case 3: + return "Aqmola"; + case 4: + return "Aqtobe"; + case 5: + return "Astana"; + case 6: + return "Atyrau"; + case 7: + return "West Kazakhstan"; + case 8: + return "Bayqonyr"; + case 9: + return "Mangghystau"; + case 10: + return "South Kazakhstan"; + case 11: + return "Pavlodar"; + case 12: + return "Qaraghandy"; + case 13: + return "Qostanay"; + case 14: + return "Qyzylorda"; + case 15: + return "East Kazakhstan"; + case 16: + return "North Kazakhstan"; + case 17: + return "Zhambyl"; + default: + return NULL; + } +} + +static const char *get_region_name_LA(int region_code) { + switch (region_code) { + case 1: + return "Attapu"; + case 2: + return "Champasak"; + case 3: + return "Houaphan"; + case 4: + return "Khammouan"; + case 5: + return "Louang Namtha"; + case 7: + return "Oudomxai"; + case 8: + return "Phongsali"; + case 9: + return "Saravan"; + case 10: + return "Savannakhet"; + case 11: + return "Vientiane"; + case 13: + return "Xaignabouri"; + case 14: + return "Xiangkhoang"; + case 17: + return "Louangphrabang"; + default: + return NULL; + } +} + +static const char *get_region_name_LB(int region_code) { + switch (region_code) { + case 1: + return "Beqaa"; + case 2: + return "Al Janub"; + case 3: + return "Liban-Nord"; + case 4: + return "Beyrouth"; + case 5: + return "Mont-Liban"; + case 6: + return "Liban-Sud"; + case 7: + return "Nabatiye"; + case 8: + return "Beqaa"; + case 9: + return "Liban-Nord"; + case 10: + return "Aakk,r"; + case 11: + return "Baalbek-Hermel"; + default: + return NULL; + } +} + +static const char *get_region_name_LC(int region_code) { + switch (region_code) { + case 1: + return "Anse-la-Raye"; + case 2: + return "Dauphin"; + case 3: + return "Castries"; + case 4: + return "Choiseul"; + case 5: + return "Dennery"; + case 6: + return "Gros-Islet"; + case 7: + return "Laborie"; + case 8: + return "Micoud"; + case 9: + return "Soufriere"; + case 10: + return "Vieux-Fort"; + case 11: + return "Praslin"; + default: + return NULL; + } +} + +static const char *get_region_name_LI(int region_code) { + switch (region_code) { + case 1: + return "Balzers"; + case 2: + return "Eschen"; + case 3: + return "Gamprin"; + case 4: + return "Mauren"; + case 5: + return "Planken"; + case 6: + return "Ruggell"; + case 7: + return "Schaan"; + case 8: + return "Schellenberg"; + case 9: + return "Triesen"; + case 10: + return "Triesenberg"; + case 11: + return "Vaduz"; + case 21: + return "Gbarpolu"; + case 22: + return "River Gee"; + default: + return NULL; + } +} + +static const char *get_region_name_LK(int region_code) { + switch (region_code) { + case 29: + return "Central"; + case 30: + return "North Central"; + case 32: + return "North Western"; + case 33: + return "Sabaragamuwa"; + case 34: + return "Southern"; + case 35: + return "Uva"; + case 36: + return "Western"; + case 37: + return "Eastern"; + case 38: + return "Northern"; + default: + return NULL; + } +} + +static const char *get_region_name_LR(int region_code) { + switch (region_code) { + case 1: + return "Bong"; + case 4: + return "Grand Cape Mount"; + case 5: + return "Lofa"; + case 6: + return "Maryland"; + case 7: + return "Monrovia"; + case 9: + return "Nimba"; + case 10: + return "Sino"; + case 11: + return "Grand Bassa"; + case 12: + return "Grand Cape Mount"; + case 13: + return "Maryland"; + case 14: + return "Montserrado"; + case 17: + return "Margibi"; + case 18: + return "River Cess"; + case 19: + return "Grand Gedeh"; + case 20: + return "Lofa"; + case 21: + return "Gbarpolu"; + case 22: + return "River Gee"; + default: + return NULL; + } +} + +static const char *get_region_name_LS(int region_code) { + switch (region_code) { + case 10: + return "Berea"; + case 11: + return "Butha-Buthe"; + case 12: + return "Leribe"; + case 13: + return "Mafeteng"; + case 14: + return "Maseru"; + case 15: + return "Mohales Hoek"; + case 16: + return "Mokhotlong"; + case 17: + return "Qachas Nek"; + case 18: + return "Quthing"; + case 19: + return "Thaba-Tseka"; + default: + return NULL; + } +} + +static const char *get_region_name_LT(int region_code) { + switch (region_code) { + case 56: + return "Alytaus Apskritis"; + case 57: + return "Kauno Apskritis"; + case 58: + return "Klaipedos Apskritis"; + case 59: + return "Marijampoles Apskritis"; + case 60: + return "Panevezio Apskritis"; + case 61: + return "Siauliu Apskritis"; + case 62: + return "Taurages Apskritis"; + case 63: + return "Telsiu Apskritis"; + case 64: + return "Utenos Apskritis"; + case 65: + return "Vilniaus Apskritis"; + default: + return NULL; + } +} + +static const char *get_region_name_LU(int region_code) { + switch (region_code) { + case 1: + return "Diekirch"; + case 2: + return "Grevenmacher"; + case 3: + return "Luxembourg"; + default: + return NULL; + } +} + +static const char *get_region_name_LV(int region_code) { + switch (region_code) { + case 1: + return "Aizkraukles"; + case 2: + return "Aluksnes"; + case 3: + return "Balvu"; + case 4: + return "Bauskas"; + case 5: + return "Cesu"; + case 6: + return "Daugavpils"; + case 7: + return "Daugavpils"; + case 8: + return "Dobeles"; + case 9: + return "Gulbenes"; + case 10: + return "Jekabpils"; + case 11: + return "Jelgava"; + case 12: + return "Jelgavas"; + case 13: + return "Jurmala"; + case 14: + return "Kraslavas"; + case 15: + return "Kuldigas"; + case 16: + return "Liepaja"; + case 17: + return "Liepajas"; + case 18: + return "Limbazu"; + case 19: + return "Ludzas"; + case 20: + return "Madonas"; + case 21: + return "Ogres"; + case 22: + return "Preilu"; + case 23: + return "Rezekne"; + case 24: + return "Rezeknes"; + case 25: + return "Riga"; + case 26: + return "Rigas"; + case 27: + return "Saldus"; + case 28: + return "Talsu"; + case 29: + return "Tukuma"; + case 30: + return "Valkas"; + case 31: + return "Valmieras"; + case 32: + return "Ventspils"; + case 33: + return "Ventspils"; + default: + return NULL; + } +} + +static const char *get_region_name_LY(int region_code) { + switch (region_code) { + case 3: + return "Al Aziziyah"; + case 5: + return "Al Jufrah"; + case 8: + return "Al Kufrah"; + case 13: + return "Ash Shati'"; + case 30: + return "Murzuq"; + case 34: + return "Sabha"; + case 41: + return "Tarhunah"; + case 42: + return "Tubruq"; + case 45: + return "Zlitan"; + case 47: + return "Ajdabiya"; + case 48: + return "Al Fatih"; + case 49: + return "Al Jabal al Akhdar"; + case 50: + return "Al Khums"; + case 51: + return "An Nuqat al Khams"; + case 52: + return "Awbari"; + case 53: + return "Az Zawiyah"; + case 54: + return "Banghazi"; + case 55: + return "Darnah"; + case 56: + return "Ghadamis"; + case 57: + return "Gharyan"; + case 58: + return "Misratah"; + case 59: + return "Sawfajjin"; + case 60: + return "Surt"; + case 61: + return "Tarabulus"; + case 62: + return "Yafran"; + default: + return NULL; + } +} + +static const char *get_region_name_MA(int region_code) { + switch (region_code) { + case 45: + return "Grand Casablanca"; + case 46: + return "Fes-Boulemane"; + case 47: + return "Marrakech-Tensift-Al Haouz"; + case 48: + return "Meknes-Tafilalet"; + case 49: + return "Rabat-Sale-Zemmour-Zaer"; + case 50: + return "Chaouia-Ouardigha"; + case 51: + return "Doukkala-Abda"; + case 52: + return "Gharb-Chrarda-Beni Hssen"; + case 53: + return "Guelmim-Es Smara"; + case 54: + return "Oriental"; + case 55: + return "Souss-Massa-Dr,a"; + case 56: + return "Tadla-Azilal"; + case 57: + return "Tanger-Tetouan"; + case 58: + return "Taza-Al Hoceima-Taounate"; + case 59: + return "La,youne-Boujdour-Sakia El Hamra"; + default: + return NULL; + } +} + +static const char *get_region_name_MC(int region_code) { + switch (region_code) { + case 1: + return "La Condamine"; + case 2: + return "Monaco"; + case 3: + return "Monte-Carlo"; + default: + return NULL; + } +} + +static const char *get_region_name_MD(int region_code) { + switch (region_code) { + case 51: + return "Gagauzia"; + case 57: + return "Chisinau"; + case 58: + return "Stinga Nistrului"; + case 59: + return "Anenii Noi"; + case 60: + return "Balti"; + case 61: + return "Basarabeasca"; + case 62: + return "Bender"; + case 63: + return "Briceni"; + case 64: + return "Cahul"; + case 65: + return "Cantemir"; + case 66: + return "Calarasi"; + case 67: + return "Causeni"; + case 68: + return "Cimislia"; + case 69: + return "Criuleni"; + case 70: + return "Donduseni"; + case 71: + return "Drochia"; + case 72: + return "Dubasari"; + case 73: + return "Edinet"; + case 74: + return "Falesti"; + case 75: + return "Floresti"; + case 76: + return "Glodeni"; + case 77: + return "Hincesti"; + case 78: + return "Ialoveni"; + case 79: + return "Leova"; + case 80: + return "Nisporeni"; + case 81: + return "Ocnita"; + case 82: + return "Orhei"; + case 83: + return "Rezina"; + case 84: + return "Riscani"; + case 85: + return "Singerei"; + case 86: + return "Soldanesti"; + case 87: + return "Soroca"; + case 88: + return "Stefan-Voda"; + case 89: + return "Straseni"; + case 90: + return "Taraclia"; + case 91: + return "Telenesti"; + case 92: + return "Ungheni"; + default: + return NULL; + } +} + +static const char *get_region_name_MG(int region_code) { + switch (region_code) { + case 1: + return "Antsiranana"; + case 2: + return "Fianarantsoa"; + case 3: + return "Mahajanga"; + case 4: + return "Toamasina"; + case 5: + return "Antananarivo"; + case 6: + return "Toliara"; + default: + return NULL; + } +} + +static const char *get_region_name_MK(int region_code) { + switch (region_code) { + case 1: + return "Aracinovo"; + case 2: + return "Bac"; + case 3: + return "Belcista"; + case 4: + return "Berovo"; + case 5: + return "Bistrica"; + case 6: + return "Bitola"; + case 7: + return "Blatec"; + case 8: + return "Bogdanci"; + case 9: + return "Bogomila"; + case 10: + return "Bogovinje"; + case 11: + return "Bosilovo"; + case 12: + return "Brvenica"; + case 13: + return "Cair"; + case 14: + return "Capari"; + case 15: + return "Caska"; + case 16: + return "Cegrane"; + case 17: + return "Centar"; + case 18: + return "Centar Zupa"; + case 19: + return "Cesinovo"; + case 20: + return "Cucer-Sandevo"; + case 21: + return "Debar"; + case 22: + return "Delcevo"; + case 23: + return "Delogozdi"; + case 24: + return "Demir Hisar"; + case 25: + return "Demir Kapija"; + case 26: + return "Dobrusevo"; + case 27: + return "Dolna Banjica"; + case 28: + return "Dolneni"; + case 29: + return "Dorce Petrov"; + case 30: + return "Drugovo"; + case 31: + return "Dzepciste"; + case 32: + return "Gazi Baba"; + case 33: + return "Gevgelija"; + case 34: + return "Gostivar"; + case 35: + return "Gradsko"; + case 36: + return "Ilinden"; + case 37: + return "Izvor"; + case 38: + return "Jegunovce"; + case 39: + return "Kamenjane"; + case 40: + return "Karbinci"; + case 41: + return "Karpos"; + case 42: + return "Kavadarci"; + case 43: + return "Kicevo"; + case 44: + return "Kisela Voda"; + case 45: + return "Klecevce"; + case 46: + return "Kocani"; + case 47: + return "Konce"; + case 48: + return "Kondovo"; + case 49: + return "Konopiste"; + case 50: + return "Kosel"; + case 51: + return "Kratovo"; + case 52: + return "Kriva Palanka"; + case 53: + return "Krivogastani"; + case 54: + return "Krusevo"; + case 55: + return "Kuklis"; + case 56: + return "Kukurecani"; + case 57: + return "Kumanovo"; + case 58: + return "Labunista"; + case 59: + return "Lipkovo"; + case 60: + return "Lozovo"; + case 61: + return "Lukovo"; + case 62: + return "Makedonska Kamenica"; + case 63: + return "Makedonski Brod"; + case 64: + return "Mavrovi Anovi"; + case 65: + return "Meseista"; + case 66: + return "Miravci"; + case 67: + return "Mogila"; + case 68: + return "Murtino"; + case 69: + return "Negotino"; + case 70: + return "Negotino-Polosko"; + case 71: + return "Novaci"; + case 72: + return "Novo Selo"; + case 73: + return "Oblesevo"; + case 74: + return "Ohrid"; + case 75: + return "Orasac"; + case 76: + return "Orizari"; + case 77: + return "Oslomej"; + case 78: + return "Pehcevo"; + case 79: + return "Petrovec"; + case 80: + return "Plasnica"; + case 81: + return "Podares"; + case 82: + return "Prilep"; + case 83: + return "Probistip"; + case 84: + return "Radovis"; + case 85: + return "Rankovce"; + case 86: + return "Resen"; + case 87: + return "Rosoman"; + case 88: + return "Rostusa"; + case 89: + return "Samokov"; + case 90: + return "Saraj"; + case 91: + return "Sipkovica"; + case 92: + return "Sopiste"; + case 93: + return "Sopotnica"; + case 94: + return "Srbinovo"; + case 95: + return "Staravina"; + case 96: + return "Star Dojran"; + case 97: + return "Staro Nagoricane"; + case 98: + return "Stip"; + case 99: + return "Struga"; + case 832: + return "Strumica"; + case 833: + return "Studenicani"; + case 834: + return "Suto Orizari"; + case 835: + return "Sveti Nikole"; + case 836: + return "Tearce"; + case 837: + return "Tetovo"; + case 838: + return "Topolcani"; + case 839: + return "Valandovo"; + case 840: + return "Vasilevo"; + case 875: + return "Veles"; + case 876: + return "Velesta"; + case 877: + return "Vevcani"; + case 878: + return "Vinica"; + case 879: + return "Vitoliste"; + case 880: + return "Vranestica"; + case 881: + return "Vrapciste"; + case 882: + return "Vratnica"; + case 883: + return "Vrutok"; + case 918: + return "Zajas"; + case 919: + return "Zelenikovo"; + case 920: + return "Zelino"; + case 921: + return "Zitose"; + case 922: + return "Zletovo"; + case 923: + return "Zrnovci"; + case 925: + return "Cair"; + case 926: + return "Caska"; + case 962: + return "Debar"; + case 963: + return "Demir Hisar"; + case 964: + return "Gostivar"; + case 965: + return "Jegunovce"; + case 966: + return "Kavadarci"; + case 967: + return "Kumanovo"; + case 968: + return "Makedonski Brod"; + case 1005: + return "Ohrid"; + case 1006: + return "Prilep"; + case 1008: + return "Dojran"; + case 1009: + return "Struga"; + case 1010: + return "Strumica"; + case 1011: + return "Tetovo"; + case 1012: + return "Valandovo"; + case 1047: + return "Veles"; + case 1048: + return "Aerodrom"; + default: + return NULL; + } +} + +static const char *get_region_name_ML(int region_code) { + switch (region_code) { + case 1: + return "Bamako"; + case 3: + return "Kayes"; + case 4: + return "Mopti"; + case 5: + return "Segou"; + case 6: + return "Sikasso"; + case 7: + return "Koulikoro"; + case 8: + return "Tombouctou"; + case 9: + return "Gao"; + case 10: + return "Kidal"; + default: + return NULL; + } +} + +static const char *get_region_name_MM(int region_code) { + switch (region_code) { + case 1: + return "Rakhine State"; + case 2: + return "Chin State"; + case 3: + return "Irrawaddy"; + case 4: + return "Kachin State"; + case 5: + return "Karan State"; + case 6: + return "Kayah State"; + case 7: + return "Magwe"; + case 8: + return "Mandalay"; + case 9: + return "Pegu"; + case 10: + return "Sagaing"; + case 11: + return "Shan State"; + case 12: + return "Tenasserim"; + case 13: + return "Mon State"; + case 14: + return "Rangoon"; + case 17: + return "Yangon"; + default: + return NULL; + } +} + +static const char *get_region_name_MN(int region_code) { + switch (region_code) { + case 1: + return "Arhangay"; + case 2: + return "Bayanhongor"; + case 3: + return "Bayan-Olgiy"; + case 5: + return "Darhan"; + case 6: + return "Dornod"; + case 7: + return "Dornogovi"; + case 8: + return "Dundgovi"; + case 9: + return "Dzavhan"; + case 10: + return "Govi-Altay"; + case 11: + return "Hentiy"; + case 12: + return "Hovd"; + case 13: + return "Hovsgol"; + case 14: + return "Omnogovi"; + case 15: + return "Ovorhangay"; + case 16: + return "Selenge"; + case 17: + return "Suhbaatar"; + case 18: + return "Tov"; + case 19: + return "Uvs"; + case 20: + return "Ulaanbaatar"; + case 21: + return "Bulgan"; + case 22: + return "Erdenet"; + case 23: + return "Darhan-Uul"; + case 24: + return "Govisumber"; + case 25: + return "Orhon"; + default: + return NULL; + } +} + +static const char *get_region_name_MO(int region_code) { + switch (region_code) { + case 1: + return "Ilhas"; + case 2: + return "Macau"; + default: + return NULL; + } +} + +static const char *get_region_name_MR(int region_code) { + switch (region_code) { + case 1: + return "Hodh Ech Chargui"; + case 2: + return "Hodh El Gharbi"; + case 3: + return "Assaba"; + case 4: + return "Gorgol"; + case 5: + return "Brakna"; + case 6: + return "Trarza"; + case 7: + return "Adrar"; + case 8: + return "Dakhlet Nouadhibou"; + case 9: + return "Tagant"; + case 10: + return "Guidimaka"; + case 11: + return "Tiris Zemmour"; + case 12: + return "Inchiri"; + default: + return NULL; + } +} + +static const char *get_region_name_MS(int region_code) { + switch (region_code) { + case 1: + return "Saint Anthony"; + case 2: + return "Saint Georges"; + case 3: + return "Saint Peter"; + default: + return NULL; + } +} + +static const char *get_region_name_MU(int region_code) { + switch (region_code) { + case 12: + return "Black River"; + case 13: + return "Flacq"; + case 14: + return "Grand Port"; + case 15: + return "Moka"; + case 16: + return "Pamplemousses"; + case 17: + return "Plaines Wilhems"; + case 18: + return "Port Louis"; + case 19: + return "Riviere du Rempart"; + case 20: + return "Savanne"; + case 21: + return "Agalega Islands"; + case 22: + return "Cargados Carajos"; + case 23: + return "Rodrigues"; + default: + return NULL; + } +} + +static const char *get_region_name_MV(int region_code) { + switch (region_code) { + case 1: + return "Seenu"; + case 5: + return "Laamu"; + case 30: + return "Alifu"; + case 31: + return "Baa"; + case 32: + return "Dhaalu"; + case 33: + return "Faafu "; + case 34: + return "Gaafu Alifu"; + case 35: + return "Gaafu Dhaalu"; + case 36: + return "Haa Alifu"; + case 37: + return "Haa Dhaalu"; + case 38: + return "Kaafu"; + case 39: + return "Lhaviyani"; + case 40: + return "Maale"; + case 41: + return "Meemu"; + case 42: + return "Gnaviyani"; + case 43: + return "Noonu"; + case 44: + return "Raa"; + case 45: + return "Shaviyani"; + case 46: + return "Thaa"; + case 47: + return "Vaavu"; + default: + return NULL; + } +} + +static const char *get_region_name_MW(int region_code) { + switch (region_code) { + case 2: + return "Chikwawa"; + case 3: + return "Chiradzulu"; + case 4: + return "Chitipa"; + case 5: + return "Thyolo"; + case 6: + return "Dedza"; + case 7: + return "Dowa"; + case 8: + return "Karonga"; + case 9: + return "Kasungu"; + case 11: + return "Lilongwe"; + case 12: + return "Mangochi"; + case 13: + return "Mchinji"; + case 15: + return "Mzimba"; + case 16: + return "Ntcheu"; + case 17: + return "Nkhata Bay"; + case 18: + return "Nkhotakota"; + case 19: + return "Nsanje"; + case 20: + return "Ntchisi"; + case 21: + return "Rumphi"; + case 22: + return "Salima"; + case 23: + return "Zomba"; + case 24: + return "Blantyre"; + case 25: + return "Mwanza"; + case 26: + return "Balaka"; + case 27: + return "Likoma"; + case 28: + return "Machinga"; + case 29: + return "Mulanje"; + case 30: + return "Phalombe"; + default: + return NULL; + } +} + +static const char *get_region_name_MX(int region_code) { + switch (region_code) { + case 1: + return "Aguascalientes"; + case 2: + return "Baja California"; + case 3: + return "Baja California Sur"; + case 4: + return "Campeche"; + case 5: + return "Chiapas"; + case 6: + return "Chihuahua"; + case 7: + return "Coahuila de Zaragoza"; + case 8: + return "Colima"; + case 9: + return "Distrito Federal"; + case 10: + return "Durango"; + case 11: + return "Guanajuato"; + case 12: + return "Guerrero"; + case 13: + return "Hidalgo"; + case 14: + return "Jalisco"; + case 15: + return "Mexico"; + case 16: + return "Michoacan de Ocampo"; + case 17: + return "Morelos"; + case 18: + return "Nayarit"; + case 19: + return "Nuevo Leon"; + case 20: + return "Oaxaca"; + case 21: + return "Puebla"; + case 22: + return "Queretaro de Arteaga"; + case 23: + return "Quintana Roo"; + case 24: + return "San Luis Potosi"; + case 25: + return "Sinaloa"; + case 26: + return "Sonora"; + case 27: + return "Tabasco"; + case 28: + return "Tamaulipas"; + case 29: + return "Tlaxcala"; + case 30: + return "Veracruz-Llave"; + case 31: + return "Yucatan"; + case 32: + return "Zacatecas"; + default: + return NULL; + } +} + +static const char *get_region_name_MY(int region_code) { + switch (region_code) { + case 1: + return "Johor"; + case 2: + return "Kedah"; + case 3: + return "Kelantan"; + case 4: + return "Melaka"; + case 5: + return "Negeri Sembilan"; + case 6: + return "Pahang"; + case 7: + return "Perak"; + case 8: + return "Perlis"; + case 9: + return "Pulau Pinang"; + case 11: + return "Sarawak"; + case 12: + return "Selangor"; + case 13: + return "Terengganu"; + case 14: + return "Kuala Lumpur"; + case 15: + return "Labuan"; + case 16: + return "Sabah"; + case 17: + return "Putrajaya"; + default: + return NULL; + } +} + +static const char *get_region_name_MZ(int region_code) { + switch (region_code) { + case 1: + return "Cabo Delgado"; + case 2: + return "Gaza"; + case 3: + return "Inhambane"; + case 4: + return "Maputo"; + case 5: + return "Sofala"; + case 6: + return "Nampula"; + case 7: + return "Niassa"; + case 8: + return "Tete"; + case 9: + return "Zambezia"; + case 10: + return "Manica"; + case 11: + return "Maputo"; + default: + return NULL; + } +} + +static const char *get_region_name_NA(int region_code) { + switch (region_code) { + case 1: + return "Bethanien"; + case 2: + return "Caprivi Oos"; + case 3: + return "Boesmanland"; + case 4: + return "Gobabis"; + case 5: + return "Grootfontein"; + case 6: + return "Kaokoland"; + case 7: + return "Karibib"; + case 8: + return "Keetmanshoop"; + case 9: + return "Luderitz"; + case 10: + return "Maltahohe"; + case 11: + return "Okahandja"; + case 12: + return "Omaruru"; + case 13: + return "Otjiwarongo"; + case 14: + return "Outjo"; + case 15: + return "Owambo"; + case 16: + return "Rehoboth"; + case 17: + return "Swakopmund"; + case 18: + return "Tsumeb"; + case 20: + return "Karasburg"; + case 21: + return "Windhoek"; + case 22: + return "Damaraland"; + case 23: + return "Hereroland Oos"; + case 24: + return "Hereroland Wes"; + case 25: + return "Kavango"; + case 26: + return "Mariental"; + case 27: + return "Namaland"; + case 28: + return "Caprivi"; + case 29: + return "Erongo"; + case 30: + return "Hardap"; + case 31: + return "Karas"; + case 32: + return "Kunene"; + case 33: + return "Ohangwena"; + case 34: + return "Okavango"; + case 35: + return "Omaheke"; + case 36: + return "Omusati"; + case 37: + return "Oshana"; + case 38: + return "Oshikoto"; + case 39: + return "Otjozondjupa"; + default: + return NULL; + } +} + +static const char *get_region_name_NE(int region_code) { + switch (region_code) { + case 1: + return "Agadez"; + case 2: + return "Diffa"; + case 3: + return "Dosso"; + case 4: + return "Maradi"; + case 5: + return "Niamey"; + case 6: + return "Tahoua"; + case 7: + return "Zinder"; + case 8: + return "Niamey"; + default: + return NULL; + } +} + +static const char *get_region_name_NG(int region_code) { + switch (region_code) { + case 5: + return "Lagos"; + case 11: + return "Federal Capital Territory"; + case 16: + return "Ogun"; + case 21: + return "Akwa Ibom"; + case 22: + return "Cross River"; + case 23: + return "Kaduna"; + case 24: + return "Katsina"; + case 25: + return "Anambra"; + case 26: + return "Benue"; + case 27: + return "Borno"; + case 28: + return "Imo"; + case 29: + return "Kano"; + case 30: + return "Kwara"; + case 31: + return "Niger"; + case 32: + return "Oyo"; + case 35: + return "Adamawa"; + case 36: + return "Delta"; + case 37: + return "Edo"; + case 39: + return "Jigawa"; + case 40: + return "Kebbi"; + case 41: + return "Kogi"; + case 42: + return "Osun"; + case 43: + return "Taraba"; + case 44: + return "Yobe"; + case 45: + return "Abia"; + case 46: + return "Bauchi"; + case 47: + return "Enugu"; + case 48: + return "Ondo"; + case 49: + return "Plateau"; + case 50: + return "Rivers"; + case 51: + return "Sokoto"; + case 52: + return "Bayelsa"; + case 53: + return "Ebonyi"; + case 54: + return "Ekiti"; + case 55: + return "Gombe"; + case 56: + return "Nassarawa"; + case 57: + return "Zamfara"; + default: + return NULL; + } +} + +static const char *get_region_name_NI(int region_code) { + switch (region_code) { + case 1: + return "Boaco"; + case 2: + return "Carazo"; + case 3: + return "Chinandega"; + case 4: + return "Chontales"; + case 5: + return "Esteli"; + case 6: + return "Granada"; + case 7: + return "Jinotega"; + case 8: + return "Leon"; + case 9: + return "Madriz"; + case 10: + return "Managua"; + case 11: + return "Masaya"; + case 12: + return "Matagalpa"; + case 13: + return "Nueva Segovia"; + case 14: + return "Rio San Juan"; + case 15: + return "Rivas"; + case 16: + return "Zelaya"; + case 17: + return "Autonoma Atlantico Norte"; + case 18: + return "Region Autonoma Atlantico Sur"; + default: + return NULL; + } +} + +static const char *get_region_name_NL(int region_code) { + switch (region_code) { + case 1: + return "Drenthe"; + case 2: + return "Friesland"; + case 3: + return "Gelderland"; + case 4: + return "Groningen"; + case 5: + return "Limburg"; + case 6: + return "Noord-Brabant"; + case 7: + return "Noord-Holland"; + case 9: + return "Utrecht"; + case 10: + return "Zeeland"; + case 11: + return "Zuid-Holland"; + case 15: + return "Overijssel"; + case 16: + return "Flevoland"; + default: + return NULL; + } +} + +static const char *get_region_name_NO(int region_code) { + switch (region_code) { + case 1: + return "Akershus"; + case 2: + return "Aust-Agder"; + case 4: + return "Buskerud"; + case 5: + return "Finnmark"; + case 6: + return "Hedmark"; + case 7: + return "Hordaland"; + case 8: + return "More og Romsdal"; + case 9: + return "Nordland"; + case 10: + return "Nord-Trondelag"; + case 11: + return "Oppland"; + case 12: + return "Oslo"; + case 13: + return "Ostfold"; + case 14: + return "Rogaland"; + case 15: + return "Sogn og Fjordane"; + case 16: + return "Sor-Trondelag"; + case 17: + return "Telemark"; + case 18: + return "Troms"; + case 19: + return "Vest-Agder"; + case 20: + return "Vestfold"; + default: + return NULL; + } +} + +static const char *get_region_name_NP(int region_code) { + switch (region_code) { + case 1: + return "Bagmati"; + case 2: + return "Bheri"; + case 3: + return "Dhawalagiri"; + case 4: + return "Gandaki"; + case 5: + return "Janakpur"; + case 6: + return "Karnali"; + case 7: + return "Kosi"; + case 8: + return "Lumbini"; + case 9: + return "Mahakali"; + case 10: + return "Mechi"; + case 11: + return "Narayani"; + case 12: + return "Rapti"; + case 13: + return "Sagarmatha"; + case 14: + return "Seti"; + default: + return NULL; + } +} + +static const char *get_region_name_NR(int region_code) { + switch (region_code) { + case 1: + return "Aiwo"; + case 2: + return "Anabar"; + case 3: + return "Anetan"; + case 4: + return "Anibare"; + case 5: + return "Baiti"; + case 6: + return "Boe"; + case 7: + return "Buada"; + case 8: + return "Denigomodu"; + case 9: + return "Ewa"; + case 10: + return "Ijuw"; + case 11: + return "Meneng"; + case 12: + return "Nibok"; + case 13: + return "Uaboe"; + case 14: + return "Yaren"; + default: + return NULL; + } +} + +static const char *get_region_name_NZ(int region_code) { + switch (region_code) { + case 10: + return "Chatham Islands"; + case 1010: + return "Auckland"; + case 1011: + return "Bay of Plenty"; + case 1012: + return "Canterbury"; + case 1047: + return "Gisborne"; + case 1048: + return "Hawke's Bay"; + case 1049: + return "Manawatu-Wanganui"; + case 1050: + return "Marlborough"; + case 1051: + return "Nelson"; + case 1052: + return "Northland"; + case 1053: + return "Otago"; + case 1054: + return "Southland"; + case 1055: + return "Taranaki"; + case 1090: + return "Waikato"; + case 1091: + return "Wellington"; + case 1092: + return "West Coast"; + default: + return NULL; + } +} + +static const char *get_region_name_OM(int region_code) { + switch (region_code) { + case 1: + return "Ad Dakhiliyah"; + case 2: + return "Al Batinah"; + case 3: + return "Al Wusta"; + case 4: + return "Ash Sharqiyah"; + case 5: + return "Az Zahirah"; + case 6: + return "Masqat"; + case 7: + return "Musandam"; + case 8: + return "Zufar"; + default: + return NULL; + } +} + +static const char *get_region_name_PA(int region_code) { + switch (region_code) { + case 1: + return "Bocas del Toro"; + case 2: + return "Chiriqui"; + case 3: + return "Cocle"; + case 4: + return "Colon"; + case 5: + return "Darien"; + case 6: + return "Herrera"; + case 7: + return "Los Santos"; + case 8: + return "Panama"; + case 9: + return "San Blas"; + case 10: + return "Veraguas"; + default: + return NULL; + } +} + +static const char *get_region_name_PE(int region_code) { + switch (region_code) { + case 1: + return "Amazonas"; + case 2: + return "Ancash"; + case 3: + return "Apurimac"; + case 4: + return "Arequipa"; + case 5: + return "Ayacucho"; + case 6: + return "Cajamarca"; + case 7: + return "Callao"; + case 8: + return "Cusco"; + case 9: + return "Huancavelica"; + case 10: + return "Huanuco"; + case 11: + return "Ica"; + case 12: + return "Junin"; + case 13: + return "La Libertad"; + case 14: + return "Lambayeque"; + case 15: + return "Lima"; + case 16: + return "Loreto"; + case 17: + return "Madre de Dios"; + case 18: + return "Moquegua"; + case 19: + return "Pasco"; + case 20: + return "Piura"; + case 21: + return "Puno"; + case 22: + return "San Martin"; + case 23: + return "Tacna"; + case 24: + return "Tumbes"; + case 25: + return "Ucayali"; + default: + return NULL; + } +} + +static const char *get_region_name_PG(int region_code) { + switch (region_code) { + case 1: + return "Central"; + case 2: + return "Gulf"; + case 3: + return "Milne Bay"; + case 4: + return "Northern"; + case 5: + return "Southern Highlands"; + case 6: + return "Western"; + case 7: + return "North Solomons"; + case 8: + return "Chimbu"; + case 9: + return "Eastern Highlands"; + case 10: + return "East New Britain"; + case 11: + return "East Sepik"; + case 12: + return "Madang"; + case 13: + return "Manus"; + case 14: + return "Morobe"; + case 15: + return "New Ireland"; + case 16: + return "Western Highlands"; + case 17: + return "West New Britain"; + case 18: + return "Sandaun"; + case 19: + return "Enga"; + case 20: + return "National Capital"; + default: + return NULL; + } +} + +static const char *get_region_name_PH(int region_code) { + switch (region_code) { + case 1: + return "Abra"; + case 2: + return "Agusan del Norte"; + case 3: + return "Agusan del Sur"; + case 4: + return "Aklan"; + case 5: + return "Albay"; + case 6: + return "Antique"; + case 7: + return "Bataan"; + case 8: + return "Batanes"; + case 9: + return "Batangas"; + case 10: + return "Benguet"; + case 11: + return "Bohol"; + case 12: + return "Bukidnon"; + case 13: + return "Bulacan"; + case 14: + return "Cagayan"; + case 15: + return "Camarines Norte"; + case 16: + return "Camarines Sur"; + case 17: + return "Camiguin"; + case 18: + return "Capiz"; + case 19: + return "Catanduanes"; + case 20: + return "Cavite"; + case 21: + return "Cebu"; + case 22: + return "Basilan"; + case 23: + return "Eastern Samar"; + case 24: + return "Davao"; + case 25: + return "Davao del Sur"; + case 26: + return "Davao Oriental"; + case 27: + return "Ifugao"; + case 28: + return "Ilocos Norte"; + case 29: + return "Ilocos Sur"; + case 30: + return "Iloilo"; + case 31: + return "Isabela"; + case 32: + return "Kalinga-Apayao"; + case 33: + return "Laguna"; + case 34: + return "Lanao del Norte"; + case 35: + return "Lanao del Sur"; + case 36: + return "La Union"; + case 37: + return "Leyte"; + case 38: + return "Marinduque"; + case 39: + return "Masbate"; + case 40: + return "Mindoro Occidental"; + case 41: + return "Mindoro Oriental"; + case 42: + return "Misamis Occidental"; + case 43: + return "Misamis Oriental"; + case 44: + return "Mountain"; + case 45: + return "Negros Occidental"; + case 46: + return "Negros Oriental"; + case 47: + return "Nueva Ecija"; + case 48: + return "Nueva Vizcaya"; + case 49: + return "Palawan"; + case 50: + return "Pampanga"; + case 51: + return "Pangasinan"; + case 53: + return "Rizal"; + case 54: + return "Romblon"; + case 55: + return "Samar"; + case 56: + return "Maguindanao"; + case 57: + return "North Cotabato"; + case 58: + return "Sorsogon"; + case 59: + return "Southern Leyte"; + case 60: + return "Sulu"; + case 61: + return "Surigao del Norte"; + case 62: + return "Surigao del Sur"; + case 63: + return "Tarlac"; + case 64: + return "Zambales"; + case 65: + return "Zamboanga del Norte"; + case 66: + return "Zamboanga del Sur"; + case 67: + return "Northern Samar"; + case 68: + return "Quirino"; + case 69: + return "Siquijor"; + case 70: + return "South Cotabato"; + case 71: + return "Sultan Kudarat"; + case 72: + return "Tawitawi"; + case 832: + return "Angeles"; + case 833: + return "Bacolod"; + case 834: + return "Bago"; + case 835: + return "Baguio"; + case 836: + return "Bais"; + case 837: + return "Basilan City"; + case 838: + return "Batangas City"; + case 839: + return "Butuan"; + case 840: + return "Cabanatuan"; + case 875: + return "Cadiz"; + case 876: + return "Cagayan de Oro"; + case 877: + return "Calbayog"; + case 878: + return "Caloocan"; + case 879: + return "Canlaon"; + case 880: + return "Cavite City"; + case 881: + return "Cebu City"; + case 882: + return "Cotabato"; + case 883: + return "Dagupan"; + case 918: + return "Danao"; + case 919: + return "Dapitan"; + case 920: + return "Davao City"; + case 921: + return "Dipolog"; + case 922: + return "Dumaguete"; + case 923: + return "General Santos"; + case 924: + return "Gingoog"; + case 925: + return "Iligan"; + case 926: + return "Iloilo City"; + case 961: + return "Iriga"; + case 962: + return "La Carlota"; + case 963: + return "Laoag"; + case 964: + return "Lapu-Lapu"; + case 965: + return "Legaspi"; + case 966: + return "Lipa"; + case 967: + return "Lucena"; + case 968: + return "Mandaue"; + case 969: + return "Manila"; + case 1004: + return "Marawi"; + case 1005: + return "Naga"; + case 1006: + return "Olongapo"; + case 1007: + return "Ormoc"; + case 1008: + return "Oroquieta"; + case 1009: + return "Ozamis"; + case 1010: + return "Pagadian"; + case 1011: + return "Palayan"; + case 1012: + return "Pasay"; + case 1047: + return "Puerto Princesa"; + case 1048: + return "Quezon City"; + case 1049: + return "Roxas"; + case 1050: + return "San Carlos"; + case 1051: + return "San Carlos"; + case 1052: + return "San Jose"; + case 1053: + return "San Pablo"; + case 1054: + return "Silay"; + case 1055: + return "Surigao"; + case 1090: + return "Tacloban"; + case 1091: + return "Tagaytay"; + case 1092: + return "Tagbilaran"; + case 1093: + return "Tangub"; + case 1094: + return "Toledo"; + case 1095: + return "Trece Martires"; + case 1096: + return "Zamboanga"; + case 1097: + return "Aurora"; + case 1134: + return "Quezon"; + case 1135: + return "Negros Occidental"; + case 1141: + return "Biliran"; + case 1181: + return "Compostela Valley"; + case 1182: + return "Davao del Norte"; + case 1221: + return "Guimaras"; + case 1222: + return "Himamaylan"; + case 1225: + return "Kalinga"; + case 1262: + return "Las Pinas"; + case 1266: + return "Malabon"; + case 1267: + return "Malaybalay"; + case 1308: + return "Muntinlupa"; + case 1309: + return "Navotas"; + case 1311: + return "Paranaque"; + case 1313: + return "Passi"; + case 1477: + return "Zambales"; + case 1352: + return "San Jose del Monte"; + case 1353: + return "San Juan"; + case 1355: + return "Santiago"; + case 1356: + return "Sarangani"; + case 1391: + return "Sipalay"; + case 1393: + return "Surigao del Norte"; + case 1478: + return "Zamboanga"; + default: + return NULL; + } +} + +static const char *get_region_name_PK(int region_code) { + switch (region_code) { + case 1: + return "Federally Administered Tribal Areas"; + case 2: + return "Balochistan"; + case 3: + return "North-West Frontier"; + case 4: + return "Punjab"; + case 5: + return "Sindh"; + case 6: + return "Azad Kashmir"; + case 7: + return "Northern Areas"; + case 8: + return "Islamabad"; + default: + return NULL; + } +} + +static const char *get_region_name_PL(int region_code) { + switch (region_code) { + case 72: + return "Dolnoslaskie"; + case 73: + return "Kujawsko-Pomorskie"; + case 74: + return "Lodzkie"; + case 75: + return "Lubelskie"; + case 76: + return "Lubuskie"; + case 77: + return "Malopolskie"; + case 78: + return "Mazowieckie"; + case 79: + return "Opolskie"; + case 80: + return "Podkarpackie"; + case 81: + return "Podlaskie"; + case 82: + return "Pomorskie"; + case 83: + return "Slaskie"; + case 84: + return "Swietokrzyskie"; + case 85: + return "Warminsko-Mazurskie"; + case 86: + return "Wielkopolskie"; + case 87: + return "Zachodniopomorskie"; + default: + return NULL; + } +} + +static const char *get_region_name_PS(int region_code) { + switch (region_code) { + case 1131: + return "Gaza"; + case 1798: + return "West Bank"; + default: + return NULL; + } +} + +static const char *get_region_name_PT(int region_code) { + switch (region_code) { + case 2: + return "Aveiro"; + case 3: + return "Beja"; + case 4: + return "Braga"; + case 5: + return "Braganca"; + case 6: + return "Castelo Branco"; + case 7: + return "Coimbra"; + case 8: + return "Evora"; + case 9: + return "Faro"; + case 10: + return "Madeira"; + case 11: + return "Guarda"; + case 13: + return "Leiria"; + case 14: + return "Lisboa"; + case 16: + return "Portalegre"; + case 17: + return "Porto"; + case 18: + return "Santarem"; + case 19: + return "Setubal"; + case 20: + return "Viana do Castelo"; + case 21: + return "Vila Real"; + case 22: + return "Viseu"; + case 23: + return "Azores"; + default: + return NULL; + } +} + +static const char *get_region_name_PY(int region_code) { + switch (region_code) { + case 1: + return "Alto Parana"; + case 2: + return "Amambay"; + case 4: + return "Caaguazu"; + case 5: + return "Caazapa"; + case 6: + return "Central"; + case 7: + return "Concepcion"; + case 8: + return "Cordillera"; + case 10: + return "Guaira"; + case 11: + return "Itapua"; + case 12: + return "Misiones"; + case 13: + return "Neembucu"; + case 15: + return "Paraguari"; + case 16: + return "Presidente Hayes"; + case 17: + return "San Pedro"; + case 19: + return "Canindeyu"; + case 22: + return "Asuncion"; + case 23: + return "Alto Paraguay"; + case 24: + return "Boqueron"; + default: + return NULL; + } +} + +static const char *get_region_name_QA(int region_code) { + switch (region_code) { + case 1: + return "Ad Dawhah"; + case 2: + return "Al Ghuwariyah"; + case 3: + return "Al Jumaliyah"; + case 4: + return "Al Khawr"; + case 5: + return "Al Wakrah Municipality"; + case 6: + return "Ar Rayyan"; + case 8: + return "Madinat ach Shamal"; + case 9: + return "Umm Salal"; + case 10: + return "Al Wakrah"; + case 11: + return "Jariyan al Batnah"; + case 12: + return "Umm Sa'id"; + default: + return NULL; + } +} + +static const char *get_region_name_RO(int region_code) { + switch (region_code) { + case 1: + return "Alba"; + case 2: + return "Arad"; + case 3: + return "Arges"; + case 4: + return "Bacau"; + case 5: + return "Bihor"; + case 6: + return "Bistrita-Nasaud"; + case 7: + return "Botosani"; + case 8: + return "Braila"; + case 9: + return "Brasov"; + case 10: + return "Bucuresti"; + case 11: + return "Buzau"; + case 12: + return "Caras-Severin"; + case 13: + return "Cluj"; + case 14: + return "Constanta"; + case 15: + return "Covasna"; + case 16: + return "Dambovita"; + case 17: + return "Dolj"; + case 18: + return "Galati"; + case 19: + return "Gorj"; + case 20: + return "Harghita"; + case 21: + return "Hunedoara"; + case 22: + return "Ialomita"; + case 23: + return "Iasi"; + case 25: + return "Maramures"; + case 26: + return "Mehedinti"; + case 27: + return "Mures"; + case 28: + return "Neamt"; + case 29: + return "Olt"; + case 30: + return "Prahova"; + case 31: + return "Salaj"; + case 32: + return "Satu Mare"; + case 33: + return "Sibiu"; + case 34: + return "Suceava"; + case 35: + return "Teleorman"; + case 36: + return "Timis"; + case 37: + return "Tulcea"; + case 38: + return "Vaslui"; + case 39: + return "Valcea"; + case 40: + return "Vrancea"; + case 41: + return "Calarasi"; + case 42: + return "Giurgiu"; + case 43: + return "Ilfov"; + default: + return NULL; + } +} + +static const char *get_region_name_RS(int region_code) { + switch (region_code) { + case 1: + return "Kosovo"; + case 2: + return "Vojvodina"; + default: + return NULL; + } +} + +static const char *get_region_name_RU(int region_code) { + switch (region_code) { + case 1: + return "Adygeya, Republic of"; + case 2: + return "Aginsky Buryatsky AO"; + case 3: + return "Gorno-Altay"; + case 4: + return "Altaisky krai"; + case 5: + return "Amur"; + case 6: + return "Arkhangel'sk"; + case 7: + return "Astrakhan'"; + case 8: + return "Bashkortostan"; + case 9: + return "Belgorod"; + case 10: + return "Bryansk"; + case 11: + return "Buryat"; + case 12: + return "Chechnya"; + case 13: + return "Chelyabinsk"; + case 14: + return "Chita"; + case 15: + return "Chukot"; + case 16: + return "Chuvashia"; + case 17: + return "Dagestan"; + case 18: + return "Evenk"; + case 19: + return "Ingush"; + case 20: + return "Irkutsk"; + case 21: + return "Ivanovo"; + case 22: + return "Kabardin-Balkar"; + case 23: + return "Kaliningrad"; + case 24: + return "Kalmyk"; + case 25: + return "Kaluga"; + case 26: + return "Kamchatka"; + case 27: + return "Karachay-Cherkess"; + case 28: + return "Karelia"; + case 29: + return "Kemerovo"; + case 30: + return "Khabarovsk"; + case 31: + return "Khakass"; + case 32: + return "Khanty-Mansiy"; + case 33: + return "Kirov"; + case 34: + return "Komi"; + case 36: + return "Koryak"; + case 37: + return "Kostroma"; + case 38: + return "Krasnodar"; + case 39: + return "Krasnoyarsk"; + case 40: + return "Kurgan"; + case 41: + return "Kursk"; + case 42: + return "Leningrad"; + case 43: + return "Lipetsk"; + case 44: + return "Magadan"; + case 45: + return "Mariy-El"; + case 46: + return "Mordovia"; + case 47: + return "Moskva"; + case 48: + return "Moscow City"; + case 49: + return "Murmansk"; + case 50: + return "Nenets"; + case 51: + return "Nizhegorod"; + case 52: + return "Novgorod"; + case 53: + return "Novosibirsk"; + case 54: + return "Omsk"; + case 55: + return "Orenburg"; + case 56: + return "Orel"; + case 57: + return "Penza"; + case 58: + return "Perm'"; + case 59: + return "Primor'ye"; + case 60: + return "Pskov"; + case 61: + return "Rostov"; + case 62: + return "Ryazan'"; + case 63: + return "Sakha"; + case 64: + return "Sakhalin"; + case 65: + return "Samara"; + case 66: + return "Saint Petersburg City"; + case 67: + return "Saratov"; + case 68: + return "North Ossetia"; + case 69: + return "Smolensk"; + case 70: + return "Stavropol'"; + case 71: + return "Sverdlovsk"; + case 72: + return "Tambovskaya oblast"; + case 73: + return "Tatarstan"; + case 74: + return "Taymyr"; + case 75: + return "Tomsk"; + case 76: + return "Tula"; + case 77: + return "Tver'"; + case 78: + return "Tyumen'"; + case 79: + return "Tuva"; + case 80: + return "Udmurt"; + case 81: + return "Ul'yanovsk"; + case 83: + return "Vladimir"; + case 84: + return "Volgograd"; + case 85: + return "Vologda"; + case 86: + return "Voronezh"; + case 87: + return "Yamal-Nenets"; + case 88: + return "Yaroslavl'"; + case 89: + return "Yevrey"; + case 90: + return "Permskiy Kray"; + case 91: + return "Krasnoyarskiy Kray"; + case 92: + return "Kamchatskiy Kray"; + case 93: + return "Zabaykal'skiy Kray"; + default: + return NULL; + } +} + +static const char *get_region_name_RW(int region_code) { + switch (region_code) { + case 1: + return "Butare"; + case 6: + return "Gitarama"; + case 7: + return "Kibungo"; + case 9: + return "Kigali"; + case 11: + return "Est"; + case 12: + return "Kigali"; + case 13: + return "Nord"; + case 14: + return "Ouest"; + case 15: + return "Sud"; + default: + return NULL; + } +} + +static const char *get_region_name_SA(int region_code) { + switch (region_code) { + case 2: + return "Al Bahah"; + case 5: + return "Al Madinah"; + case 6: + return "Ash Sharqiyah"; + case 8: + return "Al Qasim"; + case 10: + return "Ar Riyad"; + case 11: + return "Asir Province"; + case 13: + return "Ha'il"; + case 14: + return "Makkah"; + case 15: + return "Al Hudud ash Shamaliyah"; + case 16: + return "Najran"; + case 17: + return "Jizan"; + case 19: + return "Tabuk"; + case 20: + return "Al Jawf"; + default: + return NULL; + } +} + +static const char *get_region_name_SB(int region_code) { + switch (region_code) { + case 3: + return "Malaita"; + case 6: + return "Guadalcanal"; + case 7: + return "Isabel"; + case 8: + return "Makira"; + case 9: + return "Temotu"; + case 10: + return "Central"; + case 11: + return "Western"; + case 12: + return "Choiseul"; + case 13: + return "Rennell and Bellona"; + default: + return NULL; + } +} + +static const char *get_region_name_SC(int region_code) { + switch (region_code) { + case 1: + return "Anse aux Pins"; + case 2: + return "Anse Boileau"; + case 3: + return "Anse Etoile"; + case 4: + return "Anse Louis"; + case 5: + return "Anse Royale"; + case 6: + return "Baie Lazare"; + case 7: + return "Baie Sainte Anne"; + case 8: + return "Beau Vallon"; + case 9: + return "Bel Air"; + case 10: + return "Bel Ombre"; + case 11: + return "Cascade"; + case 12: + return "Glacis"; + case 13: + return "Grand' Anse"; + case 14: + return "Grand' Anse"; + case 15: + return "La Digue"; + case 16: + return "La Riviere Anglaise"; + case 17: + return "Mont Buxton"; + case 18: + return "Mont Fleuri"; + case 19: + return "Plaisance"; + case 20: + return "Pointe La Rue"; + case 21: + return "Port Glaud"; + case 22: + return "Saint Louis"; + case 23: + return "Takamaka"; + default: + return NULL; + } +} + +static const char *get_region_name_SD(int region_code) { + switch (region_code) { + case 27: + return "Al Wusta"; + case 28: + return "Al Istiwa'iyah"; + case 29: + return "Al Khartum"; + case 30: + return "Ash Shamaliyah"; + case 31: + return "Ash Sharqiyah"; + case 32: + return "Bahr al Ghazal"; + case 33: + return "Darfur"; + case 34: + return "Kurdufan"; + case 35: + return "Upper Nile"; + case 40: + return "Al Wahadah State"; + case 44: + return "Central Equatoria State"; + case 49: + return "Southern Darfur"; + case 50: + return "Southern Kordofan"; + case 52: + return "Kassala"; + case 53: + return "River Nile"; + case 55: + return "Northern Darfur"; + default: + return NULL; + } +} + +static const char *get_region_name_SE(int region_code) { + switch (region_code) { + case 2: + return "Blekinge Lan"; + case 3: + return "Gavleborgs Lan"; + case 5: + return "Gotlands Lan"; + case 6: + return "Hallands Lan"; + case 7: + return "Jamtlands Lan"; + case 8: + return "Jonkopings Lan"; + case 9: + return "Kalmar Lan"; + case 10: + return "Dalarnas Lan"; + case 12: + return "Kronobergs Lan"; + case 14: + return "Norrbottens Lan"; + case 15: + return "Orebro Lan"; + case 16: + return "Ostergotlands Lan"; + case 18: + return "Sodermanlands Lan"; + case 21: + return "Uppsala Lan"; + case 22: + return "Varmlands Lan"; + case 23: + return "Vasterbottens Lan"; + case 24: + return "Vasternorrlands Lan"; + case 25: + return "Vastmanlands Lan"; + case 26: + return "Stockholms Lan"; + case 27: + return "Skane Lan"; + case 28: + return "Vastra Gotaland"; + default: + return NULL; + } +} + +static const char *get_region_name_SH(int region_code) { + switch (region_code) { + case 1: + return "Ascension"; + case 2: + return "Saint Helena"; + case 3: + return "Tristan da Cunha"; + default: + return NULL; + } +} + +static const char *get_region_name_SI(int region_code) { + switch (region_code) { + case 1: + return "Ajdovscina Commune"; + case 2: + return "Beltinci Commune"; + case 3: + return "Bled Commune"; + case 4: + return "Bohinj Commune"; + case 5: + return "Borovnica Commune"; + case 6: + return "Bovec Commune"; + case 7: + return "Brda Commune"; + case 8: + return "Brezice Commune"; + case 9: + return "Brezovica Commune"; + case 11: + return "Celje Commune"; + case 12: + return "Cerklje na Gorenjskem Commune"; + case 13: + return "Cerknica Commune"; + case 14: + return "Cerkno Commune"; + case 15: + return "Crensovci Commune"; + case 16: + return "Crna na Koroskem Commune"; + case 17: + return "Crnomelj Commune"; + case 19: + return "Divaca Commune"; + case 20: + return "Dobrepolje Commune"; + case 22: + return "Dol pri Ljubljani Commune"; + case 24: + return "Dornava Commune"; + case 25: + return "Dravograd Commune"; + case 26: + return "Duplek Commune"; + case 27: + return "Gorenja vas-Poljane Commune"; + case 28: + return "Gorisnica Commune"; + case 29: + return "Gornja Radgona Commune"; + case 30: + return "Gornji Grad Commune"; + case 31: + return "Gornji Petrovci Commune"; + case 32: + return "Grosuplje Commune"; + case 34: + return "Hrastnik Commune"; + case 35: + return "Hrpelje-Kozina Commune"; + case 36: + return "Idrija Commune"; + case 37: + return "Ig Commune"; + case 38: + return "Ilirska Bistrica Commune"; + case 39: + return "Ivancna Gorica Commune"; + case 40: + return "Izola-Isola Commune"; + case 42: + return "Jursinci Commune"; + case 44: + return "Kanal Commune"; + case 45: + return "Kidricevo Commune"; + case 46: + return "Kobarid Commune"; + case 47: + return "Kobilje Commune"; + case 49: + return "Komen Commune"; + case 50: + return "Koper-Capodistria Urban Commune"; + case 51: + return "Kozje Commune"; + case 52: + return "Kranj Commune"; + case 53: + return "Kranjska Gora Commune"; + case 54: + return "Krsko Commune"; + case 55: + return "Kungota Commune"; + case 57: + return "Lasko Commune"; + case 61: + return "Ljubljana Urban Commune"; + case 62: + return "Ljubno Commune"; + case 64: + return "Logatec Commune"; + case 66: + return "Loski Potok Commune"; + case 68: + return "Lukovica Commune"; + case 71: + return "Medvode Commune"; + case 72: + return "Menges Commune"; + case 73: + return "Metlika Commune"; + case 74: + return "Mezica Commune"; + case 76: + return "Mislinja Commune"; + case 77: + return "Moravce Commune"; + case 78: + return "Moravske Toplice Commune"; + case 79: + return "Mozirje Commune"; + case 80: + return "Murska Sobota Urban Commune"; + case 81: + return "Muta Commune"; + case 82: + return "Naklo Commune"; + case 83: + return "Nazarje Commune"; + case 84: + return "Nova Gorica Urban Commune"; + case 86: + return "Odranci Commune"; + case 87: + return "Ormoz Commune"; + case 88: + return "Osilnica Commune"; + case 89: + return "Pesnica Commune"; + case 91: + return "Pivka Commune"; + case 92: + return "Podcetrtek Commune"; + case 94: + return "Postojna Commune"; + case 97: + return "Puconci Commune"; + case 98: + return "Race-Fram Commune"; + case 99: + return "Radece Commune"; + case 832: + return "Radenci Commune"; + case 833: + return "Radlje ob Dravi Commune"; + case 834: + return "Radovljica Commune"; + case 837: + return "Rogasovci Commune"; + case 838: + return "Rogaska Slatina Commune"; + case 839: + return "Rogatec Commune"; + case 875: + return "Semic Commune"; + case 876: + return "Sencur Commune"; + case 877: + return "Sentilj Commune"; + case 878: + return "Sentjernej Commune"; + case 880: + return "Sevnica Commune"; + case 881: + return "Sezana Commune"; + case 882: + return "Skocjan Commune"; + case 883: + return "Skofja Loka Commune"; + case 918: + return "Skofljica Commune"; + case 919: + return "Slovenj Gradec Urban Commune"; + case 921: + return "Slovenske Konjice Commune"; + case 922: + return "Smarje pri Jelsah Commune"; + case 923: + return "Smartno ob Paki Commune"; + case 924: + return "Sostanj Commune"; + case 925: + return "Starse Commune"; + case 926: + return "Store Commune"; + case 961: + return "Sveti Jurij Commune"; + case 962: + return "Tolmin Commune"; + case 963: + return "Trbovlje Commune"; + case 964: + return "Trebnje Commune"; + case 965: + return "Trzic Commune"; + case 966: + return "Turnisce Commune"; + case 967: + return "Velenje Urban Commune"; + case 968: + return "Velike Lasce Commune"; + case 1004: + return "Vipava Commune"; + case 1005: + return "Vitanje Commune"; + case 1006: + return "Vodice Commune"; + case 1008: + return "Vrhnika Commune"; + case 1009: + return "Vuzenica Commune"; + case 1010: + return "Zagorje ob Savi Commune"; + case 1012: + return "Zavrc Commune"; + case 1047: + return "Zelezniki Commune"; + case 1048: + return "Ziri Commune"; + case 1049: + return "Zrece Commune"; + case 1050: + return "Benedikt Commune"; + case 1051: + return "Bistrica ob Sotli Commune"; + case 1052: + return "Bloke Commune"; + case 1053: + return "Braslovce Commune"; + case 1054: + return "Cankova Commune"; + case 1055: + return "Cerkvenjak Commune"; + case 1090: + return "Destrnik Commune"; + case 1091: + return "Dobje Commune"; + case 1092: + return "Dobrna Commune"; + case 1093: + return "Dobrova-Horjul-Polhov Gradec Commune"; + case 1094: + return "Dobrovnik-Dobronak Commune"; + case 1095: + return "Dolenjske Toplice Commune"; + case 1096: + return "Domzale Commune"; + case 1097: + return "Grad Commune"; + case 1098: + return "Hajdina Commune"; + case 1133: + return "Hoce-Slivnica Commune"; + case 1134: + return "Hodos-Hodos Commune"; + case 1135: + return "Horjul Commune"; + case 1136: + return "Jesenice Commune"; + case 1137: + return "Jezersko Commune"; + case 1138: + return "Kamnik Commune"; + case 1139: + return "Kocevje Commune"; + case 1140: + return "Komenda Commune"; + case 1141: + return "Kostel Commune"; + case 1176: + return "Krizevci Commune"; + case 1177: + return "Kuzma Commune"; + case 1178: + return "Lenart Commune"; + case 1179: + return "Lendava-Lendva Commune"; + case 1180: + return "Litija Commune"; + case 1181: + return "Ljutomer Commune"; + case 1182: + return "Loska Dolina Commune"; + case 1183: + return "Lovrenc na Pohorju Commune"; + case 1184: + return "Luce Commune"; + case 1219: + return "Majsperk Commune"; + case 1220: + return "Maribor Commune"; + case 1221: + return "Markovci Commune"; + case 1222: + return "Miklavz na Dravskem polju Commune"; + case 1223: + return "Miren-Kostanjevica Commune"; + case 1224: + return "Mirna Pec Commune"; + case 1225: + return "Novo mesto Urban Commune"; + case 1226: + return "Oplotnica Commune"; + case 1227: + return "Piran-Pirano Commune"; + case 1262: + return "Podlehnik Commune"; + case 1263: + return "Podvelka Commune"; + case 1264: + return "Polzela Commune"; + case 1265: + return "Prebold Commune"; + case 1266: + return "Preddvor Commune"; + case 1267: + return "Prevalje Commune"; + case 1268: + return "Ptuj Urban Commune"; + case 1269: + return "Ravne na Koroskem Commune"; + case 1270: + return "Razkrizje Commune"; + case 1305: + return "Ribnica Commune"; + case 1306: + return "Ribnica na Pohorju Commune"; + case 1307: + return "Ruse Commune"; + case 1308: + return "Salovci Commune"; + case 1309: + return "Selnica ob Dravi Commune"; + case 1310: + return "Sempeter-Vrtojba Commune"; + case 1311: + return "Sentjur pri Celju Commune"; + case 1312: + return "Slovenska Bistrica Commune"; + case 1313: + return "Smartno pri Litiji Commune"; + case 1348: + return "Sodrazica Commune"; + case 1349: + return "Solcava Commune"; + case 1350: + return "Sveta Ana Commune"; + case 1351: + return "Sveti Andraz v Slovenskih goricah Commune"; + case 1352: + return "Tabor Commune"; + case 1353: + return "Tisina Commune"; + case 1354: + return "Trnovska vas Commune"; + case 1355: + return "Trzin Commune"; + case 1356: + return "Velika Polana Commune"; + case 1391: + return "Verzej Commune"; + case 1392: + return "Videm Commune"; + case 1393: + return "Vojnik Commune"; + case 1394: + return "Vransko Commune"; + case 1395: + return "Zalec Commune"; + case 1396: + return "Zetale Commune"; + case 1397: + return "Zirovnica Commune"; + case 1398: + return "Zuzemberk Commune"; + case 1399: + return "Apace Commune"; + case 1434: + return "Cirkulane Commune"; + case 1435: + return "Gorje"; + case 1436: + return "Kostanjevica na Krki"; + case 1437: + return "Log-Dragomer"; + case 1438: + return "Makole"; + case 1439: + return "Mirna"; + case 1440: + return "Mokronog-Trebelno"; + case 1441: + return "Poljcane"; + case 1442: + return "Recica ob Savinji"; + case 1477: + return "Rence-Vogrsko"; + case 1478: + return "Sentrupert"; + case 1479: + return "Smarjesk Toplice"; + case 1480: + return "Sredisce ob Dravi"; + case 1481: + return "Straza"; + case 1483: + return "Sveti Jurij v Slovenskih Goricah"; + default: + return NULL; + } +} + +static const char *get_region_name_SK(int region_code) { + switch (region_code) { + case 1: + return "Banska Bystrica"; + case 2: + return "Bratislava"; + case 3: + return "Kosice"; + case 4: + return "Nitra"; + case 5: + return "Presov"; + case 6: + return "Trencin"; + case 7: + return "Trnava"; + case 8: + return "Zilina"; + default: + return NULL; + } +} + +static const char *get_region_name_SL(int region_code) { + switch (region_code) { + case 1: + return "Eastern"; + case 2: + return "Northern"; + case 3: + return "Southern"; + case 4: + return "Western Area"; + default: + return NULL; + } +} + +static const char *get_region_name_SM(int region_code) { + switch (region_code) { + case 1: + return "Acquaviva"; + case 2: + return "Chiesanuova"; + case 3: + return "Domagnano"; + case 4: + return "Faetano"; + case 5: + return "Fiorentino"; + case 6: + return "Borgo Maggiore"; + case 7: + return "San Marino"; + case 8: + return "Monte Giardino"; + case 9: + return "Serravalle"; + default: + return NULL; + } +} + +static const char *get_region_name_SN(int region_code) { + switch (region_code) { + case 1: + return "Dakar"; + case 3: + return "Diourbel"; + case 5: + return "Tambacounda"; + case 7: + return "Thies"; + case 9: + return "Fatick"; + case 10: + return "Kaolack"; + case 11: + return "Kolda"; + case 12: + return "Ziguinchor"; + case 13: + return "Louga"; + case 14: + return "Saint-Louis"; + case 15: + return "Matam"; + default: + return NULL; + } +} + +static const char *get_region_name_SO(int region_code) { + switch (region_code) { + case 1: + return "Bakool"; + case 2: + return "Banaadir"; + case 3: + return "Bari"; + case 4: + return "Bay"; + case 5: + return "Galguduud"; + case 6: + return "Gedo"; + case 7: + return "Hiiraan"; + case 8: + return "Jubbada Dhexe"; + case 9: + return "Jubbada Hoose"; + case 10: + return "Mudug"; + case 11: + return "Nugaal"; + case 12: + return "Sanaag"; + case 13: + return "Shabeellaha Dhexe"; + case 14: + return "Shabeellaha Hoose"; + case 16: + return "Woqooyi Galbeed"; + case 18: + return "Nugaal"; + case 19: + return "Togdheer"; + case 20: + return "Woqooyi Galbeed"; + case 21: + return "Awdal"; + case 22: + return "Sool"; + default: + return NULL; + } +} + +static const char *get_region_name_SR(int region_code) { + switch (region_code) { + case 10: + return "Brokopondo"; + case 11: + return "Commewijne"; + case 12: + return "Coronie"; + case 13: + return "Marowijne"; + case 14: + return "Nickerie"; + case 15: + return "Para"; + case 16: + return "Paramaribo"; + case 17: + return "Saramacca"; + case 18: + return "Sipaliwini"; + case 19: + return "Wanica"; + default: + return NULL; + } +} + +static const char *get_region_name_SS(int region_code) { + switch (region_code) { + case 1: + return "Central Equatoria"; + case 2: + return "Eastern Equatoria"; + case 3: + return "Jonglei"; + case 4: + return "Lakes"; + case 5: + return "Northern Bahr el Ghazal"; + case 6: + return "Unity"; + case 7: + return "Upper Nile"; + case 8: + return "Warrap"; + case 9: + return "Western Bahr el Ghazal"; + case 10: + return "Western Equatoria"; + default: + return NULL; + } +} + +static const char *get_region_name_ST(int region_code) { + switch (region_code) { + case 1: + return "Principe"; + case 2: + return "Sao Tome"; + default: + return NULL; + } +} + +static const char *get_region_name_SV(int region_code) { + switch (region_code) { + case 1: + return "Ahuachapan"; + case 2: + return "Cabanas"; + case 3: + return "Chalatenango"; + case 4: + return "Cuscatlan"; + case 5: + return "La Libertad"; + case 6: + return "La Paz"; + case 7: + return "La Union"; + case 8: + return "Morazan"; + case 9: + return "San Miguel"; + case 10: + return "San Salvador"; + case 11: + return "Santa Ana"; + case 12: + return "San Vicente"; + case 13: + return "Sonsonate"; + case 14: + return "Usulutan"; + default: + return NULL; + } +} + +static const char *get_region_name_SY(int region_code) { + switch (region_code) { + case 1: + return "Al Hasakah"; + case 2: + return "Al Ladhiqiyah"; + case 3: + return "Al Qunaytirah"; + case 4: + return "Ar Raqqah"; + case 5: + return "As Suwayda'"; + case 6: + return "Dar"; + case 7: + return "Dayr az Zawr"; + case 8: + return "Rif Dimashq"; + case 9: + return "Halab"; + case 10: + return "Hamah"; + case 11: + return "Hims"; + case 12: + return "Idlib"; + case 13: + return "Dimashq"; + case 14: + return "Tartus"; + default: + return NULL; + } +} + +static const char *get_region_name_SZ(int region_code) { + switch (region_code) { + case 1: + return "Hhohho"; + case 2: + return "Lubombo"; + case 3: + return "Manzini"; + case 4: + return "Shiselweni"; + case 5: + return "Praslin"; + default: + return NULL; + } +} + +static const char *get_region_name_TD(int region_code) { + switch (region_code) { + case 1: + return "Batha"; + case 2: + return "Biltine"; + case 3: + return "Borkou-Ennedi-Tibesti"; + case 4: + return "Chari-Baguirmi"; + case 5: + return "Guera"; + case 6: + return "Kanem"; + case 7: + return "Lac"; + case 8: + return "Logone Occidental"; + case 9: + return "Logone Oriental"; + case 10: + return "Mayo-Kebbi"; + case 11: + return "Moyen-Chari"; + case 12: + return "Ouaddai"; + case 13: + return "Salamat"; + case 14: + return "Tandjile"; + default: + return NULL; + } +} + +static const char *get_region_name_TG(int region_code) { + switch (region_code) { + case 22: + return "Centrale"; + case 23: + return "Kara"; + case 24: + return "Maritime"; + case 25: + return "Plateaux"; + case 26: + return "Savanes"; + default: + return NULL; + } +} + +static const char *get_region_name_TH(int region_code) { + switch (region_code) { + case 1: + return "Mae Hong Son"; + case 2: + return "Chiang Mai"; + case 3: + return "Chiang Rai"; + case 4: + return "Nan"; + case 5: + return "Lamphun"; + case 6: + return "Lampang"; + case 7: + return "Phrae"; + case 8: + return "Tak"; + case 9: + return "Sukhothai"; + case 10: + return "Uttaradit"; + case 11: + return "Kamphaeng Phet"; + case 12: + return "Phitsanulok"; + case 13: + return "Phichit"; + case 14: + return "Phetchabun"; + case 15: + return "Uthai Thani"; + case 16: + return "Nakhon Sawan"; + case 17: + return "Nong Khai"; + case 18: + return "Loei"; + case 20: + return "Sakon Nakhon"; + case 21: + return "Nakhon Phanom"; + case 22: + return "Khon Kaen"; + case 23: + return "Kalasin"; + case 24: + return "Maha Sarakham"; + case 25: + return "Roi Et"; + case 26: + return "Chaiyaphum"; + case 27: + return "Nakhon Ratchasima"; + case 28: + return "Buriram"; + case 29: + return "Surin"; + case 30: + return "Sisaket"; + case 31: + return "Narathiwat"; + case 32: + return "Chai Nat"; + case 33: + return "Sing Buri"; + case 34: + return "Lop Buri"; + case 35: + return "Ang Thong"; + case 36: + return "Phra Nakhon Si Ayutthaya"; + case 37: + return "Saraburi"; + case 38: + return "Nonthaburi"; + case 39: + return "Pathum Thani"; + case 40: + return "Krung Thep"; + case 41: + return "Phayao"; + case 42: + return "Samut Prakan"; + case 43: + return "Nakhon Nayok"; + case 44: + return "Chachoengsao"; + case 45: + return "Prachin Buri"; + case 46: + return "Chon Buri"; + case 47: + return "Rayong"; + case 48: + return "Chanthaburi"; + case 49: + return "Trat"; + case 50: + return "Kanchanaburi"; + case 51: + return "Suphan Buri"; + case 52: + return "Ratchaburi"; + case 53: + return "Nakhon Pathom"; + case 54: + return "Samut Songkhram"; + case 55: + return "Samut Sakhon"; + case 56: + return "Phetchaburi"; + case 57: + return "Prachuap Khiri Khan"; + case 58: + return "Chumphon"; + case 59: + return "Ranong"; + case 60: + return "Surat Thani"; + case 61: + return "Phangnga"; + case 62: + return "Phuket"; + case 63: + return "Krabi"; + case 64: + return "Nakhon Si Thammarat"; + case 65: + return "Trang"; + case 66: + return "Phatthalung"; + case 67: + return "Satun"; + case 68: + return "Songkhla"; + case 69: + return "Pattani"; + case 70: + return "Yala"; + case 71: + return "Ubon Ratchathani"; + case 72: + return "Yasothon"; + case 73: + return "Nakhon Phanom"; + case 74: + return "Prachin Buri"; + case 75: + return "Ubon Ratchathani"; + case 76: + return "Udon Thani"; + case 77: + return "Amnat Charoen"; + case 78: + return "Mukdahan"; + case 79: + return "Nong Bua Lamphu"; + case 80: + return "Sa Kaeo"; + case 81: + return "Bueng Kan"; + default: + return NULL; + } +} + +static const char *get_region_name_TJ(int region_code) { + switch (region_code) { + case 1: + return "Kuhistoni Badakhshon"; + case 2: + return "Khatlon"; + case 3: + return "Sughd"; + case 4: + return "Dushanbe"; + case 5: + return "Nohiyahoi Tobei Jumhuri"; + default: + return NULL; + } +} + +static const char *get_region_name_TL(int region_code) { + switch (region_code) { + case 6: + return "Dili"; + default: + return NULL; + } +} + +static const char *get_region_name_TM(int region_code) { + switch (region_code) { + case 1: + return "Ahal"; + case 2: + return "Balkan"; + case 3: + return "Dashoguz"; + case 4: + return "Lebap"; + case 5: + return "Mary"; + default: + return NULL; + } +} + +static const char *get_region_name_TN(int region_code) { + switch (region_code) { + case 2: + return "Kasserine"; + case 3: + return "Kairouan"; + case 6: + return "Jendouba"; + case 10: + return "Qafsah"; + case 14: + return "El Kef"; + case 15: + return "Al Mahdia"; + case 16: + return "Al Munastir"; + case 17: + return "Bajah"; + case 18: + return "Bizerte"; + case 19: + return "Nabeul"; + case 22: + return "Siliana"; + case 23: + return "Sousse"; + case 27: + return "Ben Arous"; + case 28: + return "Madanin"; + case 29: + return "Gabes"; + case 31: + return "Kebili"; + case 32: + return "Sfax"; + case 33: + return "Sidi Bou Zid"; + case 34: + return "Tataouine"; + case 35: + return "Tozeur"; + case 36: + return "Tunis"; + case 37: + return "Zaghouan"; + case 38: + return "Aiana"; + case 39: + return "Manouba"; + default: + return NULL; + } +} + +static const char *get_region_name_TO(int region_code) { + switch (region_code) { + case 1: + return "Ha"; + case 2: + return "Tongatapu"; + case 3: + return "Vava"; + default: + return NULL; + } +} + +static const char *get_region_name_TR(int region_code) { + switch (region_code) { + case 2: + return "Adiyaman"; + case 3: + return "Afyonkarahisar"; + case 4: + return "Agri"; + case 5: + return "Amasya"; + case 7: + return "Antalya"; + case 8: + return "Artvin"; + case 9: + return "Aydin"; + case 10: + return "Balikesir"; + case 11: + return "Bilecik"; + case 12: + return "Bingol"; + case 13: + return "Bitlis"; + case 14: + return "Bolu"; + case 15: + return "Burdur"; + case 16: + return "Bursa"; + case 17: + return "Canakkale"; + case 19: + return "Corum"; + case 20: + return "Denizli"; + case 21: + return "Diyarbakir"; + case 22: + return "Edirne"; + case 23: + return "Elazig"; + case 24: + return "Erzincan"; + case 25: + return "Erzurum"; + case 26: + return "Eskisehir"; + case 28: + return "Giresun"; + case 31: + return "Hatay"; + case 32: + return "Mersin"; + case 33: + return "Isparta"; + case 34: + return "Istanbul"; + case 35: + return "Izmir"; + case 37: + return "Kastamonu"; + case 38: + return "Kayseri"; + case 39: + return "Kirklareli"; + case 40: + return "Kirsehir"; + case 41: + return "Kocaeli"; + case 43: + return "Kutahya"; + case 44: + return "Malatya"; + case 45: + return "Manisa"; + case 46: + return "Kahramanmaras"; + case 48: + return "Mugla"; + case 49: + return "Mus"; + case 50: + return "Nevsehir"; + case 52: + return "Ordu"; + case 53: + return "Rize"; + case 54: + return "Sakarya"; + case 55: + return "Samsun"; + case 57: + return "Sinop"; + case 58: + return "Sivas"; + case 59: + return "Tekirdag"; + case 60: + return "Tokat"; + case 61: + return "Trabzon"; + case 62: + return "Tunceli"; + case 63: + return "Sanliurfa"; + case 64: + return "Usak"; + case 65: + return "Van"; + case 66: + return "Yozgat"; + case 68: + return "Ankara"; + case 69: + return "Gumushane"; + case 70: + return "Hakkari"; + case 71: + return "Konya"; + case 72: + return "Mardin"; + case 73: + return "Nigde"; + case 74: + return "Siirt"; + case 75: + return "Aksaray"; + case 76: + return "Batman"; + case 77: + return "Bayburt"; + case 78: + return "Karaman"; + case 79: + return "Kirikkale"; + case 80: + return "Sirnak"; + case 81: + return "Adana"; + case 82: + return "Cankiri"; + case 83: + return "Gaziantep"; + case 84: + return "Kars"; + case 85: + return "Zonguldak"; + case 86: + return "Ardahan"; + case 87: + return "Bartin"; + case 88: + return "Igdir"; + case 89: + return "Karabuk"; + case 90: + return "Kilis"; + case 91: + return "Osmaniye"; + case 92: + return "Yalova"; + case 93: + return "Duzce"; + default: + return NULL; + } +} + +static const char *get_region_name_TT(int region_code) { + switch (region_code) { + case 1: + return "Arima"; + case 2: + return "Caroni"; + case 3: + return "Mayaro"; + case 4: + return "Nariva"; + case 5: + return "Port-of-Spain"; + case 6: + return "Saint Andrew"; + case 7: + return "Saint David"; + case 8: + return "Saint George"; + case 9: + return "Saint Patrick"; + case 10: + return "San Fernando"; + case 11: + return "Tobago"; + case 12: + return "Victoria"; + default: + return NULL; + } +} + +static const char *get_region_name_TW(int region_code) { + switch (region_code) { + case 1: + return "Fu-chien"; + case 2: + return "Kao-hsiung"; + case 3: + return "T'ai-pei"; + case 4: + return "T'ai-wan"; + default: + return NULL; + } +} + +static const char *get_region_name_TZ(int region_code) { + switch (region_code) { + case 2: + return "Pwani"; + case 3: + return "Dodoma"; + case 4: + return "Iringa"; + case 5: + return "Kigoma"; + case 6: + return "Kilimanjaro"; + case 7: + return "Lindi"; + case 8: + return "Mara"; + case 9: + return "Mbeya"; + case 10: + return "Morogoro"; + case 11: + return "Mtwara"; + case 12: + return "Mwanza"; + case 13: + return "Pemba North"; + case 14: + return "Ruvuma"; + case 15: + return "Shinyanga"; + case 16: + return "Singida"; + case 17: + return "Tabora"; + case 18: + return "Tanga"; + case 19: + return "Kagera"; + case 20: + return "Pemba South"; + case 21: + return "Zanzibar Central"; + case 22: + return "Zanzibar North"; + case 23: + return "Dar es Salaam"; + case 24: + return "Rukwa"; + case 25: + return "Zanzibar Urban"; + case 26: + return "Arusha"; + case 27: + return "Manyara"; + default: + return NULL; + } +} + +static const char *get_region_name_UA(int region_code) { + switch (region_code) { + case 1: + return "Cherkas'ka Oblast'"; + case 2: + return "Chernihivs'ka Oblast'"; + case 3: + return "Chernivets'ka Oblast'"; + case 4: + return "Dnipropetrovs'ka Oblast'"; + case 5: + return "Donets'ka Oblast'"; + case 6: + return "Ivano-Frankivs'ka Oblast'"; + case 7: + return "Kharkivs'ka Oblast'"; + case 8: + return "Khersons'ka Oblast'"; + case 9: + return "Khmel'nyts'ka Oblast'"; + case 10: + return "Kirovohrads'ka Oblast'"; + case 11: + return "Krym"; + case 12: + return "Kyyiv"; + case 13: + return "Kyyivs'ka Oblast'"; + case 14: + return "Luhans'ka Oblast'"; + case 15: + return "L'vivs'ka Oblast'"; + case 16: + return "Mykolayivs'ka Oblast'"; + case 17: + return "Odes'ka Oblast'"; + case 18: + return "Poltavs'ka Oblast'"; + case 19: + return "Rivnens'ka Oblast'"; + case 20: + return "Sevastopol'"; + case 21: + return "Sums'ka Oblast'"; + case 22: + return "Ternopil's'ka Oblast'"; + case 23: + return "Vinnyts'ka Oblast'"; + case 24: + return "Volyns'ka Oblast'"; + case 25: + return "Zakarpats'ka Oblast'"; + case 26: + return "Zaporiz'ka Oblast'"; + case 27: + return "Zhytomyrs'ka Oblast'"; + default: + return NULL; + } +} + +static const char *get_region_name_UG(int region_code) { + switch (region_code) { + case 26: + return "Apac"; + case 28: + return "Bundibugyo"; + case 29: + return "Bushenyi"; + case 30: + return "Gulu"; + case 31: + return "Hoima"; + case 33: + return "Jinja"; + case 36: + return "Kalangala"; + case 37: + return "Kampala"; + case 38: + return "Kamuli"; + case 39: + return "Kapchorwa"; + case 40: + return "Kasese"; + case 41: + return "Kibale"; + case 42: + return "Kiboga"; + case 43: + return "Kisoro"; + case 45: + return "Kotido"; + case 46: + return "Kumi"; + case 47: + return "Lira"; + case 50: + return "Masindi"; + case 52: + return "Mbarara"; + case 56: + return "Mubende"; + case 58: + return "Nebbi"; + case 59: + return "Ntungamo"; + case 60: + return "Pallisa"; + case 61: + return "Rakai"; + case 65: + return "Adjumani"; + case 66: + return "Bugiri"; + case 67: + return "Busia"; + case 69: + return "Katakwi"; + case 70: + return "Luwero"; + case 71: + return "Masaka"; + case 72: + return "Moyo"; + case 73: + return "Nakasongola"; + case 74: + return "Sembabule"; + case 76: + return "Tororo"; + case 77: + return "Arua"; + case 78: + return "Iganga"; + case 79: + return "Kabarole"; + case 80: + return "Kaberamaido"; + case 81: + return "Kamwenge"; + case 82: + return "Kanungu"; + case 83: + return "Kayunga"; + case 84: + return "Kitgum"; + case 85: + return "Kyenjojo"; + case 86: + return "Mayuge"; + case 87: + return "Mbale"; + case 88: + return "Moroto"; + case 89: + return "Mpigi"; + case 90: + return "Mukono"; + case 91: + return "Nakapiripirit"; + case 92: + return "Pader"; + case 93: + return "Rukungiri"; + case 94: + return "Sironko"; + case 95: + return "Soroti"; + case 96: + return "Wakiso"; + case 97: + return "Yumbe"; + default: + return NULL; + } +} + +static const char *get_region_name_US(int region_code) { + switch (region_code) { + case 848: + return "Armed Forces Americas"; + case 852: + return "Armed Forces Europe, Middle East, & Canada"; + case 858: + return "Alaska"; + case 859: + return "Alabama"; + case 863: + return "Armed Forces Pacific"; + case 865: + return "Arkansas"; + case 866: + return "American Samoa"; + case 873: + return "Arizona"; + case 934: + return "California"; + case 948: + return "Colorado"; + case 953: + return "Connecticut"; + case 979: + return "District of Columbia"; + case 981: + return "Delaware"; + case 1074: + return "Florida"; + case 1075: + return "Federated States of Micronesia"; + case 1106: + return "Georgia"; + case 1126: + return "Guam"; + case 1157: + return "Hawaii"; + case 1192: + return "Iowa"; + case 1195: + return "Idaho"; + case 1203: + return "Illinois"; + case 1205: + return "Indiana"; + case 1296: + return "Kansas"; + case 1302: + return "Kentucky"; + case 1321: + return "Louisiana"; + case 1364: + return "Massachusetts"; + case 1367: + return "Maryland"; + case 1368: + return "Maine"; + case 1371: + return "Marshall Islands"; + case 1372: + return "Michigan"; + case 1377: + return "Minnesota"; + case 1378: + return "Missouri"; + case 1379: + return "Northern Mariana Islands"; + case 1382: + return "Mississippi"; + case 1383: + return "Montana"; + case 1409: + return "North Carolina"; + case 1410: + return "North Dakota"; + case 1411: + return "Nebraska"; + case 1414: + return "New Hampshire"; + case 1416: + return "New Jersey"; + case 1419: + return "New Mexico"; + case 1428: + return "Nevada"; + case 1431: + return "New York"; + case 1457: + return "Ohio"; + case 1460: + return "Oklahoma"; + case 1467: + return "Oregon"; + case 1493: + return "Pennsylvania"; + case 1515: + return "Palau"; + case 1587: + return "Rhode Island"; + case 1624: + return "South Carolina"; + case 1625: + return "South Dakota"; + case 1678: + return "Tennessee"; + case 1688: + return "Texas"; + case 1727: + return "Utah"; + case 1751: + return "Virginia"; + case 1759: + return "Virgin Islands"; + case 1770: + return "Vermont"; + case 1794: + return "Washington"; + case 1802: + return "Wisconsin"; + case 1815: + return "West Virginia"; + case 1818: + return "Wyoming"; + default: + return NULL; + } +} + +static const char *get_region_name_UY(int region_code) { + switch (region_code) { + case 1: + return "Artigas"; + case 2: + return "Canelones"; + case 3: + return "Cerro Largo"; + case 4: + return "Colonia"; + case 5: + return "Durazno"; + case 6: + return "Flores"; + case 7: + return "Florida"; + case 8: + return "Lavalleja"; + case 9: + return "Maldonado"; + case 10: + return "Montevideo"; + case 11: + return "Paysandu"; + case 12: + return "Rio Negro"; + case 13: + return "Rivera"; + case 14: + return "Rocha"; + case 15: + return "Salto"; + case 16: + return "San Jose"; + case 17: + return "Soriano"; + case 18: + return "Tacuarembo"; + case 19: + return "Treinta y Tres"; + default: + return NULL; + } +} + +static const char *get_region_name_UZ(int region_code) { + switch (region_code) { + case 1: + return "Andijon"; + case 2: + return "Bukhoro"; + case 3: + return "Farghona"; + case 4: + return "Jizzakh"; + case 5: + return "Khorazm"; + case 6: + return "Namangan"; + case 7: + return "Nawoiy"; + case 8: + return "Qashqadaryo"; + case 9: + return "Qoraqalpoghiston"; + case 10: + return "Samarqand"; + case 11: + return "Sirdaryo"; + case 12: + return "Surkhondaryo"; + case 13: + return "Toshkent"; + case 14: + return "Toshkent"; + case 15: + return "Jizzax"; + default: + return NULL; + } +} + +static const char *get_region_name_VC(int region_code) { + switch (region_code) { + case 1: + return "Charlotte"; + case 2: + return "Saint Andrew"; + case 3: + return "Saint David"; + case 4: + return "Saint George"; + case 5: + return "Saint Patrick"; + case 6: + return "Grenadines"; + default: + return NULL; + } +} + +static const char *get_region_name_VE(int region_code) { + switch (region_code) { + case 1: + return "Amazonas"; + case 2: + return "Anzoategui"; + case 3: + return "Apure"; + case 4: + return "Aragua"; + case 5: + return "Barinas"; + case 6: + return "Bolivar"; + case 7: + return "Carabobo"; + case 8: + return "Cojedes"; + case 9: + return "Delta Amacuro"; + case 11: + return "Falcon"; + case 12: + return "Guarico"; + case 13: + return "Lara"; + case 14: + return "Merida"; + case 15: + return "Miranda"; + case 16: + return "Monagas"; + case 17: + return "Nueva Esparta"; + case 18: + return "Portuguesa"; + case 19: + return "Sucre"; + case 20: + return "Tachira"; + case 21: + return "Trujillo"; + case 22: + return "Yaracuy"; + case 23: + return "Zulia"; + case 24: + return "Dependencias Federales"; + case 25: + return "Distrito Federal"; + case 26: + return "Vargas"; + default: + return NULL; + } +} + +static const char *get_region_name_VN(int region_code) { + switch (region_code) { + case 1: + return "An Giang"; + case 3: + return "Ben Tre"; + case 5: + return "Cao Bang"; + case 9: + return "Dong Thap"; + case 13: + return "Hai Phong"; + case 20: + return "Ho Chi Minh"; + case 21: + return "Kien Giang"; + case 23: + return "Lam Dong"; + case 24: + return "Long An"; + case 30: + return "Quang Ninh"; + case 32: + return "Son La"; + case 33: + return "Tay Ninh"; + case 34: + return "Thanh Hoa"; + case 35: + return "Thai Binh"; + case 37: + return "Tien Giang"; + case 39: + return "Lang Son"; + case 43: + return "Dong Nai"; + case 44: + return "Ha Noi"; + case 45: + return "Ba Ria-Vung Tau"; + case 46: + return "Binh Dinh"; + case 47: + return "Binh Thuan"; + case 49: + return "Gia Lai"; + case 50: + return "Ha Giang"; + case 52: + return "Ha Tinh"; + case 53: + return "Hoa Binh"; + case 54: + return "Khanh Hoa"; + case 55: + return "Kon Tum"; + case 58: + return "Nghe An"; + case 59: + return "Ninh Binh"; + case 60: + return "Ninh Thuan"; + case 61: + return "Phu Yen"; + case 62: + return "Quang Binh"; + case 63: + return "Quang Ngai"; + case 64: + return "Quang Tri"; + case 65: + return "Soc Trang"; + case 66: + return "Thua Thien-Hue"; + case 67: + return "Tra Vinh"; + case 68: + return "Tuyen Quang"; + case 69: + return "Vinh Long"; + case 70: + return "Yen Bai"; + case 71: + return "Bac Giang"; + case 72: + return "Bac Kan"; + case 73: + return "Bac Lieu"; + case 74: + return "Bac Ninh"; + case 75: + return "Binh Duong"; + case 76: + return "Binh Phuoc"; + case 77: + return "Ca Mau"; + case 78: + return "Da Nang"; + case 79: + return "Hai Duong"; + case 80: + return "Ha Nam"; + case 81: + return "Hung Yen"; + case 82: + return "Nam Dinh"; + case 83: + return "Phu Tho"; + case 84: + return "Quang Nam"; + case 85: + return "Thai Nguyen"; + case 86: + return "Vinh Phuc"; + case 87: + return "Can Tho"; + case 88: + return "Dac Lak"; + case 89: + return "Lai Chau"; + case 90: + return "Lao Cai"; + case 91: + return "Dak Nong"; + case 92: + return "Dien Bien"; + case 93: + return "Hau Giang"; + default: + return NULL; + } +} + +static const char *get_region_name_VU(int region_code) { + switch (region_code) { + case 5: + return "Ambrym"; + case 6: + return "Aoba"; + case 7: + return "Torba"; + case 8: + return "Efate"; + case 9: + return "Epi"; + case 10: + return "Malakula"; + case 11: + return "Paama"; + case 12: + return "Pentecote"; + case 13: + return "Sanma"; + case 14: + return "Shepherd"; + case 15: + return "Tafea"; + case 16: + return "Malampa"; + case 17: + return "Penama"; + case 18: + return "Shefa"; + default: + return NULL; + } +} + +static const char *get_region_name_WS(int region_code) { + switch (region_code) { + case 2: + return "Aiga-i-le-Tai"; + case 3: + return "Atua"; + case 4: + return "Fa"; + case 5: + return "Gaga"; + case 6: + return "Va"; + case 7: + return "Gagaifomauga"; + case 8: + return "Palauli"; + case 9: + return "Satupa"; + case 10: + return "Tuamasaga"; + case 11: + return "Vaisigano"; + default: + return NULL; + } +} + +static const char *get_region_name_YE(int region_code) { + switch (region_code) { + case 1: + return "Abyan"; + case 2: + return "Adan"; + case 3: + return "Al Mahrah"; + case 4: + return "Hadramawt"; + case 5: + return "Shabwah"; + case 6: + return "Lahij"; + case 7: + return "Al Bayda'"; + case 8: + return "Al Hudaydah"; + case 9: + return "Al Jawf"; + case 10: + return "Al Mahwit"; + case 11: + return "Dhamar"; + case 12: + return "Hajjah"; + case 13: + return "Ibb"; + case 14: + return "Ma'rib"; + case 15: + return "Sa'dah"; + case 16: + return "San'a'"; + case 17: + return "Taizz"; + case 18: + return "Ad Dali"; + case 19: + return "Amran"; + case 20: + return "Al Bayda'"; + case 21: + return "Al Jawf"; + case 22: + return "Hajjah"; + case 23: + return "Ibb"; + case 24: + return "Lahij"; + case 25: + return "Taizz"; + default: + return NULL; + } +} + +static const char *get_region_name_ZA(int region_code) { + switch (region_code) { + case 1: + return "North-Western Province"; + case 2: + return "KwaZulu-Natal"; + case 3: + return "Free State"; + case 5: + return "Eastern Cape"; + case 6: + return "Gauteng"; + case 7: + return "Mpumalanga"; + case 8: + return "Northern Cape"; + case 9: + return "Limpopo"; + case 10: + return "North-West"; + case 11: + return "Western Cape"; + default: + return NULL; + } +} + +static const char *get_region_name_ZM(int region_code) { + switch (region_code) { + case 1: + return "Western"; + case 2: + return "Central"; + case 3: + return "Eastern"; + case 4: + return "Luapula"; + case 5: + return "Northern"; + case 6: + return "North-Western"; + case 7: + return "Southern"; + case 8: + return "Copperbelt"; + case 9: + return "Lusaka"; + default: + return NULL; + } +} + +static const char *get_region_name_ZW(int region_code) { + switch (region_code) { + case 1: + return "Manicaland"; + case 2: + return "Midlands"; + case 3: + return "Mashonaland Central"; + case 4: + return "Mashonaland East"; + case 5: + return "Mashonaland West"; + case 6: + return "Matabeleland North"; + case 7: + return "Matabeleland South"; + case 8: + return "Masvingo"; + case 9: + return "Bulawayo"; + case 10: + return "Harare"; + default: + return NULL; + } +} + +const char *GeoIP_region_name_by_code(const char *country_code, + const char *region_code) { + int region_code2 = -1; + if (region_code == NULL) { + return NULL; + } + + if (((region_code[0] >= 48) && (region_code[0] < (48 + 10))) && + ((region_code[1] >= 48) && (region_code[1] < (48 + 10)))) { + + /* only numbers, that shortens the large switch statements */ + region_code2 = (region_code[0] - 48) * 10 + region_code[1] - 48; + } + + else if ((((region_code[0] >= 65) && (region_code[0] < (65 + 26))) || + ((region_code[0] >= 48) && (region_code[0] < (48 + 10)))) && + (((region_code[1] >= 65) && (region_code[1] < (65 + 26))) || + ((region_code[1] >= 48) && (region_code[1] < (48 + 10))))) { + + region_code2 = + (region_code[0] - 48) * (65 + 26 - 48) + region_code[1] - 48 + 100; + } + + if (region_code2 == -1) { + return NULL; + } + + if (strcmp(country_code, "AD") == 0) { + return get_region_name_AD(region_code2); + } + if (strcmp(country_code, "AE") == 0) { + return get_region_name_AE(region_code2); + } + if (strcmp(country_code, "AF") == 0) { + return get_region_name_AF(region_code2); + } + if (strcmp(country_code, "AG") == 0) { + return get_region_name_AG(region_code2); + } + if (strcmp(country_code, "AL") == 0) { + return get_region_name_AL(region_code2); + } + if (strcmp(country_code, "AM") == 0) { + return get_region_name_AM(region_code2); + } + if (strcmp(country_code, "AO") == 0) { + return get_region_name_AO(region_code2); + } + if (strcmp(country_code, "AR") == 0) { + return get_region_name_AR(region_code2); + } + if (strcmp(country_code, "AT") == 0) { + return get_region_name_AT(region_code2); + } + if (strcmp(country_code, "AU") == 0) { + return get_region_name_AU(region_code2); + } + if (strcmp(country_code, "AZ") == 0) { + return get_region_name_AZ(region_code2); + } + if (strcmp(country_code, "BA") == 0) { + return get_region_name_BA(region_code2); + } + if (strcmp(country_code, "BB") == 0) { + return get_region_name_BB(region_code2); + } + if (strcmp(country_code, "BD") == 0) { + return get_region_name_BD(region_code2); + } + if (strcmp(country_code, "BE") == 0) { + return get_region_name_BE(region_code2); + } + if (strcmp(country_code, "BF") == 0) { + return get_region_name_BF(region_code2); + } + if (strcmp(country_code, "BG") == 0) { + return get_region_name_BG(region_code2); + } + if (strcmp(country_code, "BH") == 0) { + return get_region_name_BH(region_code2); + } + if (strcmp(country_code, "BI") == 0) { + return get_region_name_BI(region_code2); + } + if (strcmp(country_code, "BJ") == 0) { + return get_region_name_BJ(region_code2); + } + if (strcmp(country_code, "BM") == 0) { + return get_region_name_BM(region_code2); + } + if (strcmp(country_code, "BN") == 0) { + return get_region_name_BN(region_code2); + } + if (strcmp(country_code, "BO") == 0) { + return get_region_name_BO(region_code2); + } + if (strcmp(country_code, "BR") == 0) { + return get_region_name_BR(region_code2); + } + if (strcmp(country_code, "BS") == 0) { + return get_region_name_BS(region_code2); + } + if (strcmp(country_code, "BT") == 0) { + return get_region_name_BT(region_code2); + } + if (strcmp(country_code, "BW") == 0) { + return get_region_name_BW(region_code2); + } + if (strcmp(country_code, "BY") == 0) { + return get_region_name_BY(region_code2); + } + if (strcmp(country_code, "BZ") == 0) { + return get_region_name_BZ(region_code2); + } + if (strcmp(country_code, "CA") == 0) { + return get_region_name_CA(region_code2); + } + if (strcmp(country_code, "CD") == 0) { + return get_region_name_CD(region_code2); + } + if (strcmp(country_code, "CF") == 0) { + return get_region_name_CF(region_code2); + } + if (strcmp(country_code, "CG") == 0) { + return get_region_name_CG(region_code2); + } + if (strcmp(country_code, "CH") == 0) { + return get_region_name_CH(region_code2); + } + if (strcmp(country_code, "CI") == 0) { + return get_region_name_CI(region_code2); + } + if (strcmp(country_code, "CL") == 0) { + return get_region_name_CL(region_code2); + } + if (strcmp(country_code, "CM") == 0) { + return get_region_name_CM(region_code2); + } + if (strcmp(country_code, "CN") == 0) { + return get_region_name_CN(region_code2); + } + if (strcmp(country_code, "CO") == 0) { + return get_region_name_CO(region_code2); + } + if (strcmp(country_code, "CR") == 0) { + return get_region_name_CR(region_code2); + } + if (strcmp(country_code, "CU") == 0) { + return get_region_name_CU(region_code2); + } + if (strcmp(country_code, "CV") == 0) { + return get_region_name_CV(region_code2); + } + if (strcmp(country_code, "CY") == 0) { + return get_region_name_CY(region_code2); + } + if (strcmp(country_code, "CZ") == 0) { + return get_region_name_CZ(region_code2); + } + if (strcmp(country_code, "DE") == 0) { + return get_region_name_DE(region_code2); + } + if (strcmp(country_code, "DJ") == 0) { + return get_region_name_DJ(region_code2); + } + if (strcmp(country_code, "DK") == 0) { + return get_region_name_DK(region_code2); + } + if (strcmp(country_code, "DM") == 0) { + return get_region_name_DM(region_code2); + } + if (strcmp(country_code, "DO") == 0) { + return get_region_name_DO(region_code2); + } + if (strcmp(country_code, "DZ") == 0) { + return get_region_name_DZ(region_code2); + } + if (strcmp(country_code, "EC") == 0) { + return get_region_name_EC(region_code2); + } + if (strcmp(country_code, "EE") == 0) { + return get_region_name_EE(region_code2); + } + if (strcmp(country_code, "EG") == 0) { + return get_region_name_EG(region_code2); + } + if (strcmp(country_code, "ER") == 0) { + return get_region_name_ER(region_code2); + } + if (strcmp(country_code, "ES") == 0) { + return get_region_name_ES(region_code2); + } + if (strcmp(country_code, "ET") == 0) { + return get_region_name_ET(region_code2); + } + if (strcmp(country_code, "FI") == 0) { + return get_region_name_FI(region_code2); + } + if (strcmp(country_code, "FJ") == 0) { + return get_region_name_FJ(region_code2); + } + if (strcmp(country_code, "FM") == 0) { + return get_region_name_FM(region_code2); + } + if (strcmp(country_code, "FR") == 0) { + return get_region_name_FR(region_code2); + } + if (strcmp(country_code, "GA") == 0) { + return get_region_name_GA(region_code2); + } + if (strcmp(country_code, "GB") == 0) { + return get_region_name_GB(region_code2); + } + if (strcmp(country_code, "GD") == 0) { + return get_region_name_GD(region_code2); + } + if (strcmp(country_code, "GE") == 0) { + return get_region_name_GE(region_code2); + } + if (strcmp(country_code, "GH") == 0) { + return get_region_name_GH(region_code2); + } + if (strcmp(country_code, "GL") == 0) { + return get_region_name_GL(region_code2); + } + if (strcmp(country_code, "GM") == 0) { + return get_region_name_GM(region_code2); + } + if (strcmp(country_code, "GN") == 0) { + return get_region_name_GN(region_code2); + } + if (strcmp(country_code, "GQ") == 0) { + return get_region_name_GQ(region_code2); + } + if (strcmp(country_code, "GR") == 0) { + return get_region_name_GR(region_code2); + } + if (strcmp(country_code, "GT") == 0) { + return get_region_name_GT(region_code2); + } + if (strcmp(country_code, "GW") == 0) { + return get_region_name_GW(region_code2); + } + if (strcmp(country_code, "GY") == 0) { + return get_region_name_GY(region_code2); + } + if (strcmp(country_code, "HN") == 0) { + return get_region_name_HN(region_code2); + } + if (strcmp(country_code, "HR") == 0) { + return get_region_name_HR(region_code2); + } + if (strcmp(country_code, "HT") == 0) { + return get_region_name_HT(region_code2); + } + if (strcmp(country_code, "HU") == 0) { + return get_region_name_HU(region_code2); + } + if (strcmp(country_code, "ID") == 0) { + return get_region_name_ID(region_code2); + } + if (strcmp(country_code, "IE") == 0) { + return get_region_name_IE(region_code2); + } + if (strcmp(country_code, "IL") == 0) { + return get_region_name_IL(region_code2); + } + if (strcmp(country_code, "IN") == 0) { + return get_region_name_IN(region_code2); + } + if (strcmp(country_code, "IQ") == 0) { + return get_region_name_IQ(region_code2); + } + if (strcmp(country_code, "IR") == 0) { + return get_region_name_IR(region_code2); + } + if (strcmp(country_code, "IS") == 0) { + return get_region_name_IS(region_code2); + } + if (strcmp(country_code, "IT") == 0) { + return get_region_name_IT(region_code2); + } + if (strcmp(country_code, "JM") == 0) { + return get_region_name_JM(region_code2); + } + if (strcmp(country_code, "JO") == 0) { + return get_region_name_JO(region_code2); + } + if (strcmp(country_code, "JP") == 0) { + return get_region_name_JP(region_code2); + } + if (strcmp(country_code, "KE") == 0) { + return get_region_name_KE(region_code2); + } + if (strcmp(country_code, "KG") == 0) { + return get_region_name_KG(region_code2); + } + if (strcmp(country_code, "KH") == 0) { + return get_region_name_KH(region_code2); + } + if (strcmp(country_code, "KI") == 0) { + return get_region_name_KI(region_code2); + } + if (strcmp(country_code, "KM") == 0) { + return get_region_name_KM(region_code2); + } + if (strcmp(country_code, "KN") == 0) { + return get_region_name_KN(region_code2); + } + if (strcmp(country_code, "KP") == 0) { + return get_region_name_KP(region_code2); + } + if (strcmp(country_code, "KR") == 0) { + return get_region_name_KR(region_code2); + } + if (strcmp(country_code, "KW") == 0) { + return get_region_name_KW(region_code2); + } + if (strcmp(country_code, "KY") == 0) { + return get_region_name_KY(region_code2); + } + if (strcmp(country_code, "KZ") == 0) { + return get_region_name_KZ(region_code2); + } + if (strcmp(country_code, "LA") == 0) { + return get_region_name_LA(region_code2); + } + if (strcmp(country_code, "LB") == 0) { + return get_region_name_LB(region_code2); + } + if (strcmp(country_code, "LC") == 0) { + return get_region_name_LC(region_code2); + } + if (strcmp(country_code, "LI") == 0) { + return get_region_name_LI(region_code2); + } + if (strcmp(country_code, "LK") == 0) { + return get_region_name_LK(region_code2); + } + if (strcmp(country_code, "LR") == 0) { + return get_region_name_LR(region_code2); + } + if (strcmp(country_code, "LS") == 0) { + return get_region_name_LS(region_code2); + } + if (strcmp(country_code, "LT") == 0) { + return get_region_name_LT(region_code2); + } + if (strcmp(country_code, "LU") == 0) { + return get_region_name_LU(region_code2); + } + if (strcmp(country_code, "LV") == 0) { + return get_region_name_LV(region_code2); + } + if (strcmp(country_code, "LY") == 0) { + return get_region_name_LY(region_code2); + } + if (strcmp(country_code, "MA") == 0) { + return get_region_name_MA(region_code2); + } + if (strcmp(country_code, "MC") == 0) { + return get_region_name_MC(region_code2); + } + if (strcmp(country_code, "MD") == 0) { + return get_region_name_MD(region_code2); + } + if (strcmp(country_code, "MG") == 0) { + return get_region_name_MG(region_code2); + } + if (strcmp(country_code, "MK") == 0) { + return get_region_name_MK(region_code2); + } + if (strcmp(country_code, "ML") == 0) { + return get_region_name_ML(region_code2); + } + if (strcmp(country_code, "MM") == 0) { + return get_region_name_MM(region_code2); + } + if (strcmp(country_code, "MN") == 0) { + return get_region_name_MN(region_code2); + } + if (strcmp(country_code, "MO") == 0) { + return get_region_name_MO(region_code2); + } + if (strcmp(country_code, "MR") == 0) { + return get_region_name_MR(region_code2); + } + if (strcmp(country_code, "MS") == 0) { + return get_region_name_MS(region_code2); + } + if (strcmp(country_code, "MU") == 0) { + return get_region_name_MU(region_code2); + } + if (strcmp(country_code, "MV") == 0) { + return get_region_name_MV(region_code2); + } + if (strcmp(country_code, "MW") == 0) { + return get_region_name_MW(region_code2); + } + if (strcmp(country_code, "MX") == 0) { + return get_region_name_MX(region_code2); + } + if (strcmp(country_code, "MY") == 0) { + return get_region_name_MY(region_code2); + } + if (strcmp(country_code, "MZ") == 0) { + return get_region_name_MZ(region_code2); + } + if (strcmp(country_code, "NA") == 0) { + return get_region_name_NA(region_code2); + } + if (strcmp(country_code, "NE") == 0) { + return get_region_name_NE(region_code2); + } + if (strcmp(country_code, "NG") == 0) { + return get_region_name_NG(region_code2); + } + if (strcmp(country_code, "NI") == 0) { + return get_region_name_NI(region_code2); + } + if (strcmp(country_code, "NL") == 0) { + return get_region_name_NL(region_code2); + } + if (strcmp(country_code, "NO") == 0) { + return get_region_name_NO(region_code2); + } + if (strcmp(country_code, "NP") == 0) { + return get_region_name_NP(region_code2); + } + if (strcmp(country_code, "NR") == 0) { + return get_region_name_NR(region_code2); + } + if (strcmp(country_code, "NZ") == 0) { + return get_region_name_NZ(region_code2); + } + if (strcmp(country_code, "OM") == 0) { + return get_region_name_OM(region_code2); + } + if (strcmp(country_code, "PA") == 0) { + return get_region_name_PA(region_code2); + } + if (strcmp(country_code, "PE") == 0) { + return get_region_name_PE(region_code2); + } + if (strcmp(country_code, "PG") == 0) { + return get_region_name_PG(region_code2); + } + if (strcmp(country_code, "PH") == 0) { + return get_region_name_PH(region_code2); + } + if (strcmp(country_code, "PK") == 0) { + return get_region_name_PK(region_code2); + } + if (strcmp(country_code, "PL") == 0) { + return get_region_name_PL(region_code2); + } + if (strcmp(country_code, "PS") == 0) { + return get_region_name_PS(region_code2); + } + if (strcmp(country_code, "PT") == 0) { + return get_region_name_PT(region_code2); + } + if (strcmp(country_code, "PY") == 0) { + return get_region_name_PY(region_code2); + } + if (strcmp(country_code, "QA") == 0) { + return get_region_name_QA(region_code2); + } + if (strcmp(country_code, "RO") == 0) { + return get_region_name_RO(region_code2); + } + if (strcmp(country_code, "RS") == 0) { + return get_region_name_RS(region_code2); + } + if (strcmp(country_code, "RU") == 0) { + return get_region_name_RU(region_code2); + } + if (strcmp(country_code, "RW") == 0) { + return get_region_name_RW(region_code2); + } + if (strcmp(country_code, "SA") == 0) { + return get_region_name_SA(region_code2); + } + if (strcmp(country_code, "SB") == 0) { + return get_region_name_SB(region_code2); + } + if (strcmp(country_code, "SC") == 0) { + return get_region_name_SC(region_code2); + } + if (strcmp(country_code, "SD") == 0) { + return get_region_name_SD(region_code2); + } + if (strcmp(country_code, "SE") == 0) { + return get_region_name_SE(region_code2); + } + if (strcmp(country_code, "SH") == 0) { + return get_region_name_SH(region_code2); + } + if (strcmp(country_code, "SI") == 0) { + return get_region_name_SI(region_code2); + } + if (strcmp(country_code, "SK") == 0) { + return get_region_name_SK(region_code2); + } + if (strcmp(country_code, "SL") == 0) { + return get_region_name_SL(region_code2); + } + if (strcmp(country_code, "SM") == 0) { + return get_region_name_SM(region_code2); + } + if (strcmp(country_code, "SN") == 0) { + return get_region_name_SN(region_code2); + } + if (strcmp(country_code, "SO") == 0) { + return get_region_name_SO(region_code2); + } + if (strcmp(country_code, "SR") == 0) { + return get_region_name_SR(region_code2); + } + if (strcmp(country_code, "SS") == 0) { + return get_region_name_SS(region_code2); + } + if (strcmp(country_code, "ST") == 0) { + return get_region_name_ST(region_code2); + } + if (strcmp(country_code, "SV") == 0) { + return get_region_name_SV(region_code2); + } + if (strcmp(country_code, "SY") == 0) { + return get_region_name_SY(region_code2); + } + if (strcmp(country_code, "SZ") == 0) { + return get_region_name_SZ(region_code2); + } + if (strcmp(country_code, "TD") == 0) { + return get_region_name_TD(region_code2); + } + if (strcmp(country_code, "TG") == 0) { + return get_region_name_TG(region_code2); + } + if (strcmp(country_code, "TH") == 0) { + return get_region_name_TH(region_code2); + } + if (strcmp(country_code, "TJ") == 0) { + return get_region_name_TJ(region_code2); + } + if (strcmp(country_code, "TL") == 0) { + return get_region_name_TL(region_code2); + } + if (strcmp(country_code, "TM") == 0) { + return get_region_name_TM(region_code2); + } + if (strcmp(country_code, "TN") == 0) { + return get_region_name_TN(region_code2); + } + if (strcmp(country_code, "TO") == 0) { + return get_region_name_TO(region_code2); + } + if (strcmp(country_code, "TR") == 0) { + return get_region_name_TR(region_code2); + } + if (strcmp(country_code, "TT") == 0) { + return get_region_name_TT(region_code2); + } + if (strcmp(country_code, "TW") == 0) { + return get_region_name_TW(region_code2); + } + if (strcmp(country_code, "TZ") == 0) { + return get_region_name_TZ(region_code2); + } + if (strcmp(country_code, "UA") == 0) { + return get_region_name_UA(region_code2); + } + if (strcmp(country_code, "UG") == 0) { + return get_region_name_UG(region_code2); + } + if (strcmp(country_code, "US") == 0) { + return get_region_name_US(region_code2); + } + if (strcmp(country_code, "UY") == 0) { + return get_region_name_UY(region_code2); + } + if (strcmp(country_code, "UZ") == 0) { + return get_region_name_UZ(region_code2); + } + if (strcmp(country_code, "VC") == 0) { + return get_region_name_VC(region_code2); + } + if (strcmp(country_code, "VE") == 0) { + return get_region_name_VE(region_code2); + } + if (strcmp(country_code, "VN") == 0) { + return get_region_name_VN(region_code2); + } + if (strcmp(country_code, "VU") == 0) { + return get_region_name_VU(region_code2); + } + if (strcmp(country_code, "WS") == 0) { + return get_region_name_WS(region_code2); + } + if (strcmp(country_code, "YE") == 0) { + return get_region_name_YE(region_code2); + } + if (strcmp(country_code, "ZA") == 0) { + return get_region_name_ZA(region_code2); + } + if (strcmp(country_code, "ZM") == 0) { + return get_region_name_ZM(region_code2); + } + if (strcmp(country_code, "ZW") == 0) { + return get_region_name_ZW(region_code2); + } + return NULL; +} diff --git a/libGeoIP/timeZone.c b/libGeoIP/timeZone.c new file mode 100644 index 0000000..cc30619 --- /dev/null +++ b/libGeoIP/timeZone.c @@ -0,0 +1,1775 @@ +#include +const char *GeoIP_time_zone_by_country_and_region(const char *country, + const char *region) { + const char *timezone = NULL; + if (country == NULL) { + return NULL; + } + if (region == NULL) { + region = ""; + } + if (strcmp(country, "AD") == 0) { + return "Europe/Andorra"; + } + if (strcmp(country, "AE") == 0) { + return "Asia/Dubai"; + } + if (strcmp(country, "AF") == 0) { + return "Asia/Kabul"; + } + if (strcmp(country, "AG") == 0) { + return "America/Antigua"; + } + if (strcmp(country, "AI") == 0) { + return "America/Anguilla"; + } + if (strcmp(country, "AL") == 0) { + return "Europe/Tirane"; + } + if (strcmp(country, "AM") == 0) { + return "Asia/Yerevan"; + } + if (strcmp(country, "AN") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "AO") == 0) { + return "Africa/Luanda"; + } + if (strcmp(country, "AQ") == 0) { + return "Antarctica/South_Pole"; + } + if (strcmp(country, "AR") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "02") == 0) { + return "America/Argentina/Catamarca"; + } else if (strcmp(region, "03") == 0) { + return "America/Argentina/Tucuman"; + } else if (strcmp(region, "04") == 0) { + return "America/Argentina/Rio_Gallegos"; + } else if (strcmp(region, "05") == 0) { + return "America/Argentina/Cordoba"; + } else if (strcmp(region, "06") == 0) { + return "America/Argentina/Tucuman"; + } else if (strcmp(region, "07") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "08") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "09") == 0) { + return "America/Argentina/Tucuman"; + } else if (strcmp(region, "10") == 0) { + return "America/Argentina/Jujuy"; + } else if (strcmp(region, "11") == 0) { + return "America/Argentina/San_Luis"; + } else if (strcmp(region, "12") == 0) { + return "America/Argentina/La_Rioja"; + } else if (strcmp(region, "13") == 0) { + return "America/Argentina/Mendoza"; + } else if (strcmp(region, "14") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "15") == 0) { + return "America/Argentina/San_Luis"; + } else if (strcmp(region, "16") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "17") == 0) { + return "America/Argentina/Salta"; + } else if (strcmp(region, "18") == 0) { + return "America/Argentina/San_Juan"; + } else if (strcmp(region, "19") == 0) { + return "America/Argentina/San_Luis"; + } else if (strcmp(region, "20") == 0) { + return "America/Argentina/Rio_Gallegos"; + } else if (strcmp(region, "21") == 0) { + return "America/Argentina/Buenos_Aires"; + } else if (strcmp(region, "22") == 0) { + return "America/Argentina/Catamarca"; + } else if (strcmp(region, "23") == 0) { + return "America/Argentina/Ushuaia"; + } else if (strcmp(region, "24") == 0) { + return "America/Argentina/Tucuman"; + } else { + return NULL; + } + } + if (strcmp(country, "AS") == 0) { + return "Pacific/Pago_Pago"; + } + if (strcmp(country, "AT") == 0) { + return "Europe/Vienna"; + } + if (strcmp(country, "AU") == 0) { + if (strcmp(region, "01") == 0) { + return "Australia/Sydney"; + } else if (strcmp(region, "02") == 0) { + return "Australia/Sydney"; + } else if (strcmp(region, "03") == 0) { + return "Australia/Darwin"; + } else if (strcmp(region, "04") == 0) { + return "Australia/Brisbane"; + } else if (strcmp(region, "05") == 0) { + return "Australia/Adelaide"; + } else if (strcmp(region, "06") == 0) { + return "Australia/Hobart"; + } else if (strcmp(region, "07") == 0) { + return "Australia/Melbourne"; + } else if (strcmp(region, "08") == 0) { + return "Australia/Perth"; + } else { + return NULL; + } + } + if (strcmp(country, "AW") == 0) { + return "America/Aruba"; + } + if (strcmp(country, "AX") == 0) { + return "Europe/Mariehamn"; + } + if (strcmp(country, "AZ") == 0) { + return "Asia/Baku"; + } + if (strcmp(country, "BA") == 0) { + return "Europe/Sarajevo"; + } + if (strcmp(country, "BB") == 0) { + return "America/Barbados"; + } + if (strcmp(country, "BD") == 0) { + return "Asia/Dhaka"; + } + if (strcmp(country, "BE") == 0) { + return "Europe/Brussels"; + } + if (strcmp(country, "BF") == 0) { + return "Africa/Ouagadougou"; + } + if (strcmp(country, "BG") == 0) { + return "Europe/Sofia"; + } + if (strcmp(country, "BH") == 0) { + return "Asia/Bahrain"; + } + if (strcmp(country, "BI") == 0) { + return "Africa/Bujumbura"; + } + if (strcmp(country, "BJ") == 0) { + return "Africa/Porto-Novo"; + } + if (strcmp(country, "BL") == 0) { + return "America/St_Barthelemy"; + } + if (strcmp(country, "BM") == 0) { + return "Atlantic/Bermuda"; + } + if (strcmp(country, "BN") == 0) { + return "Asia/Brunei"; + } + if (strcmp(country, "BO") == 0) { + return "America/La_Paz"; + } + if (strcmp(country, "BQ") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "BR") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Rio_Branco"; + } else if (strcmp(region, "02") == 0) { + return "America/Maceio"; + } else if (strcmp(region, "03") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "04") == 0) { + return "America/Manaus"; + } else if (strcmp(region, "05") == 0) { + return "America/Bahia"; + } else if (strcmp(region, "06") == 0) { + return "America/Fortaleza"; + } else if (strcmp(region, "07") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "08") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "11") == 0) { + return "America/Campo_Grande"; + } else if (strcmp(region, "13") == 0) { + return "America/Belem"; + } else if (strcmp(region, "14") == 0) { + return "America/Cuiaba"; + } else if (strcmp(region, "15") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "16") == 0) { + return "America/Belem"; + } else if (strcmp(region, "17") == 0) { + return "America/Recife"; + } else if (strcmp(region, "18") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "20") == 0) { + return "America/Fortaleza"; + } else if (strcmp(region, "21") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "22") == 0) { + return "America/Recife"; + } else if (strcmp(region, "23") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "24") == 0) { + return "America/Porto_Velho"; + } else if (strcmp(region, "25") == 0) { + return "America/Boa_Vista"; + } else if (strcmp(region, "26") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "27") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "28") == 0) { + return "America/Maceio"; + } else if (strcmp(region, "29") == 0) { + return "America/Sao_Paulo"; + } else if (strcmp(region, "30") == 0) { + return "America/Recife"; + } else if (strcmp(region, "31") == 0) { + return "America/Araguaina"; + } else { + return NULL; + } + } + if (strcmp(country, "BS") == 0) { + return "America/Nassau"; + } + if (strcmp(country, "BT") == 0) { + return "Asia/Thimphu"; + } + if (strcmp(country, "BV") == 0) { + return "Antarctica/Syowa"; + } + if (strcmp(country, "BW") == 0) { + return "Africa/Gaborone"; + } + if (strcmp(country, "BY") == 0) { + return "Europe/Minsk"; + } + if (strcmp(country, "BZ") == 0) { + return "America/Belize"; + } + if (strcmp(country, "CA") == 0) { + if (strcmp(region, "AB") == 0) { + return "America/Edmonton"; + } else if (strcmp(region, "BC") == 0) { + return "America/Vancouver"; + } else if (strcmp(region, "MB") == 0) { + return "America/Winnipeg"; + } else if (strcmp(region, "NB") == 0) { + return "America/Halifax"; + } else if (strcmp(region, "NL") == 0) { + return "America/St_Johns"; + } else if (strcmp(region, "NS") == 0) { + return "America/Halifax"; + } else if (strcmp(region, "NT") == 0) { + return "America/Yellowknife"; + } else if (strcmp(region, "NU") == 0) { + return "America/Rankin_Inlet"; + } else if (strcmp(region, "ON") == 0) { + return "America/Toronto"; + } else if (strcmp(region, "PE") == 0) { + return "America/Halifax"; + } else if (strcmp(region, "QC") == 0) { + return "America/Montreal"; + } else if (strcmp(region, "SK") == 0) { + return "America/Regina"; + } else if (strcmp(region, "YT") == 0) { + return "America/Whitehorse"; + } else { + return NULL; + } + } + if (strcmp(country, "CC") == 0) { + return "Indian/Cocos"; + } + if (strcmp(country, "CD") == 0) { + if (strcmp(region, "01") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "02") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "03") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "04") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "05") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "06") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "07") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "08") == 0) { + return "Africa/Kinshasa"; + } else if (strcmp(region, "09") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "10") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "11") == 0) { + return "Africa/Lubumbashi"; + } else if (strcmp(region, "12") == 0) { + return "Africa/Lubumbashi"; + } else { + return NULL; + } + } + if (strcmp(country, "CF") == 0) { + return "Africa/Bangui"; + } + if (strcmp(country, "CG") == 0) { + return "Africa/Brazzaville"; + } + if (strcmp(country, "CH") == 0) { + return "Europe/Zurich"; + } + if (strcmp(country, "CI") == 0) { + return "Africa/Abidjan"; + } + if (strcmp(country, "CK") == 0) { + return "Pacific/Rarotonga"; + } + if (strcmp(country, "CL") == 0) { + return "America/Santiago"; + } + if (strcmp(country, "CM") == 0) { + return "Africa/Lagos"; + } + if (strcmp(country, "CN") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Urumqi"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "18") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "19") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "21") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "22") == 0) { + return "Asia/Harbin"; + } else if (strcmp(region, "23") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "24") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "25") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "26") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "28") == 0) { + return "Asia/Shanghai"; + } else if (strcmp(region, "29") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "30") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "31") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "32") == 0) { + return "Asia/Chongqing"; + } else if (strcmp(region, "33") == 0) { + return "Asia/Chongqing"; + } else { + return NULL; + } + } + if (strcmp(country, "CO") == 0) { + return "America/Bogota"; + } + if (strcmp(country, "CR") == 0) { + return "America/Costa_Rica"; + } + if (strcmp(country, "CU") == 0) { + return "America/Havana"; + } + if (strcmp(country, "CV") == 0) { + return "Atlantic/Cape_Verde"; + } + if (strcmp(country, "CW") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "CX") == 0) { + return "Indian/Christmas"; + } + if (strcmp(country, "CY") == 0) { + return "Asia/Nicosia"; + } + if (strcmp(country, "CZ") == 0) { + return "Europe/Prague"; + } + if (strcmp(country, "DE") == 0) { + return "Europe/Berlin"; + } + if (strcmp(country, "DJ") == 0) { + return "Africa/Djibouti"; + } + if (strcmp(country, "DK") == 0) { + return "Europe/Copenhagen"; + } + if (strcmp(country, "DM") == 0) { + return "America/Dominica"; + } + if (strcmp(country, "DO") == 0) { + return "America/Santo_Domingo"; + } + if (strcmp(country, "DZ") == 0) { + return "Africa/Algiers"; + } + if (strcmp(country, "EC") == 0) { + if (strcmp(region, "01") == 0) { + return "Pacific/Galapagos"; + } else if (strcmp(region, "02") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "03") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "04") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "05") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "06") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "07") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "08") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "09") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "10") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "11") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "12") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "13") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "14") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "15") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "17") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "18") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "19") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "20") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "22") == 0) { + return "America/Guayaquil"; + } else if (strcmp(region, "24") == 0) { + return "America/Guayaquil"; + } else { + return NULL; + } + } + if (strcmp(country, "EE") == 0) { + return "Europe/Tallinn"; + } + if (strcmp(country, "EG") == 0) { + return "Africa/Cairo"; + } + if (strcmp(country, "EH") == 0) { + return "Africa/El_Aaiun"; + } + if (strcmp(country, "ER") == 0) { + return "Africa/Asmara"; + } + if (strcmp(country, "ES") == 0) { + if (strcmp(region, "07") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "27") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "29") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "31") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "32") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "34") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "39") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "51") == 0) { + return "Africa/Ceuta"; + } else if (strcmp(region, "52") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "53") == 0) { + return "Atlantic/Canary"; + } else if (strcmp(region, "54") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "55") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "56") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "57") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "58") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "59") == 0) { + return "Europe/Madrid"; + } else if (strcmp(region, "60") == 0) { + return "Europe/Madrid"; + } else { + return NULL; + } + } + if (strcmp(country, "ET") == 0) { + return "Africa/Addis_Ababa"; + } + if (strcmp(country, "FI") == 0) { + return "Europe/Helsinki"; + } + if (strcmp(country, "FJ") == 0) { + return "Pacific/Fiji"; + } + if (strcmp(country, "FK") == 0) { + return "Atlantic/Stanley"; + } + if (strcmp(country, "FM") == 0) { + return "Pacific/Pohnpei"; + } + if (strcmp(country, "FO") == 0) { + return "Atlantic/Faroe"; + } + if (strcmp(country, "FR") == 0) { + return "Europe/Paris"; + } + if (strcmp(country, "FX") == 0) { + return "Europe/Paris"; + } + if (strcmp(country, "GA") == 0) { + return "Africa/Libreville"; + } + if (strcmp(country, "GB") == 0) { + return "Europe/London"; + } + if (strcmp(country, "GD") == 0) { + return "America/Grenada"; + } + if (strcmp(country, "GE") == 0) { + return "Asia/Tbilisi"; + } + if (strcmp(country, "GF") == 0) { + return "America/Cayenne"; + } + if (strcmp(country, "GG") == 0) { + return "Europe/Guernsey"; + } + if (strcmp(country, "GH") == 0) { + return "Africa/Accra"; + } + if (strcmp(country, "GI") == 0) { + return "Europe/Gibraltar"; + } + if (strcmp(country, "GL") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Thule"; + } else if (strcmp(region, "02") == 0) { + return "America/Godthab"; + } else if (strcmp(region, "03") == 0) { + return "America/Godthab"; + } else { + return NULL; + } + } + if (strcmp(country, "GM") == 0) { + return "Africa/Banjul"; + } + if (strcmp(country, "GN") == 0) { + return "Africa/Conakry"; + } + if (strcmp(country, "GP") == 0) { + return "America/Guadeloupe"; + } + if (strcmp(country, "GQ") == 0) { + return "Africa/Malabo"; + } + if (strcmp(country, "GR") == 0) { + return "Europe/Athens"; + } + if (strcmp(country, "GS") == 0) { + return "Atlantic/South_Georgia"; + } + if (strcmp(country, "GT") == 0) { + return "America/Guatemala"; + } + if (strcmp(country, "GU") == 0) { + return "Pacific/Guam"; + } + if (strcmp(country, "GW") == 0) { + return "Africa/Bissau"; + } + if (strcmp(country, "GY") == 0) { + return "America/Guyana"; + } + if (strcmp(country, "HK") == 0) { + return "Asia/Hong_Kong"; + } + if (strcmp(country, "HN") == 0) { + return "America/Tegucigalpa"; + } + if (strcmp(country, "HR") == 0) { + return "Europe/Zagreb"; + } + if (strcmp(country, "HT") == 0) { + return "America/Port-au-Prince"; + } + if (strcmp(country, "HU") == 0) { + return "Europe/Budapest"; + } + if (strcmp(country, "ID") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "17") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "18") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "19") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "21") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "22") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "23") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "24") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "25") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "26") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "28") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "29") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "30") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "31") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "32") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "33") == 0) { + return "Asia/Jakarta"; + } else if (strcmp(region, "34") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "35") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "36") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "37") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "38") == 0) { + return "Asia/Makassar"; + } else if (strcmp(region, "39") == 0) { + return "Asia/Jayapura"; + } else if (strcmp(region, "40") == 0) { + return "Asia/Pontianak"; + } else if (strcmp(region, "41") == 0) { + return "Asia/Makassar"; + } else { + return NULL; + } + } + if (strcmp(country, "IE") == 0) { + return "Europe/Dublin"; + } + if (strcmp(country, "IL") == 0) { + return "Asia/Jerusalem"; + } + if (strcmp(country, "IM") == 0) { + return "Europe/Isle_of_Man"; + } + if (strcmp(country, "IN") == 0) { + return "Asia/Kolkata"; + } + if (strcmp(country, "IO") == 0) { + return "Indian/Chagos"; + } + if (strcmp(country, "IQ") == 0) { + return "Asia/Baghdad"; + } + if (strcmp(country, "IR") == 0) { + return "Asia/Tehran"; + } + if (strcmp(country, "IS") == 0) { + return "Atlantic/Reykjavik"; + } + if (strcmp(country, "IT") == 0) { + return "Europe/Rome"; + } + if (strcmp(country, "JE") == 0) { + return "Europe/Jersey"; + } + if (strcmp(country, "JM") == 0) { + return "America/Jamaica"; + } + if (strcmp(country, "JO") == 0) { + return "Asia/Amman"; + } + if (strcmp(country, "JP") == 0) { + return "Asia/Tokyo"; + } + if (strcmp(country, "KE") == 0) { + return "Africa/Nairobi"; + } + if (strcmp(country, "KG") == 0) { + return "Asia/Bishkek"; + } + if (strcmp(country, "KH") == 0) { + return "Asia/Phnom_Penh"; + } + if (strcmp(country, "KI") == 0) { + return "Pacific/Tarawa"; + } + if (strcmp(country, "KM") == 0) { + return "Indian/Comoro"; + } + if (strcmp(country, "KN") == 0) { + return "America/St_Kitts"; + } + if (strcmp(country, "KP") == 0) { + return "Asia/Pyongyang"; + } + if (strcmp(country, "KR") == 0) { + return "Asia/Seoul"; + } + if (strcmp(country, "KW") == 0) { + return "Asia/Kuwait"; + } + if (strcmp(country, "KY") == 0) { + return "America/Cayman"; + } + if (strcmp(country, "KZ") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Aqtobe"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Aqtau"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Oral"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Aqtau"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Aqtobe"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Qyzylorda"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Almaty"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Aqtobe"; + } else if (strcmp(region, "17") == 0) { + return "Asia/Almaty"; + } else { + return NULL; + } + } + if (strcmp(country, "LA") == 0) { + return "Asia/Vientiane"; + } + if (strcmp(country, "LB") == 0) { + return "Asia/Beirut"; + } + if (strcmp(country, "LC") == 0) { + return "America/St_Lucia"; + } + if (strcmp(country, "LI") == 0) { + return "Europe/Vaduz"; + } + if (strcmp(country, "LK") == 0) { + return "Asia/Colombo"; + } + if (strcmp(country, "LR") == 0) { + return "Africa/Monrovia"; + } + if (strcmp(country, "LS") == 0) { + return "Africa/Maseru"; + } + if (strcmp(country, "LT") == 0) { + return "Europe/Vilnius"; + } + if (strcmp(country, "LU") == 0) { + return "Europe/Luxembourg"; + } + if (strcmp(country, "LV") == 0) { + return "Europe/Riga"; + } + if (strcmp(country, "LY") == 0) { + return "Africa/Tripoli"; + } + if (strcmp(country, "MA") == 0) { + return "Africa/Casablanca"; + } + if (strcmp(country, "MC") == 0) { + return "Europe/Monaco"; + } + if (strcmp(country, "MD") == 0) { + return "Europe/Chisinau"; + } + if (strcmp(country, "ME") == 0) { + return "Europe/Podgorica"; + } + if (strcmp(country, "MF") == 0) { + return "America/Marigot"; + } + if (strcmp(country, "MG") == 0) { + return "Indian/Antananarivo"; + } + if (strcmp(country, "MH") == 0) { + return "Pacific/Kwajalein"; + } + if (strcmp(country, "MK") == 0) { + return "Europe/Skopje"; + } + if (strcmp(country, "ML") == 0) { + return "Africa/Bamako"; + } + if (strcmp(country, "MM") == 0) { + return "Asia/Rangoon"; + } + if (strcmp(country, "MN") == 0) { + if (strcmp(region, "06") == 0) { + return "Asia/Choibalsan"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Ulaanbaatar"; + } else if (strcmp(region, "17") == 0) { + return "Asia/Choibalsan"; + } else if (strcmp(region, "19") == 0) { + return "Asia/Hovd"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Ulaanbaatar"; + } else if (strcmp(region, "21") == 0) { + return "Asia/Ulaanbaatar"; + } else if (strcmp(region, "25") == 0) { + return "Asia/Ulaanbaatar"; + } else { + return NULL; + } + } + if (strcmp(country, "MO") == 0) { + return "Asia/Macau"; + } + if (strcmp(country, "MP") == 0) { + return "Pacific/Saipan"; + } + if (strcmp(country, "MQ") == 0) { + return "America/Martinique"; + } + if (strcmp(country, "MR") == 0) { + return "Africa/Nouakchott"; + } + if (strcmp(country, "MS") == 0) { + return "America/Montserrat"; + } + if (strcmp(country, "MT") == 0) { + return "Europe/Malta"; + } + if (strcmp(country, "MU") == 0) { + return "Indian/Mauritius"; + } + if (strcmp(country, "MV") == 0) { + return "Indian/Maldives"; + } + if (strcmp(country, "MW") == 0) { + return "Africa/Blantyre"; + } + if (strcmp(country, "MX") == 0) { + if (strcmp(region, "01") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "02") == 0) { + return "America/Tijuana"; + } else if (strcmp(region, "03") == 0) { + return "America/Hermosillo"; + } else if (strcmp(region, "04") == 0) { + return "America/Merida"; + } else if (strcmp(region, "05") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "06") == 0) { + return "America/Chihuahua"; + } else if (strcmp(region, "07") == 0) { + return "America/Monterrey"; + } else if (strcmp(region, "08") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "09") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "10") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "11") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "12") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "13") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "14") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "15") == 0) { + return "America/Chihuahua"; + } else if (strcmp(region, "16") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "17") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "18") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "19") == 0) { + return "America/Monterrey"; + } else if (strcmp(region, "20") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "21") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "22") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "23") == 0) { + return "America/Cancun"; + } else if (strcmp(region, "24") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "25") == 0) { + return "America/Mazatlan"; + } else if (strcmp(region, "26") == 0) { + return "America/Hermosillo"; + } else if (strcmp(region, "27") == 0) { + return "America/Merida"; + } else if (strcmp(region, "28") == 0) { + return "America/Monterrey"; + } else if (strcmp(region, "29") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "30") == 0) { + return "America/Mexico_City"; + } else if (strcmp(region, "31") == 0) { + return "America/Merida"; + } else if (strcmp(region, "32") == 0) { + return "America/Monterrey"; + } else { + return NULL; + } + } + if (strcmp(country, "MY") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Kuching"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Kuala_Lumpur"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Kuching"; + } else if (strcmp(region, "16") == 0) { + return "Asia/Kuching"; + } else { + return NULL; + } + } + if (strcmp(country, "MZ") == 0) { + return "Africa/Maputo"; + } + if (strcmp(country, "NA") == 0) { + return "Africa/Windhoek"; + } + if (strcmp(country, "NC") == 0) { + return "Pacific/Noumea"; + } + if (strcmp(country, "NE") == 0) { + return "Africa/Niamey"; + } + if (strcmp(country, "NF") == 0) { + return "Pacific/Norfolk"; + } + if (strcmp(country, "NG") == 0) { + return "Africa/Lagos"; + } + if (strcmp(country, "NI") == 0) { + return "America/Managua"; + } + if (strcmp(country, "NL") == 0) { + return "Europe/Amsterdam"; + } + if (strcmp(country, "NO") == 0) { + return "Europe/Oslo"; + } + if (strcmp(country, "NP") == 0) { + return "Asia/Kathmandu"; + } + if (strcmp(country, "NR") == 0) { + return "Pacific/Nauru"; + } + if (strcmp(country, "NU") == 0) { + return "Pacific/Niue"; + } + if (strcmp(country, "NZ") == 0) { + if (strcmp(region, "85") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "E7") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "E8") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "E9") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F1") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F2") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F3") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F4") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F5") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F6") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F7") == 0) { + return "Pacific/Chatham"; + } else if (strcmp(region, "F8") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "F9") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "G1") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "G2") == 0) { + return "Pacific/Auckland"; + } else if (strcmp(region, "G3") == 0) { + return "Pacific/Auckland"; + } else { + return NULL; + } + } + if (strcmp(country, "OM") == 0) { + return "Asia/Muscat"; + } + if (strcmp(country, "PA") == 0) { + return "America/Panama"; + } + if (strcmp(country, "PE") == 0) { + return "America/Lima"; + } + if (strcmp(country, "PF") == 0) { + return "Pacific/Marquesas"; + } + if (strcmp(country, "PG") == 0) { + return "Pacific/Port_Moresby"; + } + if (strcmp(country, "PH") == 0) { + return "Asia/Manila"; + } + if (strcmp(country, "PK") == 0) { + return "Asia/Karachi"; + } + if (strcmp(country, "PL") == 0) { + return "Europe/Warsaw"; + } + if (strcmp(country, "PM") == 0) { + return "America/Miquelon"; + } + if (strcmp(country, "PN") == 0) { + return "Pacific/Pitcairn"; + } + if (strcmp(country, "PR") == 0) { + return "America/Puerto_Rico"; + } + if (strcmp(country, "PS") == 0) { + return "Asia/Gaza"; + } + if (strcmp(country, "PT") == 0) { + if (strcmp(region, "02") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "03") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "04") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "05") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "06") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "07") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "08") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "09") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "10") == 0) { + return "Atlantic/Madeira"; + } else if (strcmp(region, "11") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "13") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "14") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "16") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "17") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "18") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "19") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "20") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "21") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "22") == 0) { + return "Europe/Lisbon"; + } else if (strcmp(region, "23") == 0) { + return "Atlantic/Azores"; + } else { + return NULL; + } + } + if (strcmp(country, "PW") == 0) { + return "Pacific/Palau"; + } + if (strcmp(country, "PY") == 0) { + return "America/Asuncion"; + } + if (strcmp(country, "QA") == 0) { + return "Asia/Qatar"; + } + if (strcmp(country, "RE") == 0) { + return "Indian/Reunion"; + } + if (strcmp(country, "RO") == 0) { + return "Europe/Bucharest"; + } + if (strcmp(country, "RS") == 0) { + return "Europe/Belgrade"; + } + if (strcmp(country, "RU") == 0) { + if (strcmp(region, "01") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Novokuznetsk"; + } else if (strcmp(region, "04") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "06") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "07") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "08") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "09") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "10") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "11") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "12") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "15") == 0) { + return "Asia/Anadyr"; + } else if (strcmp(region, "16") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "17") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "18") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "20") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "21") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "22") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "23") == 0) { + return "Europe/Kaliningrad"; + } else if (strcmp(region, "24") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "25") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "26") == 0) { + return "Asia/Kamchatka"; + } else if (strcmp(region, "27") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "28") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "29") == 0) { + return "Asia/Novokuznetsk"; + } else if (strcmp(region, "30") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "31") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "32") == 0) { + return "Asia/Omsk"; + } else if (strcmp(region, "33") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "34") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "35") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "36") == 0) { + return "Asia/Anadyr"; + } else if (strcmp(region, "37") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "38") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "39") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "40") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "41") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "42") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "43") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "44") == 0) { + return "Asia/Magadan"; + } else if (strcmp(region, "45") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "46") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "47") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "48") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "49") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "50") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "51") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "52") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "53") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "54") == 0) { + return "Asia/Omsk"; + } else if (strcmp(region, "55") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "56") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "57") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "58") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "59") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "60") == 0) { + return "Europe/Kaliningrad"; + } else if (strcmp(region, "61") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "62") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "63") == 0) { + return "Asia/Yakutsk"; + } else if (strcmp(region, "64") == 0) { + return "Asia/Sakhalin"; + } else if (strcmp(region, "65") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "66") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "67") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "68") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "69") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "70") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "71") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "72") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "73") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "74") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "75") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "76") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "77") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "78") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "79") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "80") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "81") == 0) { + return "Europe/Samara"; + } else if (strcmp(region, "82") == 0) { + return "Asia/Irkutsk"; + } else if (strcmp(region, "83") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "84") == 0) { + return "Europe/Volgograd"; + } else if (strcmp(region, "85") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "86") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "87") == 0) { + return "Asia/Novosibirsk"; + } else if (strcmp(region, "88") == 0) { + return "Europe/Moscow"; + } else if (strcmp(region, "89") == 0) { + return "Asia/Vladivostok"; + } else if (strcmp(region, "90") == 0) { + return "Asia/Yekaterinburg"; + } else if (strcmp(region, "91") == 0) { + return "Asia/Krasnoyarsk"; + } else if (strcmp(region, "92") == 0) { + return "Asia/Anadyr"; + } else if (strcmp(region, "93") == 0) { + return "Asia/Irkutsk"; + } else { + return NULL; + } + } + if (strcmp(country, "RW") == 0) { + return "Africa/Kigali"; + } + if (strcmp(country, "SA") == 0) { + return "Asia/Riyadh"; + } + if (strcmp(country, "SB") == 0) { + return "Pacific/Guadalcanal"; + } + if (strcmp(country, "SC") == 0) { + return "Indian/Mahe"; + } + if (strcmp(country, "SD") == 0) { + return "Africa/Khartoum"; + } + if (strcmp(country, "SE") == 0) { + return "Europe/Stockholm"; + } + if (strcmp(country, "SG") == 0) { + return "Asia/Singapore"; + } + if (strcmp(country, "SH") == 0) { + return "Atlantic/St_Helena"; + } + if (strcmp(country, "SI") == 0) { + return "Europe/Ljubljana"; + } + if (strcmp(country, "SJ") == 0) { + return "Arctic/Longyearbyen"; + } + if (strcmp(country, "SK") == 0) { + return "Europe/Bratislava"; + } + if (strcmp(country, "SL") == 0) { + return "Africa/Freetown"; + } + if (strcmp(country, "SM") == 0) { + return "Europe/San_Marino"; + } + if (strcmp(country, "SN") == 0) { + return "Africa/Dakar"; + } + if (strcmp(country, "SO") == 0) { + return "Africa/Mogadishu"; + } + if (strcmp(country, "SR") == 0) { + return "America/Paramaribo"; + } + if (strcmp(country, "SS") == 0) { + return "Africa/Juba"; + } + if (strcmp(country, "ST") == 0) { + return "Africa/Sao_Tome"; + } + if (strcmp(country, "SV") == 0) { + return "America/El_Salvador"; + } + if (strcmp(country, "SX") == 0) { + return "America/Curacao"; + } + if (strcmp(country, "SY") == 0) { + return "Asia/Damascus"; + } + if (strcmp(country, "SZ") == 0) { + return "Africa/Mbabane"; + } + if (strcmp(country, "TC") == 0) { + return "America/Grand_Turk"; + } + if (strcmp(country, "TD") == 0) { + return "Africa/Ndjamena"; + } + if (strcmp(country, "TF") == 0) { + return "Indian/Kerguelen"; + } + if (strcmp(country, "TG") == 0) { + return "Africa/Lome"; + } + if (strcmp(country, "TH") == 0) { + return "Asia/Bangkok"; + } + if (strcmp(country, "TJ") == 0) { + return "Asia/Dushanbe"; + } + if (strcmp(country, "TK") == 0) { + return "Pacific/Fakaofo"; + } + if (strcmp(country, "TL") == 0) { + return "Asia/Dili"; + } + if (strcmp(country, "TM") == 0) { + return "Asia/Ashgabat"; + } + if (strcmp(country, "TN") == 0) { + return "Africa/Tunis"; + } + if (strcmp(country, "TO") == 0) { + return "Pacific/Tongatapu"; + } + if (strcmp(country, "TR") == 0) { + return "Asia/Istanbul"; + } + if (strcmp(country, "TT") == 0) { + return "America/Port_of_Spain"; + } + if (strcmp(country, "TV") == 0) { + return "Pacific/Funafuti"; + } + if (strcmp(country, "TW") == 0) { + return "Asia/Taipei"; + } + if (strcmp(country, "TZ") == 0) { + return "Africa/Dar_es_Salaam"; + } + if (strcmp(country, "UA") == 0) { + if (strcmp(region, "01") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "02") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "03") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "04") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "05") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "06") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "07") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "08") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "09") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "10") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "11") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "12") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "13") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "14") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "15") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "16") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "17") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "18") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "19") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "20") == 0) { + return "Europe/Simferopol"; + } else if (strcmp(region, "21") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "22") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "23") == 0) { + return "Europe/Kiev"; + } else if (strcmp(region, "24") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "25") == 0) { + return "Europe/Uzhgorod"; + } else if (strcmp(region, "26") == 0) { + return "Europe/Zaporozhye"; + } else if (strcmp(region, "27") == 0) { + return "Europe/Kiev"; + } else { + return NULL; + } + } + if (strcmp(country, "UG") == 0) { + return "Africa/Kampala"; + } + if (strcmp(country, "UM") == 0) { + return "Pacific/Wake"; + } + if (strcmp(country, "US") == 0) { + if (strcmp(region, "AK") == 0) { + return "America/Anchorage"; + } else if (strcmp(region, "AL") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "AR") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "AZ") == 0) { + return "America/Phoenix"; + } else if (strcmp(region, "CA") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "CO") == 0) { + return "America/Denver"; + } else if (strcmp(region, "CT") == 0) { + return "America/New_York"; + } else if (strcmp(region, "DC") == 0) { + return "America/New_York"; + } else if (strcmp(region, "DE") == 0) { + return "America/New_York"; + } else if (strcmp(region, "FL") == 0) { + return "America/New_York"; + } else if (strcmp(region, "GA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "HI") == 0) { + return "Pacific/Honolulu"; + } else if (strcmp(region, "IA") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "ID") == 0) { + return "America/Denver"; + } else if (strcmp(region, "IL") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "IN") == 0) { + return "America/Indiana/Indianapolis"; + } else if (strcmp(region, "KS") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "KY") == 0) { + return "America/New_York"; + } else if (strcmp(region, "LA") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "MD") == 0) { + return "America/New_York"; + } else if (strcmp(region, "ME") == 0) { + return "America/New_York"; + } else if (strcmp(region, "MI") == 0) { + return "America/New_York"; + } else if (strcmp(region, "MN") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MO") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MS") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "MT") == 0) { + return "America/Denver"; + } else if (strcmp(region, "NC") == 0) { + return "America/New_York"; + } else if (strcmp(region, "ND") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "NE") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "NH") == 0) { + return "America/New_York"; + } else if (strcmp(region, "NJ") == 0) { + return "America/New_York"; + } else if (strcmp(region, "NM") == 0) { + return "America/Denver"; + } else if (strcmp(region, "NV") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "NY") == 0) { + return "America/New_York"; + } else if (strcmp(region, "OH") == 0) { + return "America/New_York"; + } else if (strcmp(region, "OK") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "OR") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "PA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "RI") == 0) { + return "America/New_York"; + } else if (strcmp(region, "SC") == 0) { + return "America/New_York"; + } else if (strcmp(region, "SD") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "TN") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "TX") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "UT") == 0) { + return "America/Denver"; + } else if (strcmp(region, "VA") == 0) { + return "America/New_York"; + } else if (strcmp(region, "VT") == 0) { + return "America/New_York"; + } else if (strcmp(region, "WA") == 0) { + return "America/Los_Angeles"; + } else if (strcmp(region, "WI") == 0) { + return "America/Chicago"; + } else if (strcmp(region, "WV") == 0) { + return "America/New_York"; + } else if (strcmp(region, "WY") == 0) { + return "America/Denver"; + } else { + return NULL; + } + } + if (strcmp(country, "UY") == 0) { + return "America/Montevideo"; + } + if (strcmp(country, "UZ") == 0) { + if (strcmp(region, "01") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "02") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "03") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "05") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "06") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "07") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "08") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "09") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "10") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "12") == 0) { + return "Asia/Samarkand"; + } else if (strcmp(region, "13") == 0) { + return "Asia/Tashkent"; + } else if (strcmp(region, "14") == 0) { + return "Asia/Tashkent"; + } else { + return NULL; + } + } + if (strcmp(country, "VA") == 0) { + return "Europe/Vatican"; + } + if (strcmp(country, "VC") == 0) { + return "America/St_Vincent"; + } + if (strcmp(country, "VE") == 0) { + return "America/Caracas"; + } + if (strcmp(country, "VG") == 0) { + return "America/Tortola"; + } + if (strcmp(country, "VI") == 0) { + return "America/St_Thomas"; + } + if (strcmp(country, "VN") == 0) { + return "Asia/Phnom_Penh"; + } + if (strcmp(country, "VU") == 0) { + return "Pacific/Efate"; + } + if (strcmp(country, "WF") == 0) { + return "Pacific/Wallis"; + } + if (strcmp(country, "WS") == 0) { + return "Pacific/Pago_Pago"; + } + if (strcmp(country, "YE") == 0) { + return "Asia/Aden"; + } + if (strcmp(country, "YT") == 0) { + return "Indian/Mayotte"; + } + if (strcmp(country, "YU") == 0) { + return "Europe/Belgrade"; + } + if (strcmp(country, "ZA") == 0) { + return "Africa/Johannesburg"; + } + if (strcmp(country, "ZM") == 0) { + return "Africa/Lusaka"; + } + if (strcmp(country, "ZW") == 0) { + return "Africa/Harare"; + } + return timezone; +} diff --git a/m4/.placeholder b/m4/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..1615d54 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,26 @@ +man_MANS = geoiplookup6.1 geoiplookup.1 + +EXTRA_DIST = geoiplookup6.1.in geoiplookup.1.in + + +edit = sed \ + -e 's|DATADIR|$(pkgdatadir)|g' \ + -e 's|CONF_DIR|$(sysconfdir)|g' + +geoiplookup.1 geoiplookup6.1: Makefile + rm -f $@ $@.tmp + $(edit) '$(srcdir)/$@.in' >$@.tmp + mv $@.tmp $@ + +geoiplookup.1: geoiplookup.1.in +geoiplookup6.1: geoiplookup6.1.in + +CLEANFILES = geoiplookup6.1 geoiplookup.1 + +LOOKUP_MAN = $(mandir)/man1/geoiplookup.1 +LOOKUP6_MAN = $(mandir)/man1/geoiplookup6.1 + +install-data-hook: + cat geoiplookup.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP_MAN) + cat geoiplookup6.1 | sed s,DATADIR,$(pkgdatadir), > $(DESTDIR)$(LOOKUP6_MAN) + diff --git a/man/geoiplookup.1.in b/man/geoiplookup.1.in new file mode 100644 index 0000000..010e58f --- /dev/null +++ b/man/geoiplookup.1.in @@ -0,0 +1,37 @@ +.TH GEOIPLOOKUP 1 "2 Jan 2007" +.UC 4 +.SH NAME +geoiplookup \- look up country using IP Address or hostname +.SH SYNOPSIS +geoiplookup [\-d directory] [\-f filename] [\-v] +.SH DESCRIPTION +geoiplookup uses the GeoIP library and database to find the Country +that an IP address or hostname originates from. +.PP +For example +.PP +.I geoiplookup 80.60.233.195 +.PP +will find the Country that 80.60.233.195 originates from, in the following format: +.PP +.I NL, Netherlands +.PP +.SH OPTIONS +.IP "\-f" +Specify a custom path to a single GeoIP datafile. +.IP "\-d" +Specify a custom directory containing GeoIP datafile(s). By default geoiplookup looks in DATADIR +.IP "\-v" +Lists the date and build number for the GeoIP datafile(s). +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to +.SH COPYRIGHT +Copyright (C) 2016 MaxMind, Inc. + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +geoipupdate(1), nslookup(1). diff --git a/man/geoiplookup6.1.in b/man/geoiplookup6.1.in new file mode 100644 index 0000000..8816e47 --- /dev/null +++ b/man/geoiplookup6.1.in @@ -0,0 +1,42 @@ +.TH GEOIPLOOKUP6 1 "28 Oct 2008" +.UC 4 +.SH NAME +geouplookup6 \- look up country using IP Address or hostname +.SH SYNOPSIS +geouplookup6 [\-d directory] [\-f filename] [\-v] +.SH DESCRIPTION +geouplookup6 uses the GeoIP library and database to find the Country +that an IP address or hostname originates from. You must install a database suitable for geoiplookup6. IE: GeoIPv6.dat +.PP +For example: +.PP +.I geouplookup6 2001:4860:0:1001::68 +.PP +.I geoiplookup6 ipv6.google.com +.PP +will find the Country that 2001:4860:0:1001::68 originates from, in the following format: +.PP +.I US, United States +.PP +.PP Please notice, that names must resolve to a ipv6 address. For example +.PP geoiplookup6 www.maxmind.com does not work, since there is no ipv6 +.PP DNS entry +.SH OPTIONS +.IP "\-f" +Specify a custom path to a single GeoIP datafile. +.IP "\-d" +Specify a custom directory containing GeoIP datafile(s). By default geouplookup6 looks in DATADIR +.IP "\-v" +Lists the date and build number for the GeoIP datafile(s). +.SH AUTHOR +Written by T.J. Mather +.SH "REPORTING BUGS" +Report bugs to +.SH COPYRIGHT +Copyright (C) 2008 MaxMind LLC + +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +geoipupdate(1), nslookup(1). diff --git a/regioncode/generate_regionName.pl b/regioncode/generate_regionName.pl new file mode 100755 index 0000000..7b75219 --- /dev/null +++ b/regioncode/generate_regionName.pl @@ -0,0 +1,176 @@ +#!/usr/bin/perl + +# Used to generate regionName.c +# usage: ./generate_regionName.pl > ../libGeoIP/regionName.c + +# Usually run update-region-codes.pl before generate_regionName.pl like +# +# ./update-region-codes.pl +# ./generate_regionName.pl > ../libGeoIP/regionName.c + +use strict; +use warnings; +use autodie; + +use Text::CSV_XS (); + +my $last_country_code = q{}; + +my @country_codes; +my @region_code2s; +my @region_names; + +sub init_variables () { + $last_country_code = q{}; +} + +sub parse_file { + + # http://geolite.maxmind.com/download/geoip/misc/region_codes.csv + open my $fh, '<:encoding(latin1)', 'region_codes.csv'; + <$fh>; + + my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 1 } ); + + while ( my $row = $csv->getline($fh) ) { + my ( $country_code, $region_code, $name ) = @{$row}; + my $region_code2; + if ( $country_code eq 'US' || $country_code eq 'CA' ) { + $region_code =~ /^[A-Z]{2}$/ or die "Wrong region code"; + $region_code2 + = ( ( ord( substr( $region_code, 0, 1 ) ) - 48 ) + * ( 65 + 26 - 48 ) ) + + ord( substr( $region_code, 1, 1 ) ) + - 48 + 100; + } + else { + if ( $region_code =~ /^\d\d$/ ) { + $region_code2 + = ( ord( substr( $region_code, 0, 1 ) ) - 48 ) * 10 + + ord( substr( $region_code, 1, 1 ) ) + - 48; + + } + elsif ( $region_code =~ /^[A-Z0-9]{2}$/ ) { + $region_code2 + = ( ( ord( substr( $region_code, 0, 1 ) ) - 48 ) + * ( 65 + 26 - 48 ) ) + + ord( substr( $region_code, 1, 1 ) ) + - 48 + 100; + } + else { + die "Region code seems wrong $region_code\n"; + } + } + die q{region name cannot contain a quote (")} if $name =~ /"/; + readcode( $country_code, $region_code, $region_code2, $name ); + } + close $fh; +} + +sub generate_region_name_functions { + + my $i = 0; + for my $country_code (@country_codes) { + + # function head + if ( $last_country_code ne $country_code ) { + if ( $last_country_code ne q{} ) { + print " default:\n return NULL;\n"; + print " }\n"; # switch end + print "}\n"; # function get_region_name_XX end + } + $last_country_code = $country_code; + + print "\nstatic const char * get_region_name_" . $country_code + . "(int region_code)\n"; # function begin + print "{\n"; + print " switch(region_code) {\n"; # switch end + } + + print " case " . $region_code2s[$i] . ":\n"; + print qq{ return "$region_names[$i]";\n}; + $i++; + } + + if ( $last_country_code ne "" ) { + print " default:\n return NULL;\n"; + print " }\n"; # switch end + print "}\n"; # function get_region_name_XX end + } +} + +# read code to collect to array +sub readcode { + my ( $country_code, $region_code, $region_code2, $name ) = @_; + + push( @country_codes, $country_code ); + push( @region_code2s, $region_code2 ); + push( @region_names, $name ); + +} + +sub generate_region_condition () { + + for my $country_code (@country_codes) { + if ( $last_country_code ne $country_code ) { + $last_country_code = $country_code; + + print " if (strcmp(country_code," . qq(") + . $last_country_code . qq(") + . ") == 0) {\n"; # if condition + print " return get_region_name_" + . $last_country_code + . "(region_code2);\n"; + print " }\n"; # function get_region_name_XX end + } + } +} + +# implementation of GeoIP_region_name_by_code +sub generate_api_function { + + print <<__C_CODE__; + +const char * GeoIP_region_name_by_code(const char * country_code,const char * region_code) { + int region_code2 = -1; + if (region_code == NULL) { return NULL; } + + if ( ((region_code[0] >= 48) && (region_code[0] < (48 + 10))) + && ((region_code[1] >= 48) && (region_code[1] < (48 + 10))) + ) { + + /* only numbers, that shortens the large switch statements */ + region_code2 = (region_code[0] - 48) * 10 + region_code[1] - 48; + } + + else if ( ( ((region_code[0] >= 65) && (region_code[0] < (65 + 26))) + || ((region_code[0] >= 48) && (region_code[0] < (48 + 10)))) + && ( ((region_code[1] >= 65) && (region_code[1] < (65 + 26))) + || ((region_code[1] >= 48) && (region_code[1] < (48 + 10)))) + ) { + + region_code2 = (region_code[0] - 48) * (65 + 26 - 48) + region_code[1] - 48 + 100; + } + + if (region_code2 == -1) {return NULL;} + +__C_CODE__ + + init_variables(); + generate_region_condition(); + + # function end + print " return NULL;\n"; + print "}\n"; + +} + +parse_file(); +init_variables(); +print qq{#include "GeoIP.h"\n}; +print "#include \n"; +print "#include \n\n"; +generate_region_name_functions(); +generate_api_function(); + diff --git a/regioncode/region_codes.csv b/regioncode/region_codes.csv new file mode 100644 index 0000000..aa62b98 --- /dev/null +++ b/regioncode/region_codes.csv @@ -0,0 +1,4108 @@ +AD,02,"Canillo" +AD,03,"Encamp" +AD,04,"La Massana" +AD,05,"Ordino" +AD,06,"Sant Julia de Loria" +AD,07,"Andorra la Vella" +AD,08,"Escaldes-Engordany" +AE,01,"Abu Dhabi" +AE,02,"Ajman" +AE,03,"Dubai" +AE,04,"Fujairah" +AE,05,"Ras Al Khaimah" +AE,06,"Sharjah" +AE,07,"Umm Al Quwain" +AF,01,"Badakhshan" +AF,02,"Badghis" +AF,03,"Baghlan" +AF,05,"Bamian" +AF,06,"Farah" +AF,07,"Faryab" +AF,08,"Ghazni" +AF,09,"Ghowr" +AF,10,"Helmand" +AF,11,"Herat" +AF,13,"Kabol" +AF,14,"Kapisa" +AF,17,"Lowgar" +AF,18,"Nangarhar" +AF,19,"Nimruz" +AF,23,"Kandahar" +AF,24,"Kondoz" +AF,26,"Takhar" +AF,27,"Vardak" +AF,28,"Zabol" +AF,29,"Paktika" +AF,30,"Balkh" +AF,31,"Jowzjan" +AF,32,"Samangan" +AF,33,"Sar-e Pol" +AF,34,"Konar" +AF,35,"Laghman" +AF,36,"Paktia" +AF,37,"Khowst" +AF,38,"Nurestan" +AF,39,"Oruzgan" +AF,40,"Parvan" +AF,41,"Daykondi" +AF,42,"Panjshir" +AG,01,"Barbuda" +AG,03,"Saint George" +AG,04,"Saint John" +AG,05,"Saint Mary" +AG,06,"Saint Paul" +AG,07,"Saint Peter" +AG,08,"Saint Philip" +AG,09,"Redonda" +AL,40,"Berat" +AL,41,"Diber" +AL,42,"Durres" +AL,43,"Elbasan" +AL,44,"Fier" +AL,45,"Gjirokaster" +AL,46,"Korce" +AL,47,"Kukes" +AL,48,"Lezhe" +AL,49,"Shkoder" +AL,50,"Tirane" +AL,51,"Vlore" +AM,01,"Aragatsotn" +AM,02,"Ararat" +AM,03,"Armavir" +AM,04,"Geghark'unik'" +AM,05,"Kotayk'" +AM,06,"Lorri" +AM,07,"Shirak" +AM,08,"Syunik'" +AM,09,"Tavush" +AM,10,"Vayots' Dzor" +AM,11,"Yerevan" +AO,01,"Benguela" +AO,02,"Bie" +AO,03,"Cabinda" +AO,04,"Cuando Cubango" +AO,05,"Cuanza Norte" +AO,06,"Cuanza Sul" +AO,07,"Cunene" +AO,08,"Huambo" +AO,09,"Huila" +AO,12,"Malanje" +AO,13,"Namibe" +AO,14,"Moxico" +AO,15,"Uige" +AO,16,"Zaire" +AO,17,"Lunda Norte" +AO,18,"Lunda Sul" +AO,19,"Bengo" +AO,20,"Luanda" +AR,01,"Buenos Aires" +AR,02,"Catamarca" +AR,03,"Chaco" +AR,04,"Chubut" +AR,05,"Cordoba" +AR,06,"Corrientes" +AR,07,"Distrito Federal" +AR,08,"Entre Rios" +AR,09,"Formosa" +AR,10,"Jujuy" +AR,11,"La Pampa" +AR,12,"La Rioja" +AR,13,"Mendoza" +AR,14,"Misiones" +AR,15,"Neuquen" +AR,16,"Rio Negro" +AR,17,"Salta" +AR,18,"San Juan" +AR,19,"San Luis" +AR,20,"Santa Cruz" +AR,21,"Santa Fe" +AR,22,"Santiago del Estero" +AR,23,"Tierra del Fuego" +AR,24,"Tucuman" +AT,01,"Burgenland" +AT,02,"Karnten" +AT,03,"Niederosterreich" +AT,04,"Oberosterreich" +AT,05,"Salzburg" +AT,06,"Steiermark" +AT,07,"Tirol" +AT,08,"Vorarlberg" +AT,09,"Wien" +AU,01,"Australian Capital Territory" +AU,02,"New South Wales" +AU,03,"Northern Territory" +AU,04,"Queensland" +AU,05,"South Australia" +AU,06,"Tasmania" +AU,07,"Victoria" +AU,08,"Western Australia" +AZ,01,"Abseron" +AZ,02,"Agcabadi" +AZ,03,"Agdam" +AZ,04,"Agdas" +AZ,05,"Agstafa" +AZ,06,"Agsu" +AZ,07,"Ali Bayramli" +AZ,08,"Astara" +AZ,09,"Baki" +AZ,10,"Balakan" +AZ,11,"Barda" +AZ,12,"Beylaqan" +AZ,13,"Bilasuvar" +AZ,14,"Cabrayil" +AZ,15,"Calilabad" +AZ,16,"Daskasan" +AZ,17,"Davaci" +AZ,18,"Fuzuli" +AZ,19,"Gadabay" +AZ,20,"Ganca" +AZ,21,"Goranboy" +AZ,22,"Goycay" +AZ,23,"Haciqabul" +AZ,24,"Imisli" +AZ,25,"Ismayilli" +AZ,26,"Kalbacar" +AZ,27,"Kurdamir" +AZ,28,"Lacin" +AZ,29,"Lankaran" +AZ,30,"Lankaran" +AZ,31,"Lerik" +AZ,32,"Masalli" +AZ,33,"Mingacevir" +AZ,34,"Naftalan" +AZ,35,"Naxcivan" +AZ,36,"Neftcala" +AZ,37,"Oguz" +AZ,38,"Qabala" +AZ,39,"Qax" +AZ,40,"Qazax" +AZ,41,"Qobustan" +AZ,42,"Quba" +AZ,43,"Qubadli" +AZ,44,"Qusar" +AZ,45,"Saatli" +AZ,46,"Sabirabad" +AZ,47,"Saki" +AZ,48,"Saki" +AZ,49,"Salyan" +AZ,50,"Samaxi" +AZ,51,"Samkir" +AZ,52,"Samux" +AZ,53,"Siyazan" +AZ,54,"Sumqayit" +AZ,55,"Susa" +AZ,56,"Susa" +AZ,57,"Tartar" +AZ,58,"Tovuz" +AZ,59,"Ucar" +AZ,60,"Xacmaz" +AZ,61,"Xankandi" +AZ,62,"Xanlar" +AZ,63,"Xizi" +AZ,64,"Xocali" +AZ,65,"Xocavand" +AZ,66,"Yardimli" +AZ,67,"Yevlax" +AZ,68,"Yevlax" +AZ,69,"Zangilan" +AZ,70,"Zaqatala" +AZ,71,"Zardab" +BA,01,"Federation of Bosnia and Herzegovina" +BA,03,"Brcko District" +BA,02,"Republika Srpska" +BB,01,"Christ Church" +BB,02,"Saint Andrew" +BB,03,"Saint George" +BB,04,"Saint James" +BB,05,"Saint John" +BB,06,"Saint Joseph" +BB,07,"Saint Lucy" +BB,08,"Saint Michael" +BB,09,"Saint Peter" +BB,10,"Saint Philip" +BB,11,"Saint Thomas" +BD,81,"Dhaka" +BD,82,"Khulna" +BD,83,"Rajshahi" +BD,84,"Chittagong" +BD,85,"Barisal" +BD,86,"Sylhet" +BD,87,"Rangpur" +BE,01,"Antwerpen" +BE,03,"Hainaut" +BE,04,"Liege" +BE,05,"Limburg" +BE,06,"Luxembourg" +BE,07,"Namur" +BE,08,"Oost-Vlaanderen" +BE,09,"West-Vlaanderen" +BE,10,"Brabant Wallon" +BE,11,"Brussels Hoofdstedelijk Gewest" +BE,12,"Vlaams-Brabant" +BE,13,"Flanders" +BE,14,"Wallonia" +BF,15,"Bam" +BF,19,"Boulkiemde" +BF,20,"Ganzourgou" +BF,21,"Gnagna" +BF,28,"Kouritenga" +BF,33,"Oudalan" +BF,34,"Passore" +BF,36,"Sanguie" +BF,40,"Soum" +BF,42,"Tapoa" +BF,44,"Zoundweogo" +BF,45,"Bale" +BF,46,"Banwa" +BF,47,"Bazega" +BF,48,"Bougouriba" +BF,49,"Boulgou" +BF,50,"Gourma" +BF,51,"Houet" +BF,52,"Ioba" +BF,53,"Kadiogo" +BF,54,"Kenedougou" +BF,55,"Komoe" +BF,56,"Komondjari" +BF,57,"Kompienga" +BF,58,"Kossi" +BF,59,"Koulpelogo" +BF,60,"Kourweogo" +BF,61,"Leraba" +BF,62,"Loroum" +BF,63,"Mouhoun" +BF,64,"Namentenga" +BF,65,"Naouri" +BF,66,"Nayala" +BF,67,"Noumbiel" +BF,68,"Oubritenga" +BF,69,"Poni" +BF,70,"Sanmatenga" +BF,71,"Seno" +BF,72,"Sissili" +BF,73,"Sourou" +BF,74,"Tuy" +BF,75,"Yagha" +BF,76,"Yatenga" +BF,77,"Ziro" +BF,78,"Zondoma" +BG,33,"Mikhaylovgrad" +BG,38,"Blagoevgrad" +BG,39,"Burgas" +BG,40,"Dobrich" +BG,41,"Gabrovo" +BG,42,"Grad Sofiya" +BG,43,"Khaskovo" +BG,44,"Kurdzhali" +BG,45,"Kyustendil" +BG,46,"Lovech" +BG,47,"Montana" +BG,48,"Pazardzhik" +BG,49,"Pernik" +BG,50,"Pleven" +BG,51,"Plovdiv" +BG,52,"Razgrad" +BG,53,"Ruse" +BG,54,"Shumen" +BG,55,"Silistra" +BG,56,"Sliven" +BG,57,"Smolyan" +BG,58,"Sofiya" +BG,59,"Stara Zagora" +BG,60,"Turgovishte" +BG,61,"Varna" +BG,62,"Veliko Turnovo" +BG,63,"Vidin" +BG,64,"Vratsa" +BG,65,"Yambol" +BH,01,"Al Hadd" +BH,02,"Al Manamah" +BH,05,"Jidd Hafs" +BH,06,"Sitrah" +BH,08,"Al Mintaqah al Gharbiyah" +BH,09,"Mintaqat Juzur Hawar" +BH,10,"Al Mintaqah ash Shamaliyah" +BH,11,"Al Mintaqah al Wusta" +BH,12,"Madinat" +BH,13,"Ar Rifa" +BH,14,"Madinat Hamad" +BH,15,"Al Muharraq" +BH,16,"Al Asimah" +BH,17,"Al Janubiyah" +BH,18,"Ash Shamaliyah" +BH,19,"Al Wusta" +BI,02,"Bujumbura" +BI,09,"Bubanza" +BI,10,"Bururi" +BI,11,"Cankuzo" +BI,12,"Cibitoke" +BI,13,"Gitega" +BI,14,"Karuzi" +BI,15,"Kayanza" +BI,16,"Kirundo" +BI,17,"Makamba" +BI,18,"Muyinga" +BI,19,"Ngozi" +BI,20,"Rutana" +BI,21,"Ruyigi" +BI,22,"Muramvya" +BI,23,"Mwaro" +BJ,07,"Alibori" +BJ,08,"Atakora" +BJ,09,"Atlanyique" +BJ,10,"Borgou" +BJ,11,"Collines" +BJ,12,"Kouffo" +BJ,13,"Donga" +BJ,14,"Littoral" +BJ,15,"Mono" +BJ,16,"Oueme" +BJ,17,"Plateau" +BJ,18,"Zou" +BM,01,"Devonshire" +BM,02,"Hamilton" +BM,03,"Hamilton" +BM,04,"Paget" +BM,05,"Pembroke" +BM,06,"Saint George" +BM,07,"Saint George's" +BM,08,"Sandys" +BM,09,"Smiths" +BM,10,"Southampton" +BM,11,"Warwick" +BN,07,"Alibori" +BN,08,"Belait" +BN,09,"Brunei and Muara" +BN,10,"Temburong" +BN,11,"Collines" +BN,12,"Kouffo" +BN,13,"Donga" +BN,14,"Littoral" +BN,15,"Tutong" +BN,16,"Oueme" +BN,17,"Plateau" +BN,18,"Zou" +BO,01,"Chuquisaca" +BO,02,"Cochabamba" +BO,03,"El Beni" +BO,04,"La Paz" +BO,05,"Oruro" +BO,06,"Pando" +BO,07,"Potosi" +BO,08,"Santa Cruz" +BO,09,"Tarija" +BR,01,"Acre" +BR,02,"Alagoas" +BR,03,"Amapa" +BR,04,"Amazonas" +BR,05,"Bahia" +BR,06,"Ceara" +BR,07,"Distrito Federal" +BR,08,"Espirito Santo" +BR,11,"Mato Grosso do Sul" +BR,13,"Maranhao" +BR,14,"Mato Grosso" +BR,15,"Minas Gerais" +BR,16,"Para" +BR,17,"Paraiba" +BR,18,"Parana" +BR,20,"Piaui" +BR,21,"Rio de Janeiro" +BR,22,"Rio Grande do Norte" +BR,23,"Rio Grande do Sul" +BR,24,"Rondonia" +BR,25,"Roraima" +BR,26,"Santa Catarina" +BR,27,"Sao Paulo" +BR,28,"Sergipe" +BR,29,"Goias" +BR,30,"Pernambuco" +BR,31,"Tocantins" +BS,05,"Bimini" +BS,06,"Cat Island" +BS,10,"Exuma" +BS,13,"Inagua" +BS,15,"Long Island" +BS,16,"Mayaguana" +BS,18,"Ragged Island" +BS,22,"Harbour Island" +BS,23,"New Providence" +BS,24,"Acklins and Crooked Islands" +BS,25,"Freeport" +BS,26,"Fresh Creek" +BS,27,"Governor's Harbour" +BS,28,"Green Turtle Cay" +BS,29,"High Rock" +BS,30,"Kemps Bay" +BS,31,"Marsh Harbour" +BS,32,"Nichollstown and Berry Islands" +BS,33,"Rock Sound" +BS,34,"Sandy Point" +BS,35,"San Salvador and Rum Cay" +BT,05,"Bumthang" +BT,06,"Chhukha" +BT,07,"Chirang" +BT,08,"Daga" +BT,09,"Geylegphug" +BT,10,"Ha" +BT,11,"Lhuntshi" +BT,12,"Mongar" +BT,13,"Paro" +BT,14,"Pemagatsel" +BT,15,"Punakha" +BT,16,"Samchi" +BT,17,"Samdrup" +BT,18,"Shemgang" +BT,19,"Tashigang" +BT,20,"Thimphu" +BT,21,"Tongsa" +BT,22,"Wangdi Phodrang" +BW,01,"Central" +BW,03,"Ghanzi" +BW,04,"Kgalagadi" +BW,05,"Kgatleng" +BW,06,"Kweneng" +BW,08,"North-East" +BW,09,"South-East" +BW,10,"Southern" +BW,11,"North-West" +BY,01,"Brestskaya Voblasts'" +BY,02,"Homyel'skaya Voblasts'" +BY,03,"Hrodzyenskaya Voblasts'" +BY,04,"Minsk" +BY,05,"Minskaya Voblasts'" +BY,06,"Mahilyowskaya Voblasts'" +BY,07,"Vitsyebskaya Voblasts'" +BZ,01,"Belize" +BZ,02,"Cayo" +BZ,03,"Corozal" +BZ,04,"Orange Walk" +BZ,05,"Stann Creek" +BZ,06,"Toledo" +CA,AB,"Alberta" +CA,BC,"British Columbia" +CA,MB,"Manitoba" +CA,NB,"New Brunswick" +CA,NL,"Newfoundland" +CA,NS,"Nova Scotia" +CA,NT,"Northwest Territories" +CA,NU,"Nunavut" +CA,ON,"Ontario" +CA,PE,"Prince Edward Island" +CA,QC,"Quebec" +CA,SK,"Saskatchewan" +CA,YT,"Yukon Territory" +CD,01,"Bandundu" +CD,02,"Equateur" +CD,04,"Kasai-Oriental" +CD,05,"Katanga" +CD,06,"Kinshasa" +CD,08,"Bas-Congo" +CD,09,"Orientale" +CD,10,"Maniema" +CD,11,"Nord-Kivu" +CD,12,"Sud-Kivu" +CF,01,"Bamingui-Bangoran" +CF,02,"Basse-Kotto" +CF,03,"Haute-Kotto" +CF,04,"Mambere-Kadei" +CF,05,"Haut-Mbomou" +CF,06,"Kemo" +CF,07,"Lobaye" +CF,08,"Mbomou" +CF,09,"Nana-Mambere" +CF,11,"Ouaka" +CF,12,"Ouham" +CF,13,"Ouham-Pende" +CF,14,"Cuvette-Ouest" +CF,15,"Nana-Grebizi" +CF,16,"Sangha-Mbaere" +CF,17,"Ombella-Mpoko" +CF,18,"Bangui" +CG,01,"Bouenza" +CG,04,"Kouilou" +CG,05,"Lekoumou" +CG,06,"Likouala" +CG,07,"Niari" +CG,08,"Plateaux" +CG,10,"Sangha" +CG,11,"Pool" +CG,12,"Brazzaville" +CG,13,"Cuvette" +CG,14,"Cuvette-Ouest" +CH,01,"Aargau" +CH,02,"Ausser-Rhoden" +CH,03,"Basel-Landschaft" +CH,04,"Basel-Stadt" +CH,05,"Bern" +CH,06,"Fribourg" +CH,07,"Geneve" +CH,08,"Glarus" +CH,09,"Graubunden" +CH,10,"Inner-Rhoden" +CH,11,"Luzern" +CH,12,"Neuchatel" +CH,13,"Nidwalden" +CH,14,"Obwalden" +CH,15,"Sankt Gallen" +CH,16,"Schaffhausen" +CH,17,"Schwyz" +CH,18,"Solothurn" +CH,19,"Thurgau" +CH,20,"Ticino" +CH,21,"Uri" +CH,22,"Valais" +CH,23,"Vaud" +CH,24,"Zug" +CH,25,"Zurich" +CH,26,"Jura" +CI,74,"Agneby" +CI,75,"Bafing" +CI,76,"Bas-Sassandra" +CI,77,"Denguele" +CI,78,"Dix-Huit Montagnes" +CI,79,"Fromager" +CI,80,"Haut-Sassandra" +CI,81,"Lacs" +CI,82,"Lagunes" +CI,83,"Marahoue" +CI,84,"Moyen-Cavally" +CI,85,"Moyen-Comoe" +CI,86,"N'zi-Comoe" +CI,87,"Savanes" +CI,88,"Sud-Bandama" +CI,89,"Sud-Comoe" +CI,90,"Vallee du Bandama" +CI,91,"Worodougou" +CI,92,"Zanzan" +CL,01,"Valparaiso" +CL,02,"Aisen del General Carlos Ibanez del Campo" +CL,03,"Antofagasta" +CL,04,"Araucania" +CL,05,"Atacama" +CL,06,"Bio-Bio" +CL,07,"Coquimbo" +CL,08,"Libertador General Bernardo O'Higgins" +CL,09,"Los Lagos" +CL,10,"Magallanes y de la Antartica Chilena" +CL,11,"Maule" +CL,12,"Region Metropolitana" +CL,13,"Tarapaca" +CL,14,"Los Lagos" +CL,15,"Tarapaca" +CL,16,"Arica y Parinacota" +CL,17,"Los Rios" +CM,04,"Est" +CM,05,"Littoral" +CM,07,"Nord-Ouest" +CM,08,"Ouest" +CM,09,"Sud-Ouest" +CM,10,"Adamaoua" +CM,11,"Centre" +CM,12,"Extreme-Nord" +CM,13,"Nord" +CM,14,"Sud" +CN,01,"Anhui" +CN,02,"Zhejiang" +CN,03,"Jiangxi" +CN,04,"Jiangsu" +CN,05,"Jilin" +CN,06,"Qinghai" +CN,07,"Fujian" +CN,08,"Heilongjiang" +CN,09,"Henan" +CN,10,"Hebei" +CN,11,"Hunan" +CN,12,"Hubei" +CN,13,"Xinjiang" +CN,14,"Xizang" +CN,15,"Gansu" +CN,16,"Guangxi" +CN,18,"Guizhou" +CN,19,"Liaoning" +CN,20,"Nei Mongol" +CN,21,"Ningxia" +CN,22,"Beijing" +CN,23,"Shanghai" +CN,24,"Shanxi" +CN,25,"Shandong" +CN,26,"Shaanxi" +CN,28,"Tianjin" +CN,29,"Yunnan" +CN,30,"Guangdong" +CN,31,"Hainan" +CN,32,"Sichuan" +CN,33,"Chongqing" +CO,01,"Amazonas" +CO,02,"Antioquia" +CO,03,"Arauca" +CO,04,"Atlantico" +CO,08,"Caqueta" +CO,09,"Cauca" +CO,10,"Cesar" +CO,11,"Choco" +CO,12,"Cordoba" +CO,14,"Guaviare" +CO,15,"Guainia" +CO,16,"Huila" +CO,17,"La Guajira" +CO,19,"Meta" +CO,20,"Narino" +CO,21,"Norte de Santander" +CO,22,"Putumayo" +CO,23,"Quindio" +CO,24,"Risaralda" +CO,25,"San Andres y Providencia" +CO,26,"Santander" +CO,27,"Sucre" +CO,28,"Tolima" +CO,29,"Valle del Cauca" +CO,30,"Vaupes" +CO,31,"Vichada" +CO,32,"Casanare" +CO,33,"Cundinamarca" +CO,34,"Distrito Especial" +CO,35,"Bolivar" +CO,36,"Boyaca" +CO,37,"Caldas" +CO,38,"Magdalena" +CR,01,"Alajuela" +CR,02,"Cartago" +CR,03,"Guanacaste" +CR,04,"Heredia" +CR,06,"Limon" +CR,07,"Puntarenas" +CR,08,"San Jose" +CU,01,"Pinar del Rio" +CU,02,"Ciudad de la Habana" +CU,03,"Matanzas" +CU,04,"Isla de la Juventud" +CU,05,"Camaguey" +CU,07,"Ciego de Avila" +CU,08,"Cienfuegos" +CU,09,"Granma" +CU,10,"Guantanamo" +CU,11,"La Habana" +CU,12,"Holguin" +CU,13,"Las Tunas" +CU,14,"Sancti Spiritus" +CU,15,"Santiago de Cuba" +CU,16,"Villa Clara" +CV,01,"Boa Vista" +CV,02,"Brava" +CV,04,"Maio" +CV,05,"Paul" +CV,07,"Ribeira Grande" +CV,08,"Sal" +CV,10,"Sao Nicolau" +CV,11,"Sao Vicente" +CV,13,"Mosteiros" +CV,14,"Praia" +CV,15,"Santa Catarina" +CV,16,"Santa Cruz" +CV,17,"Sao Domingos" +CV,18,"Sao Filipe" +CV,19,"Sao Miguel" +CV,20,"Tarrafal" +CY,01,"Famagusta" +CY,02,"Kyrenia" +CY,03,"Larnaca" +CY,04,"Nicosia" +CY,05,"Limassol" +CY,06,"Paphos" +CZ,52,"Hlavni mesto Praha" +CZ,78,"Jihomoravsky kraj" +CZ,79,"Jihocesky kraj" +CZ,80,"Vysocina" +CZ,81,"Karlovarsky kraj" +CZ,82,"Kralovehradecky kraj" +CZ,83,"Liberecky kraj" +CZ,84,"Olomoucky kraj" +CZ,85,"Moravskoslezsky kraj" +CZ,86,"Pardubicky kraj" +CZ,87,"Plzensky kraj" +CZ,88,"Stredocesky kraj" +CZ,89,"Ustecky kraj" +CZ,90,"Zlinsky kraj" +DE,01,"Baden-Wurttemberg" +DE,02,"Bayern" +DE,03,"Bremen" +DE,04,"Hamburg" +DE,05,"Hessen" +DE,06,"Niedersachsen" +DE,07,"Nordrhein-Westfalen" +DE,08,"Rheinland-Pfalz" +DE,09,"Saarland" +DE,10,"Schleswig-Holstein" +DE,11,"Brandenburg" +DE,12,"Mecklenburg-Vorpommern" +DE,13,"Sachsen" +DE,14,"Sachsen-Anhalt" +DE,15,"Thuringen" +DE,16,"Berlin" +DJ,01,"Ali Sabieh" +DJ,04,"Obock" +DJ,05,"Tadjoura" +DJ,06,"Dikhil" +DJ,07,"Djibouti" +DJ,08,"Arta" +DK,17,"Hovedstaden" +DK,18,"Midtjylland" +DK,19,"Nordjylland" +DK,20,"Sjelland" +DK,21,"Syddanmark" +DM,02,"Saint Andrew" +DM,03,"Saint David" +DM,04,"Saint George" +DM,05,"Saint John" +DM,06,"Saint Joseph" +DM,07,"Saint Luke" +DM,08,"Saint Mark" +DM,09,"Saint Patrick" +DM,10,"Saint Paul" +DM,11,"Saint Peter" +DO,01,"Azua" +DO,02,"Baoruco" +DO,03,"Barahona" +DO,04,"Dajabon" +DO,05,"Distrito Nacional" +DO,06,"Duarte" +DO,08,"Espaillat" +DO,09,"Independencia" +DO,10,"La Altagracia" +DO,11,"Elias Pina" +DO,12,"La Romana" +DO,14,"Maria Trinidad Sanchez" +DO,15,"Monte Cristi" +DO,16,"Pedernales" +DO,17,"Peravia" +DO,18,"Puerto Plata" +DO,19,"Salcedo" +DO,20,"Samana" +DO,21,"Sanchez Ramirez" +DO,23,"San Juan" +DO,24,"San Pedro De Macoris" +DO,25,"Santiago" +DO,26,"Santiago Rodriguez" +DO,27,"Valverde" +DO,28,"El Seibo" +DO,29,"Hato Mayor" +DO,30,"La Vega" +DO,31,"Monsenor Nouel" +DO,32,"Monte Plata" +DO,33,"San Cristobal" +DO,34,"Distrito Nacional" +DO,35,"Peravia" +DO,36,"San Jose de Ocoa" +DO,37,"Santo Domingo" +DZ,01,"Alger" +DZ,03,"Batna" +DZ,04,"Constantine" +DZ,06,"Medea" +DZ,07,"Mostaganem" +DZ,09,"Oran" +DZ,10,"Saida" +DZ,12,"Setif" +DZ,13,"Tiaret" +DZ,14,"Tizi Ouzou" +DZ,15,"Tlemcen" +DZ,18,"Bejaia" +DZ,19,"Biskra" +DZ,20,"Blida" +DZ,21,"Bouira" +DZ,22,"Djelfa" +DZ,23,"Guelma" +DZ,24,"Jijel" +DZ,25,"Laghouat" +DZ,26,"Mascara" +DZ,27,"M'sila" +DZ,29,"Oum el Bouaghi" +DZ,30,"Sidi Bel Abbes" +DZ,31,"Skikda" +DZ,33,"Tebessa" +DZ,34,"Adrar" +DZ,35,"Ain Defla" +DZ,36,"Ain Temouchent" +DZ,37,"Annaba" +DZ,38,"Bechar" +DZ,39,"Bordj Bou Arreridj" +DZ,40,"Boumerdes" +DZ,41,"Chlef" +DZ,42,"El Bayadh" +DZ,43,"El Oued" +DZ,44,"El Tarf" +DZ,45,"Ghardaia" +DZ,46,"Illizi" +DZ,47,"Khenchela" +DZ,48,"Mila" +DZ,49,"Naama" +DZ,50,"Ouargla" +DZ,51,"Relizane" +DZ,52,"Souk Ahras" +DZ,53,"Tamanghasset" +DZ,54,"Tindouf" +DZ,55,"Tipaza" +DZ,56,"Tissemsilt" +EC,01,"Galapagos" +EC,02,"Azuay" +EC,03,"Bolivar" +EC,04,"Canar" +EC,05,"Carchi" +EC,06,"Chimborazo" +EC,07,"Cotopaxi" +EC,08,"El Oro" +EC,09,"Esmeraldas" +EC,10,"Guayas" +EC,11,"Imbabura" +EC,12,"Loja" +EC,13,"Los Rios" +EC,14,"Manabi" +EC,15,"Morona-Santiago" +EC,17,"Pastaza" +EC,18,"Pichincha" +EC,19,"Tungurahua" +EC,20,"Zamora-Chinchipe" +EC,22,"Sucumbios" +EC,23,"Napo" +EC,24,"Orellana" +EE,01,"Harjumaa" +EE,02,"Hiiumaa" +EE,03,"Ida-Virumaa" +EE,04,"Jarvamaa" +EE,05,"Jogevamaa" +EE,06,"Kohtla-Jarve" +EE,07,"Laanemaa" +EE,08,"Laane-Virumaa" +EE,09,"Narva" +EE,10,"Parnu" +EE,11,"Parnumaa" +EE,12,"Polvamaa" +EE,13,"Raplamaa" +EE,14,"Saaremaa" +EE,15,"Sillamae" +EE,16,"Tallinn" +EE,17,"Tartu" +EE,18,"Tartumaa" +EE,19,"Valgamaa" +EE,20,"Viljandimaa" +EE,21,"Vorumaa" +EG,01,"Ad Daqahliyah" +EG,02,"Al Bahr al Ahmar" +EG,03,"Al Buhayrah" +EG,04,"Al Fayyum" +EG,05,"Al Gharbiyah" +EG,06,"Al Iskandariyah" +EG,07,"Al Isma'iliyah" +EG,08,"Al Jizah" +EG,09,"Al Minufiyah" +EG,10,"Al Minya" +EG,11,"Al Qahirah" +EG,12,"Al Qalyubiyah" +EG,13,"Al Wadi al Jadid" +EG,14,"Ash Sharqiyah" +EG,15,"As Suways" +EG,16,"Aswan" +EG,17,"Asyut" +EG,18,"Bani Suwayf" +EG,19,"Bur Sa'id" +EG,20,"Dumyat" +EG,21,"Kafr ash Shaykh" +EG,22,"Matruh" +EG,23,"Qina" +EG,24,"Suhaj" +EG,26,"Janub Sina'" +EG,27,"Shamal Sina'" +EG,28,"Al Uqsur" +ER,01,"Anseba" +ER,02,"Debub" +ER,03,"Debubawi K'eyih Bahri" +ER,04,"Gash Barka" +ER,05,"Ma'akel" +ER,06,"Semenawi K'eyih Bahri" +ES,07,"Islas Baleares" +ES,27,"La Rioja" +ES,29,"Madrid" +ES,31,"Murcia" +ES,32,"Navarra" +ES,34,"Asturias" +ES,39,"Cantabria" +ES,51,"Andalucia" +ES,52,"Aragon" +ES,53,"Canarias" +ES,54,"Castilla-La Mancha" +ES,55,"Castilla y Leon" +ES,56,"Catalonia" +ES,57,"Extremadura" +ES,58,"Galicia" +ES,59,"Pais Vasco" +ES,60,"Comunidad Valenciana" +ET,44,"Adis Abeba" +ET,45,"Afar" +ET,46,"Amara" +ET,47,"Binshangul Gumuz" +ET,48,"Dire Dawa" +ET,49,"Gambela Hizboch" +ET,50,"Hareri Hizb" +ET,51,"Oromiya" +ET,52,"Sumale" +ET,53,"Tigray" +ET,54,"YeDebub Biheroch Bihereseboch na Hizboch" +FI,01,"Aland" +FI,06,"Lapland" +FI,08,"Oulu" +FI,13,"Southern Finland" +FI,14,"Eastern Finland" +FI,15,"Western Finland" +FJ,01,"Central" +FJ,02,"Eastern" +FJ,03,"Northern" +FJ,04,"Rotuma" +FJ,05,"Western" +FM,01,"Kosrae" +FM,02,"Pohnpei" +FM,03,"Chuuk" +FM,04,"Yap" +FR,97,"Aquitaine" +FR,98,"Auvergne" +FR,99,"Basse-Normandie" +FR,A1,"Bourgogne" +FR,A2,"Bretagne" +FR,A3,"Centre" +FR,A4,"Champagne-Ardenne" +FR,A5,"Corse" +FR,A6,"Franche-Comte" +FR,A7,"Haute-Normandie" +FR,A8,"Ile-de-France" +FR,A9,"Languedoc-Roussillon" +FR,B1,"Limousin" +FR,B2,"Lorraine" +FR,B3,"Midi-Pyrenees" +FR,B4,"Nord-Pas-de-Calais" +FR,B5,"Pays de la Loire" +FR,B6,"Picardie" +FR,B7,"Poitou-Charentes" +FR,B8,"Provence-Alpes-Cote d'Azur" +FR,B9,"Rhone-Alpes" +FR,C1,"Alsace" +GA,01,"Estuaire" +GA,02,"Haut-Ogooue" +GA,03,"Moyen-Ogooue" +GA,04,"Ngounie" +GA,05,"Nyanga" +GA,06,"Ogooue-Ivindo" +GA,07,"Ogooue-Lolo" +GA,08,"Ogooue-Maritime" +GA,09,"Woleu-Ntem" +GB,A1,"Barking and Dagenham" +GB,A2,"Barnet" +GB,A3,"Barnsley" +GB,A4,"Bath and North East Somerset" +GB,A5,"Bedfordshire" +GB,A6,"Bexley" +GB,A7,"Birmingham" +GB,A8,"Blackburn with Darwen" +GB,A9,"Blackpool" +GB,B1,"Bolton" +GB,B2,"Bournemouth" +GB,B3,"Bracknell Forest" +GB,B4,"Bradford" +GB,B5,"Brent" +GB,B6,"Brighton and Hove" +GB,B7,"Bristol, City of" +GB,B8,"Bromley" +GB,B9,"Buckinghamshire" +GB,C1,"Bury" +GB,C2,"Calderdale" +GB,C3,"Cambridgeshire" +GB,C4,"Camden" +GB,C5,"Cheshire" +GB,C6,"Cornwall" +GB,C7,"Coventry" +GB,C8,"Croydon" +GB,C9,"Cumbria" +GB,D1,"Darlington" +GB,D2,"Derby" +GB,D3,"Derbyshire" +GB,D4,"Devon" +GB,D5,"Doncaster" +GB,D6,"Dorset" +GB,D7,"Dudley" +GB,D8,"Durham" +GB,D9,"Ealing" +GB,E1,"East Riding of Yorkshire" +GB,E2,"East Sussex" +GB,E3,"Enfield" +GB,E4,"Essex" +GB,E5,"Gateshead" +GB,E6,"Gloucestershire" +GB,E7,"Greenwich" +GB,E8,"Hackney" +GB,E9,"Halton" +GB,F1,"Hammersmith and Fulham" +GB,F2,"Hampshire" +GB,F3,"Haringey" +GB,F4,"Harrow" +GB,F5,"Hartlepool" +GB,F6,"Havering" +GB,F7,"Herefordshire" +GB,F8,"Hertford" +GB,F9,"Hillingdon" +GB,G1,"Hounslow" +GB,G2,"Isle of Wight" +GB,G3,"Islington" +GB,G4,"Kensington and Chelsea" +GB,G5,"Kent" +GB,G6,"Kingston upon Hull, City of" +GB,G7,"Kingston upon Thames" +GB,G8,"Kirklees" +GB,G9,"Knowsley" +GB,H1,"Lambeth" +GB,H2,"Lancashire" +GB,H3,"Leeds" +GB,H4,"Leicester" +GB,H5,"Leicestershire" +GB,H6,"Lewisham" +GB,H7,"Lincolnshire" +GB,H8,"Liverpool" +GB,H9,"London, City of" +GB,I1,"Luton" +GB,I2,"Manchester" +GB,I3,"Medway" +GB,I4,"Merton" +GB,I5,"Middlesbrough" +GB,I6,"Milton Keynes" +GB,I7,"Newcastle upon Tyne" +GB,I8,"Newham" +GB,I9,"Norfolk" +GB,J1,"Northamptonshire" +GB,J2,"North East Lincolnshire" +GB,J3,"North Lincolnshire" +GB,J4,"North Somerset" +GB,J5,"North Tyneside" +GB,J6,"Northumberland" +GB,J7,"North Yorkshire" +GB,J8,"Nottingham" +GB,J9,"Nottinghamshire" +GB,K1,"Oldham" +GB,K2,"Oxfordshire" +GB,K3,"Peterborough" +GB,K4,"Plymouth" +GB,K5,"Poole" +GB,K6,"Portsmouth" +GB,K7,"Reading" +GB,K8,"Redbridge" +GB,K9,"Redcar and Cleveland" +GB,L1,"Richmond upon Thames" +GB,L2,"Rochdale" +GB,L3,"Rotherham" +GB,L4,"Rutland" +GB,L5,"Salford" +GB,L6,"Shropshire" +GB,L7,"Sandwell" +GB,L8,"Sefton" +GB,L9,"Sheffield" +GB,M1,"Slough" +GB,M2,"Solihull" +GB,M3,"Somerset" +GB,M4,"Southampton" +GB,M5,"Southend-on-Sea" +GB,M6,"South Gloucestershire" +GB,M7,"South Tyneside" +GB,M8,"Southwark" +GB,M9,"Staffordshire" +GB,N1,"St. Helens" +GB,N2,"Stockport" +GB,N3,"Stockton-on-Tees" +GB,N4,"Stoke-on-Trent" +GB,N5,"Suffolk" +GB,N6,"Sunderland" +GB,N7,"Surrey" +GB,N8,"Sutton" +GB,N9,"Swindon" +GB,O1,"Tameside" +GB,O2,"Telford and Wrekin" +GB,O3,"Thurrock" +GB,O4,"Torbay" +GB,O5,"Tower Hamlets" +GB,O6,"Trafford" +GB,O7,"Wakefield" +GB,O8,"Walsall" +GB,O9,"Waltham Forest" +GB,P1,"Wandsworth" +GB,P2,"Warrington" +GB,P3,"Warwickshire" +GB,P4,"West Berkshire" +GB,P5,"Westminster" +GB,P6,"West Sussex" +GB,P7,"Wigan" +GB,P8,"Wiltshire" +GB,P9,"Windsor and Maidenhead" +GB,Q1,"Wirral" +GB,Q2,"Wokingham" +GB,Q3,"Wolverhampton" +GB,Q4,"Worcestershire" +GB,Q5,"York" +GB,Q6,"Antrim" +GB,Q7,"Ards" +GB,Q8,"Armagh" +GB,Q9,"Ballymena" +GB,R1,"Ballymoney" +GB,R2,"Banbridge" +GB,R3,"Belfast" +GB,R4,"Carrickfergus" +GB,R5,"Castlereagh" +GB,R6,"Coleraine" +GB,R7,"Cookstown" +GB,R8,"Craigavon" +GB,R9,"Down" +GB,S1,"Dungannon" +GB,S2,"Fermanagh" +GB,S3,"Larne" +GB,S4,"Limavady" +GB,S5,"Lisburn" +GB,S6,"Derry" +GB,S7,"Magherafelt" +GB,S8,"Moyle" +GB,S9,"Newry and Mourne" +GB,T1,"Newtownabbey" +GB,T2,"North Down" +GB,T3,"Omagh" +GB,T4,"Strabane" +GB,T5,"Aberdeen City" +GB,T6,"Aberdeenshire" +GB,T7,"Angus" +GB,T8,"Argyll and Bute" +GB,T9,"Scottish Borders, The" +GB,U1,"Clackmannanshire" +GB,U2,"Dumfries and Galloway" +GB,U3,"Dundee City" +GB,U4,"East Ayrshire" +GB,U5,"East Dunbartonshire" +GB,U6,"East Lothian" +GB,U7,"East Renfrewshire" +GB,U8,"Edinburgh, City of" +GB,U9,"Falkirk" +GB,V1,"Fife" +GB,V2,"Glasgow City" +GB,V3,"Highland" +GB,V4,"Inverclyde" +GB,V5,"Midlothian" +GB,V6,"Moray" +GB,V7,"North Ayrshire" +GB,V8,"North Lanarkshire" +GB,V9,"Orkney" +GB,W1,"Perth and Kinross" +GB,W2,"Renfrewshire" +GB,W3,"Shetland Islands" +GB,W4,"South Ayrshire" +GB,W5,"South Lanarkshire" +GB,W6,"Stirling" +GB,W7,"West Dunbartonshire" +GB,W8,"Eilean Siar" +GB,W9,"West Lothian" +GB,X1,"Isle of Anglesey" +GB,X2,"Blaenau Gwent" +GB,X3,"Bridgend" +GB,X4,"Caerphilly" +GB,X5,"Cardiff" +GB,X6,"Ceredigion" +GB,X7,"Carmarthenshire" +GB,X8,"Conwy" +GB,X9,"Denbighshire" +GB,Y1,"Flintshire" +GB,Y2,"Gwynedd" +GB,Y3,"Merthyr Tydfil" +GB,Y4,"Monmouthshire" +GB,Y5,"Neath Port Talbot" +GB,Y6,"Newport" +GB,Y7,"Pembrokeshire" +GB,Y8,"Powys" +GB,Y9,"Rhondda Cynon Taff" +GB,Z1,"Swansea" +GB,Z2,"Torfaen" +GB,Z3,"Vale of Glamorgan, The" +GB,Z4,"Wrexham" +GB,Z5,"Bedfordshire" +GB,Z6,"Central Bedfordshire" +GB,Z7,"Cheshire East" +GB,Z8,"Cheshire West and Chester" +GB,Z9,"Isles of Scilly" +GD,01,"Saint Andrew" +GD,02,"Saint David" +GD,03,"Saint George" +GD,04,"Saint John" +GD,05,"Saint Mark" +GD,06,"Saint Patrick" +GE,01,"Abashis Raioni" +GE,02,"Abkhazia" +GE,03,"Adigenis Raioni" +GE,04,"Ajaria" +GE,05,"Akhalgoris Raioni" +GE,06,"Akhalk'alak'is Raioni" +GE,07,"Akhalts'ikhis Raioni" +GE,08,"Akhmetis Raioni" +GE,09,"Ambrolauris Raioni" +GE,10,"Aspindzis Raioni" +GE,11,"Baghdat'is Raioni" +GE,12,"Bolnisis Raioni" +GE,13,"Borjomis Raioni" +GE,14,"Chiat'ura" +GE,15,"Ch'khorotsqus Raioni" +GE,16,"Ch'okhatauris Raioni" +GE,17,"Dedop'listsqaros Raioni" +GE,18,"Dmanisis Raioni" +GE,19,"Dushet'is Raioni" +GE,20,"Gardabanis Raioni" +GE,21,"Gori" +GE,22,"Goris Raioni" +GE,23,"Gurjaanis Raioni" +GE,24,"Javis Raioni" +GE,25,"K'arelis Raioni" +GE,26,"Kaspis Raioni" +GE,27,"Kharagaulis Raioni" +GE,28,"Khashuris Raioni" +GE,29,"Khobis Raioni" +GE,30,"Khonis Raioni" +GE,31,"K'ut'aisi" +GE,32,"Lagodekhis Raioni" +GE,33,"Lanch'khut'is Raioni" +GE,34,"Lentekhis Raioni" +GE,35,"Marneulis Raioni" +GE,36,"Martvilis Raioni" +GE,37,"Mestiis Raioni" +GE,38,"Mts'khet'is Raioni" +GE,39,"Ninotsmindis Raioni" +GE,40,"Onis Raioni" +GE,41,"Ozurget'is Raioni" +GE,42,"P'ot'i" +GE,43,"Qazbegis Raioni" +GE,44,"Qvarlis Raioni" +GE,45,"Rust'avi" +GE,46,"Sach'kheris Raioni" +GE,47,"Sagarejos Raioni" +GE,48,"Samtrediis Raioni" +GE,49,"Senakis Raioni" +GE,50,"Sighnaghis Raioni" +GE,51,"T'bilisi" +GE,52,"T'elavis Raioni" +GE,53,"T'erjolis Raioni" +GE,54,"T'et'ritsqaros Raioni" +GE,55,"T'ianet'is Raioni" +GE,56,"Tqibuli" +GE,57,"Ts'ageris Raioni" +GE,58,"Tsalenjikhis Raioni" +GE,59,"Tsalkis Raioni" +GE,60,"Tsqaltubo" +GE,61,"Vanis Raioni" +GE,62,"Zestap'onis Raioni" +GE,63,"Zugdidi" +GE,64,"Zugdidis Raioni" +GH,01,"Greater Accra" +GH,02,"Ashanti" +GH,03,"Brong-Ahafo" +GH,04,"Central" +GH,05,"Eastern" +GH,06,"Northern" +GH,08,"Volta" +GH,09,"Western" +GH,10,"Upper East" +GH,11,"Upper West" +GL,01,"Nordgronland" +GL,02,"Ostgronland" +GL,03,"Vestgronland" +GM,01,"Banjul" +GM,02,"Lower River" +GM,03,"Central River" +GM,04,"Upper River" +GM,05,"Western" +GM,07,"North Bank" +GN,01,"Beyla" +GN,02,"Boffa" +GN,03,"Boke" +GN,04,"Conakry" +GN,05,"Dabola" +GN,06,"Dalaba" +GN,07,"Dinguiraye" +GN,09,"Faranah" +GN,10,"Forecariah" +GN,11,"Fria" +GN,12,"Gaoual" +GN,13,"Gueckedou" +GN,15,"Kerouane" +GN,16,"Kindia" +GN,17,"Kissidougou" +GN,18,"Koundara" +GN,19,"Kouroussa" +GN,21,"Macenta" +GN,22,"Mali" +GN,23,"Mamou" +GN,25,"Pita" +GN,27,"Telimele" +GN,28,"Tougue" +GN,29,"Yomou" +GN,30,"Coyah" +GN,31,"Dubreka" +GN,32,"Kankan" +GN,33,"Koubia" +GN,34,"Labe" +GN,35,"Lelouma" +GN,36,"Lola" +GN,37,"Mandiana" +GN,38,"Nzerekore" +GN,39,"Siguiri" +GQ,03,"Annobon" +GQ,04,"Bioko Norte" +GQ,05,"Bioko Sur" +GQ,06,"Centro Sur" +GQ,07,"Kie-Ntem" +GQ,08,"Litoral" +GQ,09,"Wele-Nzas" +GR,01,"Evros" +GR,02,"Rodhopi" +GR,03,"Xanthi" +GR,04,"Drama" +GR,05,"Serrai" +GR,06,"Kilkis" +GR,07,"Pella" +GR,08,"Florina" +GR,09,"Kastoria" +GR,10,"Grevena" +GR,11,"Kozani" +GR,12,"Imathia" +GR,13,"Thessaloniki" +GR,14,"Kavala" +GR,15,"Khalkidhiki" +GR,16,"Pieria" +GR,17,"Ioannina" +GR,18,"Thesprotia" +GR,19,"Preveza" +GR,20,"Arta" +GR,21,"Larisa" +GR,22,"Trikala" +GR,23,"Kardhitsa" +GR,24,"Magnisia" +GR,25,"Kerkira" +GR,26,"Levkas" +GR,27,"Kefallinia" +GR,28,"Zakinthos" +GR,29,"Fthiotis" +GR,30,"Evritania" +GR,31,"Aitolia kai Akarnania" +GR,32,"Fokis" +GR,33,"Voiotia" +GR,34,"Evvoia" +GR,35,"Attiki" +GR,36,"Argolis" +GR,37,"Korinthia" +GR,38,"Akhaia" +GR,39,"Ilia" +GR,40,"Messinia" +GR,41,"Arkadhia" +GR,42,"Lakonia" +GR,43,"Khania" +GR,44,"Rethimni" +GR,45,"Iraklion" +GR,46,"Lasithi" +GR,47,"Dhodhekanisos" +GR,48,"Samos" +GR,49,"Kikladhes" +GR,50,"Khios" +GR,51,"Lesvos" +GT,01,"Alta Verapaz" +GT,02,"Baja Verapaz" +GT,03,"Chimaltenango" +GT,04,"Chiquimula" +GT,05,"El Progreso" +GT,06,"Escuintla" +GT,07,"Guatemala" +GT,08,"Huehuetenango" +GT,09,"Izabal" +GT,10,"Jalapa" +GT,11,"Jutiapa" +GT,12,"Peten" +GT,13,"Quetzaltenango" +GT,14,"Quiche" +GT,15,"Retalhuleu" +GT,16,"Sacatepequez" +GT,17,"San Marcos" +GT,18,"Santa Rosa" +GT,19,"Solola" +GT,20,"Suchitepequez" +GT,21,"Totonicapan" +GT,22,"Zacapa" +GW,01,"Bafata" +GW,02,"Quinara" +GW,04,"Oio" +GW,05,"Bolama" +GW,06,"Cacheu" +GW,07,"Tombali" +GW,10,"Gabu" +GW,11,"Bissau" +GW,12,"Biombo" +GY,10,"Barima-Waini" +GY,11,"Cuyuni-Mazaruni" +GY,12,"Demerara-Mahaica" +GY,13,"East Berbice-Corentyne" +GY,14,"Essequibo Islands-West Demerara" +GY,15,"Mahaica-Berbice" +GY,16,"Pomeroon-Supenaam" +GY,17,"Potaro-Siparuni" +GY,18,"Upper Demerara-Berbice" +GY,19,"Upper Takutu-Upper Essequibo" +HN,01,"Atlantida" +HN,02,"Choluteca" +HN,03,"Colon" +HN,04,"Comayagua" +HN,05,"Copan" +HN,06,"Cortes" +HN,07,"El Paraiso" +HN,08,"Francisco Morazan" +HN,09,"Gracias a Dios" +HN,10,"Intibuca" +HN,11,"Islas de la Bahia" +HN,12,"La Paz" +HN,13,"Lempira" +HN,14,"Ocotepeque" +HN,15,"Olancho" +HN,16,"Santa Barbara" +HN,17,"Valle" +HN,18,"Yoro" +HR,01,"Bjelovarsko-Bilogorska" +HR,02,"Brodsko-Posavska" +HR,03,"Dubrovacko-Neretvanska" +HR,04,"Istarska" +HR,05,"Karlovacka" +HR,06,"Koprivnicko-Krizevacka" +HR,07,"Krapinsko-Zagorska" +HR,08,"Licko-Senjska" +HR,09,"Medimurska" +HR,10,"Osjecko-Baranjska" +HR,11,"Pozesko-Slavonska" +HR,12,"Primorsko-Goranska" +HR,13,"Sibensko-Kninska" +HR,14,"Sisacko-Moslavacka" +HR,15,"Splitsko-Dalmatinska" +HR,16,"Varazdinska" +HR,17,"Viroviticko-Podravska" +HR,18,"Vukovarsko-Srijemska" +HR,19,"Zadarska" +HR,20,"Zagrebacka" +HR,21,"Grad Zagreb" +HT,03,"Nord-Ouest" +HT,06,"Artibonite" +HT,07,"Centre" +HT,09,"Nord" +HT,10,"Nord-Est" +HT,11,"Ouest" +HT,12,"Sud" +HT,13,"Sud-Est" +HT,14,"Grand' Anse" +HT,15,"Nippes" +HU,01,"Bacs-Kiskun" +HU,02,"Baranya" +HU,03,"Bekes" +HU,04,"Borsod-Abauj-Zemplen" +HU,05,"Budapest" +HU,06,"Csongrad" +HU,07,"Debrecen" +HU,08,"Fejer" +HU,09,"Gyor-Moson-Sopron" +HU,10,"Hajdu-Bihar" +HU,11,"Heves" +HU,12,"Komarom-Esztergom" +HU,13,"Miskolc" +HU,14,"Nograd" +HU,15,"Pecs" +HU,16,"Pest" +HU,17,"Somogy" +HU,18,"Szabolcs-Szatmar-Bereg" +HU,19,"Szeged" +HU,20,"Jasz-Nagykun-Szolnok" +HU,21,"Tolna" +HU,22,"Vas" +HU,23,"Veszprem" +HU,24,"Zala" +HU,25,"Gyor" +HU,26,"Bekescsaba" +HU,27,"Dunaujvaros" +HU,28,"Eger" +HU,29,"Hodmezovasarhely" +HU,30,"Kaposvar" +HU,31,"Kecskemet" +HU,32,"Nagykanizsa" +HU,33,"Nyiregyhaza" +HU,34,"Sopron" +HU,35,"Szekesfehervar" +HU,36,"Szolnok" +HU,37,"Szombathely" +HU,38,"Tatabanya" +HU,39,"Veszprem" +HU,40,"Zalaegerszeg" +HU,41,"Salgotarjan" +HU,42,"Szekszard" +HU,43,"Erd" +ID,01,"Aceh" +ID,02,"Bali" +ID,03,"Bengkulu" +ID,04,"Jakarta Raya" +ID,05,"Jambi" +ID,07,"Jawa Tengah" +ID,08,"Jawa Timur" +ID,10,"Yogyakarta" +ID,11,"Kalimantan Barat" +ID,12,"Kalimantan Selatan" +ID,13,"Kalimantan Tengah" +ID,14,"Kalimantan Timur" +ID,15,"Lampung" +ID,17,"Nusa Tenggara Barat" +ID,18,"Nusa Tenggara Timur" +ID,21,"Sulawesi Tengah" +ID,22,"Sulawesi Tenggara" +ID,24,"Sumatera Barat" +ID,26,"Sumatera Utara" +ID,28,"Maluku" +ID,29,"Maluku Utara" +ID,30,"Jawa Barat" +ID,31,"Sulawesi Utara" +ID,32,"Sumatera Selatan" +ID,33,"Banten" +ID,34,"Gorontalo" +ID,35,"Kepulauan Bangka Belitung" +ID,36,"Papua" +ID,37,"Riau" +ID,38,"Sulawesi Selatan" +ID,39,"Irian Jaya Barat" +ID,40,"Kepulauan Riau" +ID,41,"Sulawesi Barat" +IE,01,"Carlow" +IE,02,"Cavan" +IE,03,"Clare" +IE,04,"Cork" +IE,06,"Donegal" +IE,07,"Dublin" +IE,10,"Galway" +IE,11,"Kerry" +IE,12,"Kildare" +IE,13,"Kilkenny" +IE,14,"Leitrim" +IE,15,"Laois" +IE,16,"Limerick" +IE,18,"Longford" +IE,19,"Louth" +IE,20,"Mayo" +IE,21,"Meath" +IE,22,"Monaghan" +IE,23,"Offaly" +IE,24,"Roscommon" +IE,25,"Sligo" +IE,26,"Tipperary" +IE,27,"Waterford" +IE,29,"Westmeath" +IE,30,"Wexford" +IE,31,"Wicklow" +IL,01,"HaDarom" +IL,02,"HaMerkaz" +IL,03,"HaZafon" +IL,04,"Hefa" +IL,05,"Tel Aviv" +IL,06,"Yerushalayim" +IN,01,"Andaman and Nicobar Islands" +IN,02,"Andhra Pradesh" +IN,03,"Assam" +IN,05,"Chandigarh" +IN,06,"Dadra and Nagar Haveli" +IN,07,"Delhi" +IN,09,"Gujarat" +IN,10,"Haryana" +IN,11,"Himachal Pradesh" +IN,12,"Jammu and Kashmir" +IN,13,"Kerala" +IN,14,"Lakshadweep" +IN,16,"Maharashtra" +IN,17,"Manipur" +IN,18,"Meghalaya" +IN,19,"Karnataka" +IN,20,"Nagaland" +IN,21,"Orissa" +IN,22,"Puducherry" +IN,23,"Punjab" +IN,24,"Rajasthan" +IN,25,"Tamil Nadu" +IN,26,"Tripura" +IN,28,"West Bengal" +IN,29,"Sikkim" +IN,30,"Arunachal Pradesh" +IN,31,"Mizoram" +IN,32,"Daman and Diu" +IN,33,"Goa" +IN,34,"Bihar" +IN,35,"Madhya Pradesh" +IN,36,"Uttar Pradesh" +IN,37,"Chhattisgarh" +IN,38,"Jharkhand" +IN,39,"Uttarakhand" +IQ,01,"Al Anbar" +IQ,02,"Al Basrah" +IQ,03,"Al Muthanna" +IQ,04,"Al Qadisiyah" +IQ,05,"As Sulaymaniyah" +IQ,06,"Babil" +IQ,07,"Baghdad" +IQ,08,"Dahuk" +IQ,09,"Dhi Qar" +IQ,10,"Diyala" +IQ,11,"Arbil" +IQ,12,"Karbala'" +IQ,13,"At Ta'mim" +IQ,14,"Maysan" +IQ,15,"Ninawa" +IQ,16,"Wasit" +IQ,17,"An Najaf" +IQ,18,"Salah ad Din" +IR,01,"Azarbayjan-e Bakhtari" +IR,03,"Chahar Mahall va Bakhtiari" +IR,04,"Sistan va Baluchestan" +IR,05,"Kohkiluyeh va Buyer Ahmadi" +IR,07,"Fars" +IR,08,"Gilan" +IR,09,"Hamadan" +IR,10,"Ilam" +IR,11,"Hormozgan" +IR,12,"Kerman" +IR,13,"Bakhtaran" +IR,15,"Khuzestan" +IR,16,"Kordestan" +IR,17,"Mazandaran" +IR,18,"Semnan Province" +IR,19,"Markazi" +IR,21,"Zanjan" +IR,22,"Bushehr" +IR,23,"Lorestan" +IR,24,"Markazi" +IR,25,"Semnan" +IR,26,"Tehran" +IR,27,"Zanjan" +IR,28,"Esfahan" +IR,29,"Kerman" +IR,30,"Khorasan" +IR,31,"Yazd" +IR,32,"Ardabil" +IR,33,"East Azarbaijan" +IR,34,"Markazi" +IR,35,"Mazandaran" +IR,36,"Zanjan" +IR,37,"Golestan" +IR,38,"Qazvin" +IR,39,"Qom" +IR,40,"Yazd" +IR,41,"Khorasan-e Janubi" +IR,42,"Khorasan-e Razavi" +IR,43,"Khorasan-e Shemali" +IR,44,"Alborz" +IS,03,"Arnessysla" +IS,05,"Austur-Hunavatnssysla" +IS,06,"Austur-Skaftafellssysla" +IS,07,"Borgarfjardarsysla" +IS,09,"Eyjafjardarsysla" +IS,10,"Gullbringusysla" +IS,15,"Kjosarsysla" +IS,17,"Myrasysla" +IS,20,"Nordur-Mulasysla" +IS,21,"Nordur-Tingeyjarsysla" +IS,23,"Rangarvallasysla" +IS,28,"Skagafjardarsysla" +IS,29,"Snafellsnes- og Hnappadalssysla" +IS,30,"Strandasysla" +IS,31,"Sudur-Mulasysla" +IS,32,"Sudur-Tingeyjarsysla" +IS,34,"Vestur-Bardastrandarsysla" +IS,35,"Vestur-Hunavatnssysla" +IS,36,"Vestur-Isafjardarsysla" +IS,37,"Vestur-Skaftafellssysla" +IS,38,"Austurland" +IS,39,"Hofuoborgarsvaoio" +IS,40,"Norourland Eystra" +IS,41,"Norourland Vestra" +IS,42,"Suourland" +IS,43,"Suournes" +IS,44,"Vestfiroir" +IS,45,"Vesturland" +IT,01,"Abruzzi" +IT,02,"Basilicata" +IT,03,"Calabria" +IT,04,"Campania" +IT,05,"Emilia-Romagna" +IT,06,"Friuli-Venezia Giulia" +IT,07,"Lazio" +IT,08,"Liguria" +IT,09,"Lombardia" +IT,10,"Marche" +IT,11,"Molise" +IT,12,"Piemonte" +IT,13,"Puglia" +IT,14,"Sardegna" +IT,15,"Sicilia" +IT,16,"Toscana" +IT,17,"Trentino-Alto Adige" +IT,18,"Umbria" +IT,19,"Valle d'Aosta" +IT,20,"Veneto" +JM,01,"Clarendon" +JM,02,"Hanover" +JM,04,"Manchester" +JM,07,"Portland" +JM,08,"Saint Andrew" +JM,09,"Saint Ann" +JM,10,"Saint Catherine" +JM,11,"Saint Elizabeth" +JM,12,"Saint James" +JM,13,"Saint Mary" +JM,14,"Saint Thomas" +JM,15,"Trelawny" +JM,16,"Westmoreland" +JM,17,"Kingston" +JO,02,"Al Balqa'" +JO,09,"Al Karak" +JO,12,"At Tafilah" +JO,15,"Al Mafraq" +JO,16,"Amman" +JO,17,"Az Zaraqa" +JO,18,"Irbid" +JO,19,"Ma'an" +JO,20,"Ajlun" +JO,21,"Al Aqabah" +JO,22,"Jarash" +JO,23,"Madaba" +JP,01,"Aichi" +JP,02,"Akita" +JP,03,"Aomori" +JP,04,"Chiba" +JP,05,"Ehime" +JP,06,"Fukui" +JP,07,"Fukuoka" +JP,08,"Fukushima" +JP,09,"Gifu" +JP,10,"Gumma" +JP,11,"Hiroshima" +JP,12,"Hokkaido" +JP,13,"Hyogo" +JP,14,"Ibaraki" +JP,15,"Ishikawa" +JP,16,"Iwate" +JP,17,"Kagawa" +JP,18,"Kagoshima" +JP,19,"Kanagawa" +JP,20,"Kochi" +JP,21,"Kumamoto" +JP,22,"Kyoto" +JP,23,"Mie" +JP,24,"Miyagi" +JP,25,"Miyazaki" +JP,26,"Nagano" +JP,27,"Nagasaki" +JP,28,"Nara" +JP,29,"Niigata" +JP,30,"Oita" +JP,31,"Okayama" +JP,32,"Osaka" +JP,33,"Saga" +JP,34,"Saitama" +JP,35,"Shiga" +JP,36,"Shimane" +JP,37,"Shizuoka" +JP,38,"Tochigi" +JP,39,"Tokushima" +JP,40,"Tokyo" +JP,41,"Tottori" +JP,42,"Toyama" +JP,43,"Wakayama" +JP,44,"Yamagata" +JP,45,"Yamaguchi" +JP,46,"Yamanashi" +JP,47,"Okinawa" +KE,01,"Central" +KE,02,"Coast" +KE,03,"Eastern" +KE,05,"Nairobi Area" +KE,06,"North-Eastern" +KE,07,"Nyanza" +KE,08,"Rift Valley" +KE,09,"Western" +KG,01,"Bishkek" +KG,02,"Chuy" +KG,03,"Jalal-Abad" +KG,04,"Naryn" +KG,05,"Osh" +KG,06,"Talas" +KG,07,"Ysyk-Kol" +KG,08,"Osh" +KG,09,"Batken" +KH,01,"Batdambang" +KH,02,"Kampong Cham" +KH,03,"Kampong Chhnang" +KH,04,"Kampong Speu" +KH,05,"Kampong Thum" +KH,06,"Kampot" +KH,07,"Kandal" +KH,08,"Koh Kong" +KH,09,"Kracheh" +KH,10,"Mondulkiri" +KH,11,"Phnum Penh" +KH,12,"Pursat" +KH,13,"Preah Vihear" +KH,14,"Prey Veng" +KH,15,"Ratanakiri Kiri" +KH,16,"Siem Reap" +KH,17,"Stung Treng" +KH,18,"Svay Rieng" +KH,19,"Takeo" +KH,22,"Phnum Penh" +KH,23,"Ratanakiri" +KH,25,"Banteay Meanchey" +KH,28,"Preah Seihanu" +KH,29,"Batdambang" +KH,30,"Pailin" +KI,01,"Gilbert Islands" +KI,02,"Line Islands" +KI,03,"Phoenix Islands" +KM,01,"Anjouan" +KM,02,"Grande Comore" +KM,03,"Moheli" +KN,01,"Christ Church Nichola Town" +KN,02,"Saint Anne Sandy Point" +KN,03,"Saint George Basseterre" +KN,04,"Saint George Gingerland" +KN,05,"Saint James Windward" +KN,06,"Saint John Capisterre" +KN,07,"Saint John Figtree" +KN,08,"Saint Mary Cayon" +KN,09,"Saint Paul Capisterre" +KN,10,"Saint Paul Charlestown" +KN,11,"Saint Peter Basseterre" +KN,12,"Saint Thomas Lowland" +KN,13,"Saint Thomas Middle Island" +KN,15,"Trinity Palmetto Point" +KP,01,"Chagang-do" +KP,03,"Hamgyong-namdo" +KP,06,"Hwanghae-namdo" +KP,07,"Hwanghae-bukto" +KP,08,"Kaesong-si" +KP,09,"Kangwon-do" +KP,11,"P'yongan-bukto" +KP,12,"P'yongyang-si" +KP,13,"Yanggang-do" +KP,14,"Namp'o-si" +KP,15,"P'yongan-namdo" +KP,17,"Hamgyong-bukto" +KP,18,"Najin Sonbong-si" +KR,01,"Cheju-do" +KR,03,"Cholla-bukto" +KR,05,"Ch'ungch'ong-bukto" +KR,06,"Kangwon-do" +KR,10,"Pusan-jikhalsi" +KR,11,"Seoul-t'ukpyolsi" +KR,12,"Inch'on-jikhalsi" +KR,13,"Kyonggi-do" +KR,14,"Kyongsang-bukto" +KR,15,"Taegu-jikhalsi" +KR,16,"Cholla-namdo" +KR,17,"Ch'ungch'ong-namdo" +KR,18,"Kwangju-jikhalsi" +KR,19,"Taejon-jikhalsi" +KR,20,"Kyongsang-namdo" +KR,21,"Ulsan-gwangyoksi" +KW,01,"Al Ahmadi" +KW,02,"Al Kuwayt" +KW,05,"Al Jahra" +KW,07,"Al Farwaniyah" +KW,08,"Hawalli" +KW,09,"Mubarak al Kabir" +KY,01,"Creek" +KY,02,"Eastern" +KY,03,"Midland" +KY,04,"South Town" +KY,05,"Spot Bay" +KY,06,"Stake Bay" +KY,07,"West End" +KY,08,"Western" +KZ,01,"Almaty" +KZ,02,"Almaty City" +KZ,03,"Aqmola" +KZ,04,"Aqtobe" +KZ,05,"Astana" +KZ,06,"Atyrau" +KZ,07,"West Kazakhstan" +KZ,08,"Bayqonyr" +KZ,09,"Mangghystau" +KZ,10,"South Kazakhstan" +KZ,11,"Pavlodar" +KZ,12,"Qaraghandy" +KZ,13,"Qostanay" +KZ,14,"Qyzylorda" +KZ,15,"East Kazakhstan" +KZ,16,"North Kazakhstan" +KZ,17,"Zhambyl" +LA,01,"Attapu" +LA,02,"Champasak" +LA,03,"Houaphan" +LA,04,"Khammouan" +LA,05,"Louang Namtha" +LA,07,"Oudomxai" +LA,08,"Phongsali" +LA,09,"Saravan" +LA,10,"Savannakhet" +LA,11,"Vientiane" +LA,13,"Xaignabouri" +LA,14,"Xiangkhoang" +LA,17,"Louangphrabang" +LB,01,"Beqaa" +LB,02,"Al Janub" +LB,03,"Liban-Nord" +LB,04,"Beyrouth" +LB,05,"Mont-Liban" +LB,06,"Liban-Sud" +LB,07,"Nabatiye" +LB,08,"Beqaa" +LB,09,"Liban-Nord" +LB,10,"Aakk,r" +LB,11,"Baalbek-Hermel" +LC,01,"Anse-la-Raye" +LC,02,"Dauphin" +LC,03,"Castries" +LC,04,"Choiseul" +LC,05,"Dennery" +LC,06,"Gros-Islet" +LC,07,"Laborie" +LC,08,"Micoud" +LC,09,"Soufriere" +LC,10,"Vieux-Fort" +LC,11,"Praslin" +LI,01,"Balzers" +LI,02,"Eschen" +LI,03,"Gamprin" +LI,04,"Mauren" +LI,05,"Planken" +LI,06,"Ruggell" +LI,07,"Schaan" +LI,08,"Schellenberg" +LI,09,"Triesen" +LI,10,"Triesenberg" +LI,11,"Vaduz" +LI,21,"Gbarpolu" +LI,22,"River Gee" +LK,29,"Central" +LK,30,"North Central" +LK,32,"North Western" +LK,33,"Sabaragamuwa" +LK,34,"Southern" +LK,35,"Uva" +LK,36,"Western" +LK,37,"Eastern" +LK,38,"Northern" +LR,01,"Bong" +LR,04,"Grand Cape Mount" +LR,05,"Lofa" +LR,06,"Maryland" +LR,07,"Monrovia" +LR,09,"Nimba" +LR,10,"Sino" +LR,11,"Grand Bassa" +LR,12,"Grand Cape Mount" +LR,13,"Maryland" +LR,14,"Montserrado" +LR,17,"Margibi" +LR,18,"River Cess" +LR,19,"Grand Gedeh" +LR,20,"Lofa" +LR,21,"Gbarpolu" +LR,22,"River Gee" +LS,10,"Berea" +LS,11,"Butha-Buthe" +LS,12,"Leribe" +LS,13,"Mafeteng" +LS,14,"Maseru" +LS,15,"Mohales Hoek" +LS,16,"Mokhotlong" +LS,17,"Qachas Nek" +LS,18,"Quthing" +LS,19,"Thaba-Tseka" +LT,56,"Alytaus Apskritis" +LT,57,"Kauno Apskritis" +LT,58,"Klaipedos Apskritis" +LT,59,"Marijampoles Apskritis" +LT,60,"Panevezio Apskritis" +LT,61,"Siauliu Apskritis" +LT,62,"Taurages Apskritis" +LT,63,"Telsiu Apskritis" +LT,64,"Utenos Apskritis" +LT,65,"Vilniaus Apskritis" +LU,01,"Diekirch" +LU,02,"Grevenmacher" +LU,03,"Luxembourg" +LV,01,"Aizkraukles" +LV,02,"Aluksnes" +LV,03,"Balvu" +LV,04,"Bauskas" +LV,05,"Cesu" +LV,06,"Daugavpils" +LV,07,"Daugavpils" +LV,08,"Dobeles" +LV,09,"Gulbenes" +LV,10,"Jekabpils" +LV,11,"Jelgava" +LV,12,"Jelgavas" +LV,13,"Jurmala" +LV,14,"Kraslavas" +LV,15,"Kuldigas" +LV,16,"Liepaja" +LV,17,"Liepajas" +LV,18,"Limbazu" +LV,19,"Ludzas" +LV,20,"Madonas" +LV,21,"Ogres" +LV,22,"Preilu" +LV,23,"Rezekne" +LV,24,"Rezeknes" +LV,25,"Riga" +LV,26,"Rigas" +LV,27,"Saldus" +LV,28,"Talsu" +LV,29,"Tukuma" +LV,30,"Valkas" +LV,31,"Valmieras" +LV,32,"Ventspils" +LV,33,"Ventspils" +LY,03,"Al Aziziyah" +LY,05,"Al Jufrah" +LY,08,"Al Kufrah" +LY,13,"Ash Shati'" +LY,30,"Murzuq" +LY,34,"Sabha" +LY,41,"Tarhunah" +LY,42,"Tubruq" +LY,45,"Zlitan" +LY,47,"Ajdabiya" +LY,48,"Al Fatih" +LY,49,"Al Jabal al Akhdar" +LY,50,"Al Khums" +LY,51,"An Nuqat al Khams" +LY,52,"Awbari" +LY,53,"Az Zawiyah" +LY,54,"Banghazi" +LY,55,"Darnah" +LY,56,"Ghadamis" +LY,57,"Gharyan" +LY,58,"Misratah" +LY,59,"Sawfajjin" +LY,60,"Surt" +LY,61,"Tarabulus" +LY,62,"Yafran" +MA,45,"Grand Casablanca" +MA,46,"Fes-Boulemane" +MA,47,"Marrakech-Tensift-Al Haouz" +MA,48,"Meknes-Tafilalet" +MA,49,"Rabat-Sale-Zemmour-Zaer" +MA,50,"Chaouia-Ouardigha" +MA,51,"Doukkala-Abda" +MA,52,"Gharb-Chrarda-Beni Hssen" +MA,53,"Guelmim-Es Smara" +MA,54,"Oriental" +MA,55,"Souss-Massa-Dr,a" +MA,56,"Tadla-Azilal" +MA,57,"Tanger-Tetouan" +MA,58,"Taza-Al Hoceima-Taounate" +MA,59,"La,youne-Boujdour-Sakia El Hamra" +MC,01,"La Condamine" +MC,02,"Monaco" +MC,03,"Monte-Carlo" +MD,51,"Gagauzia" +MD,57,"Chisinau" +MD,58,"Stinga Nistrului" +MD,59,"Anenii Noi" +MD,60,"Balti" +MD,61,"Basarabeasca" +MD,62,"Bender" +MD,63,"Briceni" +MD,64,"Cahul" +MD,65,"Cantemir" +MD,66,"Calarasi" +MD,67,"Causeni" +MD,68,"Cimislia" +MD,69,"Criuleni" +MD,70,"Donduseni" +MD,71,"Drochia" +MD,72,"Dubasari" +MD,73,"Edinet" +MD,74,"Falesti" +MD,75,"Floresti" +MD,76,"Glodeni" +MD,77,"Hincesti" +MD,78,"Ialoveni" +MD,79,"Leova" +MD,80,"Nisporeni" +MD,81,"Ocnita" +MD,82,"Orhei" +MD,83,"Rezina" +MD,84,"Riscani" +MD,85,"Singerei" +MD,86,"Soldanesti" +MD,87,"Soroca" +MD,88,"Stefan-Voda" +MD,89,"Straseni" +MD,90,"Taraclia" +MD,91,"Telenesti" +MD,92,"Ungheni" +MG,01,"Antsiranana" +MG,02,"Fianarantsoa" +MG,03,"Mahajanga" +MG,04,"Toamasina" +MG,05,"Antananarivo" +MG,06,"Toliara" +MK,01,"Aracinovo" +MK,02,"Bac" +MK,03,"Belcista" +MK,04,"Berovo" +MK,05,"Bistrica" +MK,06,"Bitola" +MK,07,"Blatec" +MK,08,"Bogdanci" +MK,09,"Bogomila" +MK,10,"Bogovinje" +MK,11,"Bosilovo" +MK,12,"Brvenica" +MK,13,"Cair" +MK,14,"Capari" +MK,15,"Caska" +MK,16,"Cegrane" +MK,17,"Centar" +MK,18,"Centar Zupa" +MK,19,"Cesinovo" +MK,20,"Cucer-Sandevo" +MK,21,"Debar" +MK,22,"Delcevo" +MK,23,"Delogozdi" +MK,24,"Demir Hisar" +MK,25,"Demir Kapija" +MK,26,"Dobrusevo" +MK,27,"Dolna Banjica" +MK,28,"Dolneni" +MK,29,"Dorce Petrov" +MK,30,"Drugovo" +MK,31,"Dzepciste" +MK,32,"Gazi Baba" +MK,33,"Gevgelija" +MK,34,"Gostivar" +MK,35,"Gradsko" +MK,36,"Ilinden" +MK,37,"Izvor" +MK,38,"Jegunovce" +MK,39,"Kamenjane" +MK,40,"Karbinci" +MK,41,"Karpos" +MK,42,"Kavadarci" +MK,43,"Kicevo" +MK,44,"Kisela Voda" +MK,45,"Klecevce" +MK,46,"Kocani" +MK,47,"Konce" +MK,48,"Kondovo" +MK,49,"Konopiste" +MK,50,"Kosel" +MK,51,"Kratovo" +MK,52,"Kriva Palanka" +MK,53,"Krivogastani" +MK,54,"Krusevo" +MK,55,"Kuklis" +MK,56,"Kukurecani" +MK,57,"Kumanovo" +MK,58,"Labunista" +MK,59,"Lipkovo" +MK,60,"Lozovo" +MK,61,"Lukovo" +MK,62,"Makedonska Kamenica" +MK,63,"Makedonski Brod" +MK,64,"Mavrovi Anovi" +MK,65,"Meseista" +MK,66,"Miravci" +MK,67,"Mogila" +MK,68,"Murtino" +MK,69,"Negotino" +MK,70,"Negotino-Polosko" +MK,71,"Novaci" +MK,72,"Novo Selo" +MK,73,"Oblesevo" +MK,74,"Ohrid" +MK,75,"Orasac" +MK,76,"Orizari" +MK,77,"Oslomej" +MK,78,"Pehcevo" +MK,79,"Petrovec" +MK,80,"Plasnica" +MK,81,"Podares" +MK,82,"Prilep" +MK,83,"Probistip" +MK,84,"Radovis" +MK,85,"Rankovce" +MK,86,"Resen" +MK,87,"Rosoman" +MK,88,"Rostusa" +MK,89,"Samokov" +MK,90,"Saraj" +MK,91,"Sipkovica" +MK,92,"Sopiste" +MK,93,"Sopotnica" +MK,94,"Srbinovo" +MK,95,"Staravina" +MK,96,"Star Dojran" +MK,97,"Staro Nagoricane" +MK,98,"Stip" +MK,99,"Struga" +MK,A1,"Strumica" +MK,A2,"Studenicani" +MK,A3,"Suto Orizari" +MK,A4,"Sveti Nikole" +MK,A5,"Tearce" +MK,A6,"Tetovo" +MK,A7,"Topolcani" +MK,A8,"Valandovo" +MK,A9,"Vasilevo" +MK,B1,"Veles" +MK,B2,"Velesta" +MK,B3,"Vevcani" +MK,B4,"Vinica" +MK,B5,"Vitoliste" +MK,B6,"Vranestica" +MK,B7,"Vrapciste" +MK,B8,"Vratnica" +MK,B9,"Vrutok" +MK,C1,"Zajas" +MK,C2,"Zelenikovo" +MK,C3,"Zelino" +MK,C4,"Zitose" +MK,C5,"Zletovo" +MK,C6,"Zrnovci" +MK,C8,"Cair" +MK,C9,"Caska" +MK,D2,"Debar" +MK,D3,"Demir Hisar" +MK,D4,"Gostivar" +MK,D5,"Jegunovce" +MK,D6,"Kavadarci" +MK,D7,"Kumanovo" +MK,D8,"Makedonski Brod" +MK,E2,"Ohrid" +MK,E3,"Prilep" +MK,E5,"Dojran" +MK,E6,"Struga" +MK,E7,"Strumica" +MK,E8,"Tetovo" +MK,E9,"Valandovo" +MK,F1,"Veles" +MK,F2,"Aerodrom" +ML,01,"Bamako" +ML,03,"Kayes" +ML,04,"Mopti" +ML,05,"Segou" +ML,06,"Sikasso" +ML,07,"Koulikoro" +ML,08,"Tombouctou" +ML,09,"Gao" +ML,10,"Kidal" +MM,01,"Rakhine State" +MM,02,"Chin State" +MM,03,"Irrawaddy" +MM,04,"Kachin State" +MM,05,"Karan State" +MM,06,"Kayah State" +MM,07,"Magwe" +MM,08,"Mandalay" +MM,09,"Pegu" +MM,10,"Sagaing" +MM,11,"Shan State" +MM,12,"Tenasserim" +MM,13,"Mon State" +MM,14,"Rangoon" +MM,17,"Yangon" +MN,01,"Arhangay" +MN,02,"Bayanhongor" +MN,03,"Bayan-Olgiy" +MN,05,"Darhan" +MN,06,"Dornod" +MN,07,"Dornogovi" +MN,08,"Dundgovi" +MN,09,"Dzavhan" +MN,10,"Govi-Altay" +MN,11,"Hentiy" +MN,12,"Hovd" +MN,13,"Hovsgol" +MN,14,"Omnogovi" +MN,15,"Ovorhangay" +MN,16,"Selenge" +MN,17,"Suhbaatar" +MN,18,"Tov" +MN,19,"Uvs" +MN,20,"Ulaanbaatar" +MN,21,"Bulgan" +MN,22,"Erdenet" +MN,23,"Darhan-Uul" +MN,24,"Govisumber" +MN,25,"Orhon" +MO,01,"Ilhas" +MO,02,"Macau" +MR,01,"Hodh Ech Chargui" +MR,02,"Hodh El Gharbi" +MR,03,"Assaba" +MR,04,"Gorgol" +MR,05,"Brakna" +MR,06,"Trarza" +MR,07,"Adrar" +MR,08,"Dakhlet Nouadhibou" +MR,09,"Tagant" +MR,10,"Guidimaka" +MR,11,"Tiris Zemmour" +MR,12,"Inchiri" +MS,01,"Saint Anthony" +MS,02,"Saint Georges" +MS,03,"Saint Peter" +MU,12,"Black River" +MU,13,"Flacq" +MU,14,"Grand Port" +MU,15,"Moka" +MU,16,"Pamplemousses" +MU,17,"Plaines Wilhems" +MU,18,"Port Louis" +MU,19,"Riviere du Rempart" +MU,20,"Savanne" +MU,21,"Agalega Islands" +MU,22,"Cargados Carajos" +MU,23,"Rodrigues" +MV,01,"Seenu" +MV,05,"Laamu" +MV,30,"Alifu" +MV,31,"Baa" +MV,32,"Dhaalu" +MV,33,"Faafu " +MV,34,"Gaafu Alifu" +MV,35,"Gaafu Dhaalu" +MV,36,"Haa Alifu" +MV,37,"Haa Dhaalu" +MV,38,"Kaafu" +MV,39,"Lhaviyani" +MV,40,"Maale" +MV,41,"Meemu" +MV,42,"Gnaviyani" +MV,43,"Noonu" +MV,44,"Raa" +MV,45,"Shaviyani" +MV,46,"Thaa" +MV,47,"Vaavu" +MW,02,"Chikwawa" +MW,03,"Chiradzulu" +MW,04,"Chitipa" +MW,05,"Thyolo" +MW,06,"Dedza" +MW,07,"Dowa" +MW,08,"Karonga" +MW,09,"Kasungu" +MW,11,"Lilongwe" +MW,12,"Mangochi" +MW,13,"Mchinji" +MW,15,"Mzimba" +MW,16,"Ntcheu" +MW,17,"Nkhata Bay" +MW,18,"Nkhotakota" +MW,19,"Nsanje" +MW,20,"Ntchisi" +MW,21,"Rumphi" +MW,22,"Salima" +MW,23,"Zomba" +MW,24,"Blantyre" +MW,25,"Mwanza" +MW,26,"Balaka" +MW,27,"Likoma" +MW,28,"Machinga" +MW,29,"Mulanje" +MW,30,"Phalombe" +MX,01,"Aguascalientes" +MX,02,"Baja California" +MX,03,"Baja California Sur" +MX,04,"Campeche" +MX,05,"Chiapas" +MX,06,"Chihuahua" +MX,07,"Coahuila de Zaragoza" +MX,08,"Colima" +MX,09,"Distrito Federal" +MX,10,"Durango" +MX,11,"Guanajuato" +MX,12,"Guerrero" +MX,13,"Hidalgo" +MX,14,"Jalisco" +MX,15,"Mexico" +MX,16,"Michoacan de Ocampo" +MX,17,"Morelos" +MX,18,"Nayarit" +MX,19,"Nuevo Leon" +MX,20,"Oaxaca" +MX,21,"Puebla" +MX,22,"Queretaro de Arteaga" +MX,23,"Quintana Roo" +MX,24,"San Luis Potosi" +MX,25,"Sinaloa" +MX,26,"Sonora" +MX,27,"Tabasco" +MX,28,"Tamaulipas" +MX,29,"Tlaxcala" +MX,30,"Veracruz-Llave" +MX,31,"Yucatan" +MX,32,"Zacatecas" +MY,01,"Johor" +MY,02,"Kedah" +MY,03,"Kelantan" +MY,04,"Melaka" +MY,05,"Negeri Sembilan" +MY,06,"Pahang" +MY,07,"Perak" +MY,08,"Perlis" +MY,09,"Pulau Pinang" +MY,11,"Sarawak" +MY,12,"Selangor" +MY,13,"Terengganu" +MY,14,"Kuala Lumpur" +MY,15,"Labuan" +MY,16,"Sabah" +MY,17,"Putrajaya" +MZ,01,"Cabo Delgado" +MZ,02,"Gaza" +MZ,03,"Inhambane" +MZ,04,"Maputo" +MZ,05,"Sofala" +MZ,06,"Nampula" +MZ,07,"Niassa" +MZ,08,"Tete" +MZ,09,"Zambezia" +MZ,10,"Manica" +MZ,11,"Maputo" +NA,01,"Bethanien" +NA,02,"Caprivi Oos" +NA,03,"Boesmanland" +NA,04,"Gobabis" +NA,05,"Grootfontein" +NA,06,"Kaokoland" +NA,07,"Karibib" +NA,08,"Keetmanshoop" +NA,09,"Luderitz" +NA,10,"Maltahohe" +NA,11,"Okahandja" +NA,12,"Omaruru" +NA,13,"Otjiwarongo" +NA,14,"Outjo" +NA,15,"Owambo" +NA,16,"Rehoboth" +NA,17,"Swakopmund" +NA,18,"Tsumeb" +NA,20,"Karasburg" +NA,21,"Windhoek" +NA,22,"Damaraland" +NA,23,"Hereroland Oos" +NA,24,"Hereroland Wes" +NA,25,"Kavango" +NA,26,"Mariental" +NA,27,"Namaland" +NA,28,"Caprivi" +NA,29,"Erongo" +NA,30,"Hardap" +NA,31,"Karas" +NA,32,"Kunene" +NA,33,"Ohangwena" +NA,34,"Okavango" +NA,35,"Omaheke" +NA,36,"Omusati" +NA,37,"Oshana" +NA,38,"Oshikoto" +NA,39,"Otjozondjupa" +NE,01,"Agadez" +NE,02,"Diffa" +NE,03,"Dosso" +NE,04,"Maradi" +NE,05,"Niamey" +NE,06,"Tahoua" +NE,07,"Zinder" +NE,08,"Niamey" +NG,05,"Lagos" +NG,11,"Federal Capital Territory" +NG,16,"Ogun" +NG,21,"Akwa Ibom" +NG,22,"Cross River" +NG,23,"Kaduna" +NG,24,"Katsina" +NG,25,"Anambra" +NG,26,"Benue" +NG,27,"Borno" +NG,28,"Imo" +NG,29,"Kano" +NG,30,"Kwara" +NG,31,"Niger" +NG,32,"Oyo" +NG,35,"Adamawa" +NG,36,"Delta" +NG,37,"Edo" +NG,39,"Jigawa" +NG,40,"Kebbi" +NG,41,"Kogi" +NG,42,"Osun" +NG,43,"Taraba" +NG,44,"Yobe" +NG,45,"Abia" +NG,46,"Bauchi" +NG,47,"Enugu" +NG,48,"Ondo" +NG,49,"Plateau" +NG,50,"Rivers" +NG,51,"Sokoto" +NG,52,"Bayelsa" +NG,53,"Ebonyi" +NG,54,"Ekiti" +NG,55,"Gombe" +NG,56,"Nassarawa" +NG,57,"Zamfara" +NI,01,"Boaco" +NI,02,"Carazo" +NI,03,"Chinandega" +NI,04,"Chontales" +NI,05,"Esteli" +NI,06,"Granada" +NI,07,"Jinotega" +NI,08,"Leon" +NI,09,"Madriz" +NI,10,"Managua" +NI,11,"Masaya" +NI,12,"Matagalpa" +NI,13,"Nueva Segovia" +NI,14,"Rio San Juan" +NI,15,"Rivas" +NI,16,"Zelaya" +NI,17,"Autonoma Atlantico Norte" +NI,18,"Region Autonoma Atlantico Sur" +NL,01,"Drenthe" +NL,02,"Friesland" +NL,03,"Gelderland" +NL,04,"Groningen" +NL,05,"Limburg" +NL,06,"Noord-Brabant" +NL,07,"Noord-Holland" +NL,09,"Utrecht" +NL,10,"Zeeland" +NL,11,"Zuid-Holland" +NL,15,"Overijssel" +NL,16,"Flevoland" +NO,01,"Akershus" +NO,02,"Aust-Agder" +NO,04,"Buskerud" +NO,05,"Finnmark" +NO,06,"Hedmark" +NO,07,"Hordaland" +NO,08,"More og Romsdal" +NO,09,"Nordland" +NO,10,"Nord-Trondelag" +NO,11,"Oppland" +NO,12,"Oslo" +NO,13,"Ostfold" +NO,14,"Rogaland" +NO,15,"Sogn og Fjordane" +NO,16,"Sor-Trondelag" +NO,17,"Telemark" +NO,18,"Troms" +NO,19,"Vest-Agder" +NO,20,"Vestfold" +NP,01,"Bagmati" +NP,02,"Bheri" +NP,03,"Dhawalagiri" +NP,04,"Gandaki" +NP,05,"Janakpur" +NP,06,"Karnali" +NP,07,"Kosi" +NP,08,"Lumbini" +NP,09,"Mahakali" +NP,10,"Mechi" +NP,11,"Narayani" +NP,12,"Rapti" +NP,13,"Sagarmatha" +NP,14,"Seti" +NR,01,"Aiwo" +NR,02,"Anabar" +NR,03,"Anetan" +NR,04,"Anibare" +NR,05,"Baiti" +NR,06,"Boe" +NR,07,"Buada" +NR,08,"Denigomodu" +NR,09,"Ewa" +NR,10,"Ijuw" +NR,11,"Meneng" +NR,12,"Nibok" +NR,13,"Uaboe" +NR,14,"Yaren" +NZ,10,"Chatham Islands" +NZ,E7,"Auckland" +NZ,E8,"Bay of Plenty" +NZ,E9,"Canterbury" +NZ,F1,"Gisborne" +NZ,F2,"Hawke's Bay" +NZ,F3,"Manawatu-Wanganui" +NZ,F4,"Marlborough" +NZ,F5,"Nelson" +NZ,F6,"Northland" +NZ,F7,"Otago" +NZ,F8,"Southland" +NZ,F9,"Taranaki" +NZ,G1,"Waikato" +NZ,G2,"Wellington" +NZ,G3,"West Coast" +OM,01,"Ad Dakhiliyah" +OM,02,"Al Batinah" +OM,03,"Al Wusta" +OM,04,"Ash Sharqiyah" +OM,05,"Az Zahirah" +OM,06,"Masqat" +OM,07,"Musandam" +OM,08,"Zufar" +PA,01,"Bocas del Toro" +PA,02,"Chiriqui" +PA,03,"Cocle" +PA,04,"Colon" +PA,05,"Darien" +PA,06,"Herrera" +PA,07,"Los Santos" +PA,08,"Panama" +PA,09,"San Blas" +PA,10,"Veraguas" +PE,01,"Amazonas" +PE,02,"Ancash" +PE,03,"Apurimac" +PE,04,"Arequipa" +PE,05,"Ayacucho" +PE,06,"Cajamarca" +PE,07,"Callao" +PE,08,"Cusco" +PE,09,"Huancavelica" +PE,10,"Huanuco" +PE,11,"Ica" +PE,12,"Junin" +PE,13,"La Libertad" +PE,14,"Lambayeque" +PE,15,"Lima" +PE,16,"Loreto" +PE,17,"Madre de Dios" +PE,18,"Moquegua" +PE,19,"Pasco" +PE,20,"Piura" +PE,21,"Puno" +PE,22,"San Martin" +PE,23,"Tacna" +PE,24,"Tumbes" +PE,25,"Ucayali" +PG,01,"Central" +PG,02,"Gulf" +PG,03,"Milne Bay" +PG,04,"Northern" +PG,05,"Southern Highlands" +PG,06,"Western" +PG,07,"North Solomons" +PG,08,"Chimbu" +PG,09,"Eastern Highlands" +PG,10,"East New Britain" +PG,11,"East Sepik" +PG,12,"Madang" +PG,13,"Manus" +PG,14,"Morobe" +PG,15,"New Ireland" +PG,16,"Western Highlands" +PG,17,"West New Britain" +PG,18,"Sandaun" +PG,19,"Enga" +PG,20,"National Capital" +PH,01,"Abra" +PH,02,"Agusan del Norte" +PH,03,"Agusan del Sur" +PH,04,"Aklan" +PH,05,"Albay" +PH,06,"Antique" +PH,07,"Bataan" +PH,08,"Batanes" +PH,09,"Batangas" +PH,10,"Benguet" +PH,11,"Bohol" +PH,12,"Bukidnon" +PH,13,"Bulacan" +PH,14,"Cagayan" +PH,15,"Camarines Norte" +PH,16,"Camarines Sur" +PH,17,"Camiguin" +PH,18,"Capiz" +PH,19,"Catanduanes" +PH,20,"Cavite" +PH,21,"Cebu" +PH,22,"Basilan" +PH,23,"Eastern Samar" +PH,24,"Davao" +PH,25,"Davao del Sur" +PH,26,"Davao Oriental" +PH,27,"Ifugao" +PH,28,"Ilocos Norte" +PH,29,"Ilocos Sur" +PH,30,"Iloilo" +PH,31,"Isabela" +PH,32,"Kalinga-Apayao" +PH,33,"Laguna" +PH,34,"Lanao del Norte" +PH,35,"Lanao del Sur" +PH,36,"La Union" +PH,37,"Leyte" +PH,38,"Marinduque" +PH,39,"Masbate" +PH,40,"Mindoro Occidental" +PH,41,"Mindoro Oriental" +PH,42,"Misamis Occidental" +PH,43,"Misamis Oriental" +PH,44,"Mountain" +PH,45,"Negros Occidental" +PH,46,"Negros Oriental" +PH,47,"Nueva Ecija" +PH,48,"Nueva Vizcaya" +PH,49,"Palawan" +PH,50,"Pampanga" +PH,51,"Pangasinan" +PH,53,"Rizal" +PH,54,"Romblon" +PH,55,"Samar" +PH,56,"Maguindanao" +PH,57,"North Cotabato" +PH,58,"Sorsogon" +PH,59,"Southern Leyte" +PH,60,"Sulu" +PH,61,"Surigao del Norte" +PH,62,"Surigao del Sur" +PH,63,"Tarlac" +PH,64,"Zambales" +PH,65,"Zamboanga del Norte" +PH,66,"Zamboanga del Sur" +PH,67,"Northern Samar" +PH,68,"Quirino" +PH,69,"Siquijor" +PH,70,"South Cotabato" +PH,71,"Sultan Kudarat" +PH,72,"Tawitawi" +PH,A1,"Angeles" +PH,A2,"Bacolod" +PH,A3,"Bago" +PH,A4,"Baguio" +PH,A5,"Bais" +PH,A6,"Basilan City" +PH,A7,"Batangas City" +PH,A8,"Butuan" +PH,A9,"Cabanatuan" +PH,B1,"Cadiz" +PH,B2,"Cagayan de Oro" +PH,B3,"Calbayog" +PH,B4,"Caloocan" +PH,B5,"Canlaon" +PH,B6,"Cavite City" +PH,B7,"Cebu City" +PH,B8,"Cotabato" +PH,B9,"Dagupan" +PH,C1,"Danao" +PH,C2,"Dapitan" +PH,C3,"Davao City" +PH,C4,"Dipolog" +PH,C5,"Dumaguete" +PH,C6,"General Santos" +PH,C7,"Gingoog" +PH,C8,"Iligan" +PH,C9,"Iloilo City" +PH,D1,"Iriga" +PH,D2,"La Carlota" +PH,D3,"Laoag" +PH,D4,"Lapu-Lapu" +PH,D5,"Legaspi" +PH,D6,"Lipa" +PH,D7,"Lucena" +PH,D8,"Mandaue" +PH,D9,"Manila" +PH,E1,"Marawi" +PH,E2,"Naga" +PH,E3,"Olongapo" +PH,E4,"Ormoc" +PH,E5,"Oroquieta" +PH,E6,"Ozamis" +PH,E7,"Pagadian" +PH,E8,"Palayan" +PH,E9,"Pasay" +PH,F1,"Puerto Princesa" +PH,F2,"Quezon City" +PH,F3,"Roxas" +PH,F4,"San Carlos" +PH,F5,"San Carlos" +PH,F6,"San Jose" +PH,F7,"San Pablo" +PH,F8,"Silay" +PH,F9,"Surigao" +PH,G1,"Tacloban" +PH,G2,"Tagaytay" +PH,G3,"Tagbilaran" +PH,G4,"Tangub" +PH,G5,"Toledo" +PH,G6,"Trece Martires" +PH,G7,"Zamboanga" +PH,G8,"Aurora" +PH,H2,"Quezon" +PH,H3,"Negros Occidental" +PH,H9,"Biliran" +PH,I6,"Compostela Valley" +PH,I7,"Davao del Norte" +PH,J3,"Guimaras" +PH,J4,"Himamaylan" +PH,J7,"Kalinga" +PH,K1,"Las Pinas" +PH,K5,"Malabon" +PH,K6,"Malaybalay" +PH,L4,"Muntinlupa" +PH,L5,"Navotas" +PH,L7,"Paranaque" +PH,L9,"Passi" +PH,P1,"Zambales" +PH,M5,"San Jose del Monte" +PH,M6,"San Juan" +PH,M8,"Santiago" +PH,M9,"Sarangani" +PH,N1,"Sipalay" +PH,N3,"Surigao del Norte" +PH,P2,"Zamboanga" +PK,01,"Federally Administered Tribal Areas" +PK,02,"Balochistan" +PK,03,"North-West Frontier" +PK,04,"Punjab" +PK,05,"Sindh" +PK,06,"Azad Kashmir" +PK,07,"Northern Areas" +PK,08,"Islamabad" +PL,72,"Dolnoslaskie" +PL,73,"Kujawsko-Pomorskie" +PL,74,"Lodzkie" +PL,75,"Lubelskie" +PL,76,"Lubuskie" +PL,77,"Malopolskie" +PL,78,"Mazowieckie" +PL,79,"Opolskie" +PL,80,"Podkarpackie" +PL,81,"Podlaskie" +PL,82,"Pomorskie" +PL,83,"Slaskie" +PL,84,"Swietokrzyskie" +PL,85,"Warminsko-Mazurskie" +PL,86,"Wielkopolskie" +PL,87,"Zachodniopomorskie" +PS,GZ,"Gaza" +PS,WE,"West Bank" +PT,02,"Aveiro" +PT,03,"Beja" +PT,04,"Braga" +PT,05,"Braganca" +PT,06,"Castelo Branco" +PT,07,"Coimbra" +PT,08,"Evora" +PT,09,"Faro" +PT,10,"Madeira" +PT,11,"Guarda" +PT,13,"Leiria" +PT,14,"Lisboa" +PT,16,"Portalegre" +PT,17,"Porto" +PT,18,"Santarem" +PT,19,"Setubal" +PT,20,"Viana do Castelo" +PT,21,"Vila Real" +PT,22,"Viseu" +PT,23,"Azores" +PY,01,"Alto Parana" +PY,02,"Amambay" +PY,04,"Caaguazu" +PY,05,"Caazapa" +PY,06,"Central" +PY,07,"Concepcion" +PY,08,"Cordillera" +PY,10,"Guaira" +PY,11,"Itapua" +PY,12,"Misiones" +PY,13,"Neembucu" +PY,15,"Paraguari" +PY,16,"Presidente Hayes" +PY,17,"San Pedro" +PY,19,"Canindeyu" +PY,22,"Asuncion" +PY,23,"Alto Paraguay" +PY,24,"Boqueron" +QA,01,"Ad Dawhah" +QA,02,"Al Ghuwariyah" +QA,03,"Al Jumaliyah" +QA,04,"Al Khawr" +QA,05,"Al Wakrah Municipality" +QA,06,"Ar Rayyan" +QA,08,"Madinat ach Shamal" +QA,09,"Umm Salal" +QA,10,"Al Wakrah" +QA,11,"Jariyan al Batnah" +QA,12,"Umm Sa'id" +RO,01,"Alba" +RO,02,"Arad" +RO,03,"Arges" +RO,04,"Bacau" +RO,05,"Bihor" +RO,06,"Bistrita-Nasaud" +RO,07,"Botosani" +RO,08,"Braila" +RO,09,"Brasov" +RO,10,"Bucuresti" +RO,11,"Buzau" +RO,12,"Caras-Severin" +RO,13,"Cluj" +RO,14,"Constanta" +RO,15,"Covasna" +RO,16,"Dambovita" +RO,17,"Dolj" +RO,18,"Galati" +RO,19,"Gorj" +RO,20,"Harghita" +RO,21,"Hunedoara" +RO,22,"Ialomita" +RO,23,"Iasi" +RO,25,"Maramures" +RO,26,"Mehedinti" +RO,27,"Mures" +RO,28,"Neamt" +RO,29,"Olt" +RO,30,"Prahova" +RO,31,"Salaj" +RO,32,"Satu Mare" +RO,33,"Sibiu" +RO,34,"Suceava" +RO,35,"Teleorman" +RO,36,"Timis" +RO,37,"Tulcea" +RO,38,"Vaslui" +RO,39,"Valcea" +RO,40,"Vrancea" +RO,41,"Calarasi" +RO,42,"Giurgiu" +RO,43,"Ilfov" +RS,01,"Kosovo" +RS,02,"Vojvodina" +RU,01,"Adygeya, Republic of" +RU,02,"Aginsky Buryatsky AO" +RU,03,"Gorno-Altay" +RU,04,"Altaisky krai" +RU,05,"Amur" +RU,06,"Arkhangel'sk" +RU,07,"Astrakhan'" +RU,08,"Bashkortostan" +RU,09,"Belgorod" +RU,10,"Bryansk" +RU,11,"Buryat" +RU,12,"Chechnya" +RU,13,"Chelyabinsk" +RU,14,"Chita" +RU,15,"Chukot" +RU,16,"Chuvashia" +RU,17,"Dagestan" +RU,18,"Evenk" +RU,19,"Ingush" +RU,20,"Irkutsk" +RU,21,"Ivanovo" +RU,22,"Kabardin-Balkar" +RU,23,"Kaliningrad" +RU,24,"Kalmyk" +RU,25,"Kaluga" +RU,26,"Kamchatka" +RU,27,"Karachay-Cherkess" +RU,28,"Karelia" +RU,29,"Kemerovo" +RU,30,"Khabarovsk" +RU,31,"Khakass" +RU,32,"Khanty-Mansiy" +RU,33,"Kirov" +RU,34,"Komi" +RU,36,"Koryak" +RU,37,"Kostroma" +RU,38,"Krasnodar" +RU,39,"Krasnoyarsk" +RU,40,"Kurgan" +RU,41,"Kursk" +RU,42,"Leningrad" +RU,43,"Lipetsk" +RU,44,"Magadan" +RU,45,"Mariy-El" +RU,46,"Mordovia" +RU,47,"Moskva" +RU,48,"Moscow City" +RU,49,"Murmansk" +RU,50,"Nenets" +RU,51,"Nizhegorod" +RU,52,"Novgorod" +RU,53,"Novosibirsk" +RU,54,"Omsk" +RU,55,"Orenburg" +RU,56,"Orel" +RU,57,"Penza" +RU,58,"Perm'" +RU,59,"Primor'ye" +RU,60,"Pskov" +RU,61,"Rostov" +RU,62,"Ryazan'" +RU,63,"Sakha" +RU,64,"Sakhalin" +RU,65,"Samara" +RU,66,"Saint Petersburg City" +RU,67,"Saratov" +RU,68,"North Ossetia" +RU,69,"Smolensk" +RU,70,"Stavropol'" +RU,71,"Sverdlovsk" +RU,72,"Tambovskaya oblast" +RU,73,"Tatarstan" +RU,74,"Taymyr" +RU,75,"Tomsk" +RU,76,"Tula" +RU,77,"Tver'" +RU,78,"Tyumen'" +RU,79,"Tuva" +RU,80,"Udmurt" +RU,81,"Ul'yanovsk" +RU,83,"Vladimir" +RU,84,"Volgograd" +RU,85,"Vologda" +RU,86,"Voronezh" +RU,87,"Yamal-Nenets" +RU,88,"Yaroslavl'" +RU,89,"Yevrey" +RU,90,"Permskiy Kray" +RU,91,"Krasnoyarskiy Kray" +RU,92,"Kamchatskiy Kray" +RU,93,"Zabaykal'skiy Kray" +RW,01,"Butare" +RW,06,"Gitarama" +RW,07,"Kibungo" +RW,09,"Kigali" +RW,11,"Est" +RW,12,"Kigali" +RW,13,"Nord" +RW,14,"Ouest" +RW,15,"Sud" +SA,02,"Al Bahah" +SA,05,"Al Madinah" +SA,06,"Ash Sharqiyah" +SA,08,"Al Qasim" +SA,10,"Ar Riyad" +SA,11,"Asir Province" +SA,13,"Ha'il" +SA,14,"Makkah" +SA,15,"Al Hudud ash Shamaliyah" +SA,16,"Najran" +SA,17,"Jizan" +SA,19,"Tabuk" +SA,20,"Al Jawf" +SB,03,"Malaita" +SB,06,"Guadalcanal" +SB,07,"Isabel" +SB,08,"Makira" +SB,09,"Temotu" +SB,10,"Central" +SB,11,"Western" +SB,12,"Choiseul" +SB,13,"Rennell and Bellona" +SC,01,"Anse aux Pins" +SC,02,"Anse Boileau" +SC,03,"Anse Etoile" +SC,04,"Anse Louis" +SC,05,"Anse Royale" +SC,06,"Baie Lazare" +SC,07,"Baie Sainte Anne" +SC,08,"Beau Vallon" +SC,09,"Bel Air" +SC,10,"Bel Ombre" +SC,11,"Cascade" +SC,12,"Glacis" +SC,13,"Grand' Anse" +SC,14,"Grand' Anse" +SC,15,"La Digue" +SC,16,"La Riviere Anglaise" +SC,17,"Mont Buxton" +SC,18,"Mont Fleuri" +SC,19,"Plaisance" +SC,20,"Pointe La Rue" +SC,21,"Port Glaud" +SC,22,"Saint Louis" +SC,23,"Takamaka" +SD,27,"Al Wusta" +SD,28,"Al Istiwa'iyah" +SD,29,"Al Khartum" +SD,30,"Ash Shamaliyah" +SD,31,"Ash Sharqiyah" +SD,32,"Bahr al Ghazal" +SD,33,"Darfur" +SD,34,"Kurdufan" +SD,35,"Upper Nile" +SD,40,"Al Wahadah State" +SD,44,"Central Equatoria State" +SD,49,"Southern Darfur" +SD,50,"Southern Kordofan" +SD,52,"Kassala" +SD,53,"River Nile" +SD,55,"Northern Darfur" +SE,02,"Blekinge Lan" +SE,03,"Gavleborgs Lan" +SE,05,"Gotlands Lan" +SE,06,"Hallands Lan" +SE,07,"Jamtlands Lan" +SE,08,"Jonkopings Lan" +SE,09,"Kalmar Lan" +SE,10,"Dalarnas Lan" +SE,12,"Kronobergs Lan" +SE,14,"Norrbottens Lan" +SE,15,"Orebro Lan" +SE,16,"Ostergotlands Lan" +SE,18,"Sodermanlands Lan" +SE,21,"Uppsala Lan" +SE,22,"Varmlands Lan" +SE,23,"Vasterbottens Lan" +SE,24,"Vasternorrlands Lan" +SE,25,"Vastmanlands Lan" +SE,26,"Stockholms Lan" +SE,27,"Skane Lan" +SE,28,"Vastra Gotaland" +SH,01,"Ascension" +SH,02,"Saint Helena" +SH,03,"Tristan da Cunha" +SI,01,"Ajdovscina Commune" +SI,02,"Beltinci Commune" +SI,03,"Bled Commune" +SI,04,"Bohinj Commune" +SI,05,"Borovnica Commune" +SI,06,"Bovec Commune" +SI,07,"Brda Commune" +SI,08,"Brezice Commune" +SI,09,"Brezovica Commune" +SI,11,"Celje Commune" +SI,12,"Cerklje na Gorenjskem Commune" +SI,13,"Cerknica Commune" +SI,14,"Cerkno Commune" +SI,15,"Crensovci Commune" +SI,16,"Crna na Koroskem Commune" +SI,17,"Crnomelj Commune" +SI,19,"Divaca Commune" +SI,20,"Dobrepolje Commune" +SI,22,"Dol pri Ljubljani Commune" +SI,24,"Dornava Commune" +SI,25,"Dravograd Commune" +SI,26,"Duplek Commune" +SI,27,"Gorenja vas-Poljane Commune" +SI,28,"Gorisnica Commune" +SI,29,"Gornja Radgona Commune" +SI,30,"Gornji Grad Commune" +SI,31,"Gornji Petrovci Commune" +SI,32,"Grosuplje Commune" +SI,34,"Hrastnik Commune" +SI,35,"Hrpelje-Kozina Commune" +SI,36,"Idrija Commune" +SI,37,"Ig Commune" +SI,38,"Ilirska Bistrica Commune" +SI,39,"Ivancna Gorica Commune" +SI,40,"Izola-Isola Commune" +SI,42,"Jursinci Commune" +SI,44,"Kanal Commune" +SI,45,"Kidricevo Commune" +SI,46,"Kobarid Commune" +SI,47,"Kobilje Commune" +SI,49,"Komen Commune" +SI,50,"Koper-Capodistria Urban Commune" +SI,51,"Kozje Commune" +SI,52,"Kranj Commune" +SI,53,"Kranjska Gora Commune" +SI,54,"Krsko Commune" +SI,55,"Kungota Commune" +SI,57,"Lasko Commune" +SI,61,"Ljubljana Urban Commune" +SI,62,"Ljubno Commune" +SI,64,"Logatec Commune" +SI,66,"Loski Potok Commune" +SI,68,"Lukovica Commune" +SI,71,"Medvode Commune" +SI,72,"Menges Commune" +SI,73,"Metlika Commune" +SI,74,"Mezica Commune" +SI,76,"Mislinja Commune" +SI,77,"Moravce Commune" +SI,78,"Moravske Toplice Commune" +SI,79,"Mozirje Commune" +SI,80,"Murska Sobota Urban Commune" +SI,81,"Muta Commune" +SI,82,"Naklo Commune" +SI,83,"Nazarje Commune" +SI,84,"Nova Gorica Urban Commune" +SI,86,"Odranci Commune" +SI,87,"Ormoz Commune" +SI,88,"Osilnica Commune" +SI,89,"Pesnica Commune" +SI,91,"Pivka Commune" +SI,92,"Podcetrtek Commune" +SI,94,"Postojna Commune" +SI,97,"Puconci Commune" +SI,98,"Race-Fram Commune" +SI,99,"Radece Commune" +SI,A1,"Radenci Commune" +SI,A2,"Radlje ob Dravi Commune" +SI,A3,"Radovljica Commune" +SI,A6,"Rogasovci Commune" +SI,A7,"Rogaska Slatina Commune" +SI,A8,"Rogatec Commune" +SI,B1,"Semic Commune" +SI,B2,"Sencur Commune" +SI,B3,"Sentilj Commune" +SI,B4,"Sentjernej Commune" +SI,B6,"Sevnica Commune" +SI,B7,"Sezana Commune" +SI,B8,"Skocjan Commune" +SI,B9,"Skofja Loka Commune" +SI,C1,"Skofljica Commune" +SI,C2,"Slovenj Gradec Urban Commune" +SI,C4,"Slovenske Konjice Commune" +SI,C5,"Smarje pri Jelsah Commune" +SI,C6,"Smartno ob Paki Commune" +SI,C7,"Sostanj Commune" +SI,C8,"Starse Commune" +SI,C9,"Store Commune" +SI,D1,"Sveti Jurij Commune" +SI,D2,"Tolmin Commune" +SI,D3,"Trbovlje Commune" +SI,D4,"Trebnje Commune" +SI,D5,"Trzic Commune" +SI,D6,"Turnisce Commune" +SI,D7,"Velenje Urban Commune" +SI,D8,"Velike Lasce Commune" +SI,E1,"Vipava Commune" +SI,E2,"Vitanje Commune" +SI,E3,"Vodice Commune" +SI,E5,"Vrhnika Commune" +SI,E6,"Vuzenica Commune" +SI,E7,"Zagorje ob Savi Commune" +SI,E9,"Zavrc Commune" +SI,F1,"Zelezniki Commune" +SI,F2,"Ziri Commune" +SI,F3,"Zrece Commune" +SI,F4,"Benedikt Commune" +SI,F5,"Bistrica ob Sotli Commune" +SI,F6,"Bloke Commune" +SI,F7,"Braslovce Commune" +SI,F8,"Cankova Commune" +SI,F9,"Cerkvenjak Commune" +SI,G1,"Destrnik Commune" +SI,G2,"Dobje Commune" +SI,G3,"Dobrna Commune" +SI,G4,"Dobrova-Horjul-Polhov Gradec Commune" +SI,G5,"Dobrovnik-Dobronak Commune" +SI,G6,"Dolenjske Toplice Commune" +SI,G7,"Domzale Commune" +SI,G8,"Grad Commune" +SI,G9,"Hajdina Commune" +SI,H1,"Hoce-Slivnica Commune" +SI,H2,"Hodos-Hodos Commune" +SI,H3,"Horjul Commune" +SI,H4,"Jesenice Commune" +SI,H5,"Jezersko Commune" +SI,H6,"Kamnik Commune" +SI,H7,"Kocevje Commune" +SI,H8,"Komenda Commune" +SI,H9,"Kostel Commune" +SI,I1,"Krizevci Commune" +SI,I2,"Kuzma Commune" +SI,I3,"Lenart Commune" +SI,I4,"Lendava-Lendva Commune" +SI,I5,"Litija Commune" +SI,I6,"Ljutomer Commune" +SI,I7,"Loska Dolina Commune" +SI,I8,"Lovrenc na Pohorju Commune" +SI,I9,"Luce Commune" +SI,J1,"Majsperk Commune" +SI,J2,"Maribor Commune" +SI,J3,"Markovci Commune" +SI,J4,"Miklavz na Dravskem polju Commune" +SI,J5,"Miren-Kostanjevica Commune" +SI,J6,"Mirna Pec Commune" +SI,J7,"Novo mesto Urban Commune" +SI,J8,"Oplotnica Commune" +SI,J9,"Piran-Pirano Commune" +SI,K1,"Podlehnik Commune" +SI,K2,"Podvelka Commune" +SI,K3,"Polzela Commune" +SI,K4,"Prebold Commune" +SI,K5,"Preddvor Commune" +SI,K6,"Prevalje Commune" +SI,K7,"Ptuj Urban Commune" +SI,K8,"Ravne na Koroskem Commune" +SI,K9,"Razkrizje Commune" +SI,L1,"Ribnica Commune" +SI,L2,"Ribnica na Pohorju Commune" +SI,L3,"Ruse Commune" +SI,L4,"Salovci Commune" +SI,L5,"Selnica ob Dravi Commune" +SI,L6,"Sempeter-Vrtojba Commune" +SI,L7,"Sentjur pri Celju Commune" +SI,L8,"Slovenska Bistrica Commune" +SI,L9,"Smartno pri Litiji Commune" +SI,M1,"Sodrazica Commune" +SI,M2,"Solcava Commune" +SI,M3,"Sveta Ana Commune" +SI,M4,"Sveti Andraz v Slovenskih goricah Commune" +SI,M5,"Tabor Commune" +SI,M6,"Tisina Commune" +SI,M7,"Trnovska vas Commune" +SI,M8,"Trzin Commune" +SI,M9,"Velika Polana Commune" +SI,N1,"Verzej Commune" +SI,N2,"Videm Commune" +SI,N3,"Vojnik Commune" +SI,N4,"Vransko Commune" +SI,N5,"Zalec Commune" +SI,N6,"Zetale Commune" +SI,N7,"Zirovnica Commune" +SI,N8,"Zuzemberk Commune" +SI,N9,"Apace Commune" +SI,O1,"Cirkulane Commune" +SI,O2,"Gorje" +SI,O3,"Kostanjevica na Krki" +SI,O4,"Log-Dragomer" +SI,O5,"Makole" +SI,O6,"Mirna" +SI,O7,"Mokronog-Trebelno" +SI,O8,"Poljcane" +SI,O9,"Recica ob Savinji" +SI,P1,"Rence-Vogrsko" +SI,P2,"Sentrupert" +SI,P3,"Smarjesk Toplice" +SI,P4,"Sredisce ob Dravi" +SI,P5,"Straza" +SI,P7,"Sveti Jurij v Slovenskih Goricah" +SK,01,"Banska Bystrica" +SK,02,"Bratislava" +SK,03,"Kosice" +SK,04,"Nitra" +SK,05,"Presov" +SK,06,"Trencin" +SK,07,"Trnava" +SK,08,"Zilina" +SL,01,"Eastern" +SL,02,"Northern" +SL,03,"Southern" +SL,04,"Western Area" +SM,01,"Acquaviva" +SM,02,"Chiesanuova" +SM,03,"Domagnano" +SM,04,"Faetano" +SM,05,"Fiorentino" +SM,06,"Borgo Maggiore" +SM,07,"San Marino" +SM,08,"Monte Giardino" +SM,09,"Serravalle" +SN,01,"Dakar" +SN,03,"Diourbel" +SN,05,"Tambacounda" +SN,07,"Thies" +SN,09,"Fatick" +SN,10,"Kaolack" +SN,11,"Kolda" +SN,12,"Ziguinchor" +SN,13,"Louga" +SN,14,"Saint-Louis" +SN,15,"Matam" +SO,01,"Bakool" +SO,02,"Banaadir" +SO,03,"Bari" +SO,04,"Bay" +SO,05,"Galguduud" +SO,06,"Gedo" +SO,07,"Hiiraan" +SO,08,"Jubbada Dhexe" +SO,09,"Jubbada Hoose" +SO,10,"Mudug" +SO,11,"Nugaal" +SO,12,"Sanaag" +SO,13,"Shabeellaha Dhexe" +SO,14,"Shabeellaha Hoose" +SO,16,"Woqooyi Galbeed" +SO,18,"Nugaal" +SO,19,"Togdheer" +SO,20,"Woqooyi Galbeed" +SO,21,"Awdal" +SO,22,"Sool" +SR,10,"Brokopondo" +SR,11,"Commewijne" +SR,12,"Coronie" +SR,13,"Marowijne" +SR,14,"Nickerie" +SR,15,"Para" +SR,16,"Paramaribo" +SR,17,"Saramacca" +SR,18,"Sipaliwini" +SR,19,"Wanica" +SS,01,"Central Equatoria" +SS,02,"Eastern Equatoria" +SS,03,"Jonglei" +SS,04,"Lakes" +SS,05,"Northern Bahr el Ghazal" +SS,06,"Unity" +SS,07,"Upper Nile" +SS,08,"Warrap" +SS,09,"Western Bahr el Ghazal" +SS,10,"Western Equatoria" +ST,01,"Principe" +ST,02,"Sao Tome" +SV,01,"Ahuachapan" +SV,02,"Cabanas" +SV,03,"Chalatenango" +SV,04,"Cuscatlan" +SV,05,"La Libertad" +SV,06,"La Paz" +SV,07,"La Union" +SV,08,"Morazan" +SV,09,"San Miguel" +SV,10,"San Salvador" +SV,11,"Santa Ana" +SV,12,"San Vicente" +SV,13,"Sonsonate" +SV,14,"Usulutan" +SY,01,"Al Hasakah" +SY,02,"Al Ladhiqiyah" +SY,03,"Al Qunaytirah" +SY,04,"Ar Raqqah" +SY,05,"As Suwayda'" +SY,06,"Dar" +SY,07,"Dayr az Zawr" +SY,08,"Rif Dimashq" +SY,09,"Halab" +SY,10,"Hamah" +SY,11,"Hims" +SY,12,"Idlib" +SY,13,"Dimashq" +SY,14,"Tartus" +SZ,01,"Hhohho" +SZ,02,"Lubombo" +SZ,03,"Manzini" +SZ,04,"Shiselweni" +SZ,05,"Praslin" +TD,01,"Batha" +TD,02,"Biltine" +TD,03,"Borkou-Ennedi-Tibesti" +TD,04,"Chari-Baguirmi" +TD,05,"Guera" +TD,06,"Kanem" +TD,07,"Lac" +TD,08,"Logone Occidental" +TD,09,"Logone Oriental" +TD,10,"Mayo-Kebbi" +TD,11,"Moyen-Chari" +TD,12,"Ouaddai" +TD,13,"Salamat" +TD,14,"Tandjile" +TG,22,"Centrale" +TG,23,"Kara" +TG,24,"Maritime" +TG,25,"Plateaux" +TG,26,"Savanes" +TH,01,"Mae Hong Son" +TH,02,"Chiang Mai" +TH,03,"Chiang Rai" +TH,04,"Nan" +TH,05,"Lamphun" +TH,06,"Lampang" +TH,07,"Phrae" +TH,08,"Tak" +TH,09,"Sukhothai" +TH,10,"Uttaradit" +TH,11,"Kamphaeng Phet" +TH,12,"Phitsanulok" +TH,13,"Phichit" +TH,14,"Phetchabun" +TH,15,"Uthai Thani" +TH,16,"Nakhon Sawan" +TH,17,"Nong Khai" +TH,18,"Loei" +TH,20,"Sakon Nakhon" +TH,21,"Nakhon Phanom" +TH,22,"Khon Kaen" +TH,23,"Kalasin" +TH,24,"Maha Sarakham" +TH,25,"Roi Et" +TH,26,"Chaiyaphum" +TH,27,"Nakhon Ratchasima" +TH,28,"Buriram" +TH,29,"Surin" +TH,30,"Sisaket" +TH,31,"Narathiwat" +TH,32,"Chai Nat" +TH,33,"Sing Buri" +TH,34,"Lop Buri" +TH,35,"Ang Thong" +TH,36,"Phra Nakhon Si Ayutthaya" +TH,37,"Saraburi" +TH,38,"Nonthaburi" +TH,39,"Pathum Thani" +TH,40,"Krung Thep" +TH,41,"Phayao" +TH,42,"Samut Prakan" +TH,43,"Nakhon Nayok" +TH,44,"Chachoengsao" +TH,45,"Prachin Buri" +TH,46,"Chon Buri" +TH,47,"Rayong" +TH,48,"Chanthaburi" +TH,49,"Trat" +TH,50,"Kanchanaburi" +TH,51,"Suphan Buri" +TH,52,"Ratchaburi" +TH,53,"Nakhon Pathom" +TH,54,"Samut Songkhram" +TH,55,"Samut Sakhon" +TH,56,"Phetchaburi" +TH,57,"Prachuap Khiri Khan" +TH,58,"Chumphon" +TH,59,"Ranong" +TH,60,"Surat Thani" +TH,61,"Phangnga" +TH,62,"Phuket" +TH,63,"Krabi" +TH,64,"Nakhon Si Thammarat" +TH,65,"Trang" +TH,66,"Phatthalung" +TH,67,"Satun" +TH,68,"Songkhla" +TH,69,"Pattani" +TH,70,"Yala" +TH,71,"Ubon Ratchathani" +TH,72,"Yasothon" +TH,73,"Nakhon Phanom" +TH,74,"Prachin Buri" +TH,75,"Ubon Ratchathani" +TH,76,"Udon Thani" +TH,77,"Amnat Charoen" +TH,78,"Mukdahan" +TH,79,"Nong Bua Lamphu" +TH,80,"Sa Kaeo" +TH,81,"Bueng Kan" +TJ,01,"Kuhistoni Badakhshon" +TJ,02,"Khatlon" +TJ,03,"Sughd" +TJ,04,"Dushanbe" +TJ,05,"Nohiyahoi Tobei Jumhuri" +TL,06,"Dili" +TM,01,"Ahal" +TM,02,"Balkan" +TM,03,"Dashoguz" +TM,04,"Lebap" +TM,05,"Mary" +TN,02,"Kasserine" +TN,03,"Kairouan" +TN,06,"Jendouba" +TN,10,"Qafsah" +TN,14,"El Kef" +TN,15,"Al Mahdia" +TN,16,"Al Munastir" +TN,17,"Bajah" +TN,18,"Bizerte" +TN,19,"Nabeul" +TN,22,"Siliana" +TN,23,"Sousse" +TN,27,"Ben Arous" +TN,28,"Madanin" +TN,29,"Gabes" +TN,31,"Kebili" +TN,32,"Sfax" +TN,33,"Sidi Bou Zid" +TN,34,"Tataouine" +TN,35,"Tozeur" +TN,36,"Tunis" +TN,37,"Zaghouan" +TN,38,"Aiana" +TN,39,"Manouba" +TO,01,"Ha" +TO,02,"Tongatapu" +TO,03,"Vava" +TR,02,"Adiyaman" +TR,03,"Afyonkarahisar" +TR,04,"Agri" +TR,05,"Amasya" +TR,07,"Antalya" +TR,08,"Artvin" +TR,09,"Aydin" +TR,10,"Balikesir" +TR,11,"Bilecik" +TR,12,"Bingol" +TR,13,"Bitlis" +TR,14,"Bolu" +TR,15,"Burdur" +TR,16,"Bursa" +TR,17,"Canakkale" +TR,19,"Corum" +TR,20,"Denizli" +TR,21,"Diyarbakir" +TR,22,"Edirne" +TR,23,"Elazig" +TR,24,"Erzincan" +TR,25,"Erzurum" +TR,26,"Eskisehir" +TR,28,"Giresun" +TR,31,"Hatay" +TR,32,"Mersin" +TR,33,"Isparta" +TR,34,"Istanbul" +TR,35,"Izmir" +TR,37,"Kastamonu" +TR,38,"Kayseri" +TR,39,"Kirklareli" +TR,40,"Kirsehir" +TR,41,"Kocaeli" +TR,43,"Kutahya" +TR,44,"Malatya" +TR,45,"Manisa" +TR,46,"Kahramanmaras" +TR,48,"Mugla" +TR,49,"Mus" +TR,50,"Nevsehir" +TR,52,"Ordu" +TR,53,"Rize" +TR,54,"Sakarya" +TR,55,"Samsun" +TR,57,"Sinop" +TR,58,"Sivas" +TR,59,"Tekirdag" +TR,60,"Tokat" +TR,61,"Trabzon" +TR,62,"Tunceli" +TR,63,"Sanliurfa" +TR,64,"Usak" +TR,65,"Van" +TR,66,"Yozgat" +TR,68,"Ankara" +TR,69,"Gumushane" +TR,70,"Hakkari" +TR,71,"Konya" +TR,72,"Mardin" +TR,73,"Nigde" +TR,74,"Siirt" +TR,75,"Aksaray" +TR,76,"Batman" +TR,77,"Bayburt" +TR,78,"Karaman" +TR,79,"Kirikkale" +TR,80,"Sirnak" +TR,81,"Adana" +TR,82,"Cankiri" +TR,83,"Gaziantep" +TR,84,"Kars" +TR,85,"Zonguldak" +TR,86,"Ardahan" +TR,87,"Bartin" +TR,88,"Igdir" +TR,89,"Karabuk" +TR,90,"Kilis" +TR,91,"Osmaniye" +TR,92,"Yalova" +TR,93,"Duzce" +TT,01,"Arima" +TT,02,"Caroni" +TT,03,"Mayaro" +TT,04,"Nariva" +TT,05,"Port-of-Spain" +TT,06,"Saint Andrew" +TT,07,"Saint David" +TT,08,"Saint George" +TT,09,"Saint Patrick" +TT,10,"San Fernando" +TT,11,"Tobago" +TT,12,"Victoria" +TW,01,"Fu-chien" +TW,02,"Kao-hsiung" +TW,03,"T'ai-pei" +TW,04,"T'ai-wan" +TZ,02,"Pwani" +TZ,03,"Dodoma" +TZ,04,"Iringa" +TZ,05,"Kigoma" +TZ,06,"Kilimanjaro" +TZ,07,"Lindi" +TZ,08,"Mara" +TZ,09,"Mbeya" +TZ,10,"Morogoro" +TZ,11,"Mtwara" +TZ,12,"Mwanza" +TZ,13,"Pemba North" +TZ,14,"Ruvuma" +TZ,15,"Shinyanga" +TZ,16,"Singida" +TZ,17,"Tabora" +TZ,18,"Tanga" +TZ,19,"Kagera" +TZ,20,"Pemba South" +TZ,21,"Zanzibar Central" +TZ,22,"Zanzibar North" +TZ,23,"Dar es Salaam" +TZ,24,"Rukwa" +TZ,25,"Zanzibar Urban" +TZ,26,"Arusha" +TZ,27,"Manyara" +UA,01,"Cherkas'ka Oblast'" +UA,02,"Chernihivs'ka Oblast'" +UA,03,"Chernivets'ka Oblast'" +UA,04,"Dnipropetrovs'ka Oblast'" +UA,05,"Donets'ka Oblast'" +UA,06,"Ivano-Frankivs'ka Oblast'" +UA,07,"Kharkivs'ka Oblast'" +UA,08,"Khersons'ka Oblast'" +UA,09,"Khmel'nyts'ka Oblast'" +UA,10,"Kirovohrads'ka Oblast'" +UA,11,"Krym" +UA,12,"Kyyiv" +UA,13,"Kyyivs'ka Oblast'" +UA,14,"Luhans'ka Oblast'" +UA,15,"L'vivs'ka Oblast'" +UA,16,"Mykolayivs'ka Oblast'" +UA,17,"Odes'ka Oblast'" +UA,18,"Poltavs'ka Oblast'" +UA,19,"Rivnens'ka Oblast'" +UA,20,"Sevastopol'" +UA,21,"Sums'ka Oblast'" +UA,22,"Ternopil's'ka Oblast'" +UA,23,"Vinnyts'ka Oblast'" +UA,24,"Volyns'ka Oblast'" +UA,25,"Zakarpats'ka Oblast'" +UA,26,"Zaporiz'ka Oblast'" +UA,27,"Zhytomyrs'ka Oblast'" +UG,26,"Apac" +UG,28,"Bundibugyo" +UG,29,"Bushenyi" +UG,30,"Gulu" +UG,31,"Hoima" +UG,33,"Jinja" +UG,36,"Kalangala" +UG,37,"Kampala" +UG,38,"Kamuli" +UG,39,"Kapchorwa" +UG,40,"Kasese" +UG,41,"Kibale" +UG,42,"Kiboga" +UG,43,"Kisoro" +UG,45,"Kotido" +UG,46,"Kumi" +UG,47,"Lira" +UG,50,"Masindi" +UG,52,"Mbarara" +UG,56,"Mubende" +UG,58,"Nebbi" +UG,59,"Ntungamo" +UG,60,"Pallisa" +UG,61,"Rakai" +UG,65,"Adjumani" +UG,66,"Bugiri" +UG,67,"Busia" +UG,69,"Katakwi" +UG,70,"Luwero" +UG,71,"Masaka" +UG,72,"Moyo" +UG,73,"Nakasongola" +UG,74,"Sembabule" +UG,76,"Tororo" +UG,77,"Arua" +UG,78,"Iganga" +UG,79,"Kabarole" +UG,80,"Kaberamaido" +UG,81,"Kamwenge" +UG,82,"Kanungu" +UG,83,"Kayunga" +UG,84,"Kitgum" +UG,85,"Kyenjojo" +UG,86,"Mayuge" +UG,87,"Mbale" +UG,88,"Moroto" +UG,89,"Mpigi" +UG,90,"Mukono" +UG,91,"Nakapiripirit" +UG,92,"Pader" +UG,93,"Rukungiri" +UG,94,"Sironko" +UG,95,"Soroti" +UG,96,"Wakiso" +UG,97,"Yumbe" +US,AA,"Armed Forces Americas" +US,AE,"Armed Forces Europe, Middle East, & Canada" +US,AK,"Alaska" +US,AL,"Alabama" +US,AP,"Armed Forces Pacific" +US,AR,"Arkansas" +US,AS,"American Samoa" +US,AZ,"Arizona" +US,CA,"California" +US,CO,"Colorado" +US,CT,"Connecticut" +US,DC,"District of Columbia" +US,DE,"Delaware" +US,FL,"Florida" +US,FM,"Federated States of Micronesia" +US,GA,"Georgia" +US,GU,"Guam" +US,HI,"Hawaii" +US,IA,"Iowa" +US,ID,"Idaho" +US,IL,"Illinois" +US,IN,"Indiana" +US,KS,"Kansas" +US,KY,"Kentucky" +US,LA,"Louisiana" +US,MA,"Massachusetts" +US,MD,"Maryland" +US,ME,"Maine" +US,MH,"Marshall Islands" +US,MI,"Michigan" +US,MN,"Minnesota" +US,MO,"Missouri" +US,MP,"Northern Mariana Islands" +US,MS,"Mississippi" +US,MT,"Montana" +US,NC,"North Carolina" +US,ND,"North Dakota" +US,NE,"Nebraska" +US,NH,"New Hampshire" +US,NJ,"New Jersey" +US,NM,"New Mexico" +US,NV,"Nevada" +US,NY,"New York" +US,OH,"Ohio" +US,OK,"Oklahoma" +US,OR,"Oregon" +US,PA,"Pennsylvania" +US,PW,"Palau" +US,RI,"Rhode Island" +US,SC,"South Carolina" +US,SD,"South Dakota" +US,TN,"Tennessee" +US,TX,"Texas" +US,UT,"Utah" +US,VA,"Virginia" +US,VI,"Virgin Islands" +US,VT,"Vermont" +US,WA,"Washington" +US,WI,"Wisconsin" +US,WV,"West Virginia" +US,WY,"Wyoming" +UY,01,"Artigas" +UY,02,"Canelones" +UY,03,"Cerro Largo" +UY,04,"Colonia" +UY,05,"Durazno" +UY,06,"Flores" +UY,07,"Florida" +UY,08,"Lavalleja" +UY,09,"Maldonado" +UY,10,"Montevideo" +UY,11,"Paysandu" +UY,12,"Rio Negro" +UY,13,"Rivera" +UY,14,"Rocha" +UY,15,"Salto" +UY,16,"San Jose" +UY,17,"Soriano" +UY,18,"Tacuarembo" +UY,19,"Treinta y Tres" +UZ,01,"Andijon" +UZ,02,"Bukhoro" +UZ,03,"Farghona" +UZ,04,"Jizzakh" +UZ,05,"Khorazm" +UZ,06,"Namangan" +UZ,07,"Nawoiy" +UZ,08,"Qashqadaryo" +UZ,09,"Qoraqalpoghiston" +UZ,10,"Samarqand" +UZ,11,"Sirdaryo" +UZ,12,"Surkhondaryo" +UZ,13,"Toshkent" +UZ,14,"Toshkent" +UZ,15,"Jizzax" +VC,01,"Charlotte" +VC,02,"Saint Andrew" +VC,03,"Saint David" +VC,04,"Saint George" +VC,05,"Saint Patrick" +VC,06,"Grenadines" +VE,01,"Amazonas" +VE,02,"Anzoategui" +VE,03,"Apure" +VE,04,"Aragua" +VE,05,"Barinas" +VE,06,"Bolivar" +VE,07,"Carabobo" +VE,08,"Cojedes" +VE,09,"Delta Amacuro" +VE,11,"Falcon" +VE,12,"Guarico" +VE,13,"Lara" +VE,14,"Merida" +VE,15,"Miranda" +VE,16,"Monagas" +VE,17,"Nueva Esparta" +VE,18,"Portuguesa" +VE,19,"Sucre" +VE,20,"Tachira" +VE,21,"Trujillo" +VE,22,"Yaracuy" +VE,23,"Zulia" +VE,24,"Dependencias Federales" +VE,25,"Distrito Federal" +VE,26,"Vargas" +VN,01,"An Giang" +VN,03,"Ben Tre" +VN,05,"Cao Bang" +VN,09,"Dong Thap" +VN,13,"Hai Phong" +VN,20,"Ho Chi Minh" +VN,21,"Kien Giang" +VN,23,"Lam Dong" +VN,24,"Long An" +VN,30,"Quang Ninh" +VN,32,"Son La" +VN,33,"Tay Ninh" +VN,34,"Thanh Hoa" +VN,35,"Thai Binh" +VN,37,"Tien Giang" +VN,39,"Lang Son" +VN,43,"Dong Nai" +VN,44,"Ha Noi" +VN,45,"Ba Ria-Vung Tau" +VN,46,"Binh Dinh" +VN,47,"Binh Thuan" +VN,49,"Gia Lai" +VN,50,"Ha Giang" +VN,52,"Ha Tinh" +VN,53,"Hoa Binh" +VN,54,"Khanh Hoa" +VN,55,"Kon Tum" +VN,58,"Nghe An" +VN,59,"Ninh Binh" +VN,60,"Ninh Thuan" +VN,61,"Phu Yen" +VN,62,"Quang Binh" +VN,63,"Quang Ngai" +VN,64,"Quang Tri" +VN,65,"Soc Trang" +VN,66,"Thua Thien-Hue" +VN,67,"Tra Vinh" +VN,68,"Tuyen Quang" +VN,69,"Vinh Long" +VN,70,"Yen Bai" +VN,71,"Bac Giang" +VN,72,"Bac Kan" +VN,73,"Bac Lieu" +VN,74,"Bac Ninh" +VN,75,"Binh Duong" +VN,76,"Binh Phuoc" +VN,77,"Ca Mau" +VN,78,"Da Nang" +VN,79,"Hai Duong" +VN,80,"Ha Nam" +VN,81,"Hung Yen" +VN,82,"Nam Dinh" +VN,83,"Phu Tho" +VN,84,"Quang Nam" +VN,85,"Thai Nguyen" +VN,86,"Vinh Phuc" +VN,87,"Can Tho" +VN,88,"Dac Lak" +VN,89,"Lai Chau" +VN,90,"Lao Cai" +VN,91,"Dak Nong" +VN,92,"Dien Bien" +VN,93,"Hau Giang" +VU,05,"Ambrym" +VU,06,"Aoba" +VU,07,"Torba" +VU,08,"Efate" +VU,09,"Epi" +VU,10,"Malakula" +VU,11,"Paama" +VU,12,"Pentecote" +VU,13,"Sanma" +VU,14,"Shepherd" +VU,15,"Tafea" +VU,16,"Malampa" +VU,17,"Penama" +VU,18,"Shefa" +WS,02,"Aiga-i-le-Tai" +WS,03,"Atua" +WS,04,"Fa" +WS,05,"Gaga" +WS,06,"Va" +WS,07,"Gagaifomauga" +WS,08,"Palauli" +WS,09,"Satupa" +WS,10,"Tuamasaga" +WS,11,"Vaisigano" +YE,01,"Abyan" +YE,02,"Adan" +YE,03,"Al Mahrah" +YE,04,"Hadramawt" +YE,05,"Shabwah" +YE,06,"Lahij" +YE,07,"Al Bayda'" +YE,08,"Al Hudaydah" +YE,09,"Al Jawf" +YE,10,"Al Mahwit" +YE,11,"Dhamar" +YE,12,"Hajjah" +YE,13,"Ibb" +YE,14,"Ma'rib" +YE,15,"Sa'dah" +YE,16,"San'a'" +YE,17,"Taizz" +YE,18,"Ad Dali" +YE,19,"Amran" +YE,20,"Al Bayda'" +YE,21,"Al Jawf" +YE,22,"Hajjah" +YE,23,"Ibb" +YE,24,"Lahij" +YE,25,"Taizz" +ZA,01,"North-Western Province" +ZA,02,"KwaZulu-Natal" +ZA,03,"Free State" +ZA,05,"Eastern Cape" +ZA,06,"Gauteng" +ZA,07,"Mpumalanga" +ZA,08,"Northern Cape" +ZA,09,"Limpopo" +ZA,10,"North-West" +ZA,11,"Western Cape" +ZM,01,"Western" +ZM,02,"Central" +ZM,03,"Eastern" +ZM,04,"Luapula" +ZM,05,"Northern" +ZM,06,"North-Western" +ZM,07,"Southern" +ZM,08,"Copperbelt" +ZM,09,"Lusaka" +ZW,01,"Manicaland" +ZW,02,"Midlands" +ZW,03,"Mashonaland Central" +ZW,04,"Mashonaland East" +ZW,05,"Mashonaland West" +ZW,06,"Matabeleland North" +ZW,07,"Matabeleland South" +ZW,08,"Masvingo" +ZW,09,"Bulawayo" +ZW,10,"Harare" diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..8c38178 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,38 @@ +check_PROGRAMS = test-geoip test-geoip-invalid-file + +noinst_PROGRAMS = benchmark test-geoip-region test-geoip-city test-geoip-org test-geoip-domain test-geoip-asnum test-geoip-isp test-geoip-netspeed + +EXTRA_PROGRAMS = benchmark \ + test-geoip-region \ + test-geoip-city \ + test-geoip-org \ + test-geoip-domain \ + test-geoip-asnum \ + test-geoip-isp \ + test-geoip-netspeed + +LDADD = $(top_builddir)/libGeoIP/libGeoIP.la +AM_CPPFLAGS = -I$(top_srcdir)/libGeoIP -DSRCDIR=\"$(top_srcdir)\" -Wall + +test_geoip_SOURCES = test-geoip.c + +test_geoip_invalid_file_SOURCES = test-geoip-invalid-file.c + +test_geoip_region_SOURCES = test-geoip-region.c + +test_geoip_org_SOURCES = test-geoip-org.c + +test_geoip_domain_SOURCES = test-geoip-domain.c + +test_geoip_isp_SOURCES = test-geoip-isp.c + +test_geoip_asnum_SOURCES = test-geoip-asnum.c + +test_geoip_netspeed_SOURCES = test-geoip-netspeed.c + +test_geoip_city_SOURCES = test-geoip-city.c + +benchmark_SOURCES = benchmark.c + +EXTRA_DIST = Makefile.vc city_test.txt country_test.txt country_test2.txt country_test_name.txt region_test.txt +TESTS = test-geoip test-geoip-invalid-file diff --git a/test/Makefile.vc b/test/Makefile.vc new file mode 100644 index 0000000..db80c10 --- /dev/null +++ b/test/Makefile.vc @@ -0,0 +1,29 @@ +#NMAKE makefile for Windows developers. +#Produces a static library (GeoIP.lib). + +COMPILER=cl + +LINK = link -nologo + +CFLAGS=-DWIN32 -MD -nologo + +GEOIPINC = -I..\libGeoIP + +CC1 = $(COMPILER) $(CFLAGS) $(GEOIPINC) -DSRCDIR=\"../\" + +GEOIPLIB = ..\libGeoIP\GeoIP.lib + +EXTRA_LIBS= advapi32.lib wsock32.lib + +AR=lib + +TEST: benchmark.exe test-geoip.exe + +benchmark.exe: benchmark.c + $(CC1) -c benchmark.c + $(LINK) benchmark.obj $(GEOIPLIB) + +test-geoip.exe: test-geoip.c + $(CC1) -c test-geoip.c + $(LINK) test-geoip.obj $(GEOIPLIB) + diff --git a/test/benchmark.c b/test/benchmark.c new file mode 100644 index 0000000..2d7925a --- /dev/null +++ b/test/benchmark.c @@ -0,0 +1,183 @@ +#include "GeoIP.h" +#include "GeoIPCity.h" +#include +#if !defined(_MSC_VER) +#include +#endif + +char *ipstring[4] = { + "24.24.24.24", "80.24.24.80", "200.24.24.40", "68.24.24.46"}; + +int numipstrings = 4; + +#if defined(_WIN32) +#define DATADIR SRCDIR "/data/" +#else +#define DATADIR "/usr/local/share/GeoIP/" +#endif + +#define GEOIP_OPEN(basename, flg) \ + do { \ + i = GeoIP_open(DATADIR basename, (flg) | GEOIP_SILENCE); \ + if (i == NULL) { \ + printf("error: %s%s does not exist\n", DATADIR, basename); \ + return; \ + /* or a 'longjmp(geo_jmp,1)'? */ \ + } \ + } while (0) + +#if !defined(_WIN32) +struct timeval timer_t1; +struct timeval timer_t2; +#else /* !defined(_WIN32) */ +FILETIME timer_t1; /* 100 ns */ +FILETIME timer_t2; +#endif /* !defined(_WIN32) */ + +#if !defined(_WIN32) +void timerstart(void) { gettimeofday(&timer_t1, NULL); } + +double timerstop(void) { + int a1 = 0; + int a2 = 0; + double r = 0; + gettimeofday(&timer_t2, NULL); + a1 = timer_t2.tv_sec - timer_t1.tv_sec; + a2 = timer_t2.tv_usec - timer_t1.tv_usec; + if (a1 < 0) { + a1 = a1 - 1; + a2 = a2 + 1000000; + } + r = (((double)a1) + (((double)a2) / 1000000)); + return r; +} +#else /* !defined(_WIN32) */ +void timerstart(void) { GetSystemTimeAsFileTime(&timer_t1); } + +double timerstop(void) { + __int64 delta; /* VC6 can't convert an unsigned int64 to to double */ + GetSystemTimeAsFileTime(&timer_t2); + delta = FILETIME_TO_USEC(timer_t2) - FILETIME_TO_USEC(timer_t1); + return ((double)delta) / 1E6; +} +#endif /* !defined(_WIN32) */ + +void testgeoipcountry(int flags, const char *msg, int numlookups) { + double t = 0; + int i4 = 0; + int i2 = 0; + GeoIP *i = NULL; + + GEOIP_OPEN("GeoIP.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + GeoIP_country_name_by_addr(i, ipstring[i4]); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +void testgeoiporg(int flags, const char *msg, int numlookups) { + GeoIP *i = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + + GEOIP_OPEN("GeoIPOrg.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + free(GeoIP_name_by_addr(i, ipstring[i4])); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +void testgeoipregion(int flags, const char *msg, int numlookups) { + GeoIP *i = NULL; + GeoIPRegion *i3 = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + + GEOIP_OPEN("GeoIPRegion.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + i3 = GeoIP_region_by_addr(i, ipstring[i4]); + GeoIPRegion_delete(i3); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +void testgeoipcity(int flags, const char *msg, int numlookups) { + GeoIP *i = NULL; + GeoIPRecord *i3 = NULL; + int i4 = 0; + int i2 = 0; + double t = 0; + + GEOIP_OPEN("GeoLiteCity.dat", flags); + timerstart(); + for (i2 = 0; i2 < numlookups; i2++) { + i3 = GeoIP_record_by_addr(i, ipstring[i4]); + GeoIPRecord_delete(i3); + i4 = (i4 + 1) % numipstrings; + } + t = timerstop(); + printf("%s\n", msg); + printf("%d lookups made in %f seconds \n", numlookups, t); + GeoIP_delete(i); +} + +int main(void) { + int time = 300 * numipstrings; + testgeoipcountry(0, "GeoIP Country", 100 * time); + testgeoipcountry( + GEOIP_CHECK_CACHE, "GeoIP Country with GEOIP_CHECK_CACHE", 100 * time); + testgeoipcountry(GEOIP_MEMORY_CACHE, + "GeoIP Country with GEOIP_MEMORY_CACHE", + 1000 * time); + testgeoipcountry( + GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE, + "GeoIP Country with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE", + 1000 * time); + + testgeoipregion(0, "GeoIP Region", 100 * time); + testgeoipregion( + GEOIP_CHECK_CACHE, "GeoIP Region with GEOIP_CHECK_CACHE", 100 * time); + testgeoipregion(GEOIP_MEMORY_CACHE, + "GeoIP Region with GEOIP_MEMORY_CACHE", + 1000 * time); + testgeoipregion( + GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE, + "GeoIP Region with GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE", + 1000 * time); + + testgeoiporg(0, "GeoIP Org", 50 * time); + testgeoiporg( + GEOIP_INDEX_CACHE, "GeoIP Org with GEOIP_INDEX_CACHE", 200 * time); + testgeoiporg(GEOIP_INDEX_CACHE | GEOIP_CHECK_CACHE, + "GeoIP Org with GEOIP_INDEX_CACHE and GEOIP_CHECK_CACHE", + 200 * time); + testgeoiporg( + GEOIP_MEMORY_CACHE, "GeoIP Org with GEOIP_MEMORY_CACHE", 500 * time); + + testgeoipcity(0, "GeoIP City", 50 * time); + testgeoipcity( + GEOIP_INDEX_CACHE, "GeoIP City with GEOIP_INDEX_CACHE", 200 * time); + testgeoipcity(GEOIP_INDEX_CACHE | GEOIP_CHECK_CACHE, + "GeoIP City with GEOIP_INDEX_CACHE and GEOIP_CHECK_CACHE", + 200 * time); + testgeoipcity( + GEOIP_MEMORY_CACHE, "GeoIP City with GEOIP_MEMORY_CACHE", 500 * time); + return 0; +} diff --git a/test/city_test.txt b/test/city_test.txt new file mode 100644 index 0000000..2ba04ac --- /dev/null +++ b/test/city_test.txt @@ -0,0 +1,2 @@ +24.24.24.24 # Should return Ithaca, NY, US +80.24.24.24 # Should return Madrid, 29, ES diff --git a/test/country_test.txt b/test/country_test.txt new file mode 100644 index 0000000..a395b75 --- /dev/null +++ b/test/country_test.txt @@ -0,0 +1,61 @@ +12.87.118.0 US USA +63.147.126.103 FR FRA +64.17.254.216 US USA +65.23.121.221 US USA +65.116.3.80 US USA +66.92.181.240 US USA +67.43.156.0 A1 A1 +67.43.156.64 A1 A1 +67.43.156.128 A1 A1 +67.43.156.192 A1 A1 +69.218.251.16 US USA +70.46.123.145 US USA +71.138.104.240 US USA +72.214.6.72 GB GBR +74.0.137.194 US USA +75.77.211.208 US USA +78.26.70.208 IT ITA +81.2.69.160 GB GBR +82.99.17.96 NO NOR +83.206.36.224 FR FRA +85.88.2.224 DE DEU +89.92.212.0 FR FRA +89.92.212.32 FR FRA +89.92.212.80 FR FRA +89.92.212.94 FR FRA +89.92.212.95 FR FRA +89.92.212.96 FR FRA +89.92.212.144 FR FRA +89.92.212.224 FR FRA +89.92.212.248 FR FRA +89.92.212.252 FR FRA +89.92.213.0 FR FRA +89.92.213.16 FR FRA +89.92.213.32 FR FRA +89.92.213.44 FR FRA +89.92.213.48 FR FRA +89.92.213.64 FR FRA +89.92.213.80 FR FRA +89.92.213.88 FR FRA +89.92.213.96 FR FRA +89.92.213.104 FR FRA +89.92.213.108 FR FRA +89.92.213.110 FR FRA +89.92.213.112 FR FRA +89.92.213.166 FR FRA +89.92.213.167 FR FRA +89.92.213.168 FR FRA +89.92.213.176 FR FRA +89.92.213.192 FR FRA +89.92.213.200 FR FRA +89.92.213.224 FR FRA +89.160.20.112 SE SWE +142.217.214.0 CA CAN +143.217.214.0 VN VNM +204.128.241.208 CA CAN +208.110.217.107 US USA +216.83.171.192 US USA +216.160.83.56 US USA +222.230.136.0 JP JPN +222.230.137.0 JP JPN +223.0.0.0 FR FRA diff --git a/test/country_test2.txt b/test/country_test2.txt new file mode 100644 index 0000000..30c5982 --- /dev/null +++ b/test/country_test2.txt @@ -0,0 +1,61 @@ +12.87.118.0 US +63.147.126.103 FR +64.17.254.216 US +65.23.121.221 US +65.116.3.80 US +66.92.181.240 US +67.43.156.0 A1 +67.43.156.64 A1 +67.43.156.128 A1 +67.43.156.192 A1 +69.218.251.16 US +70.46.123.145 US +71.138.104.240 US +72.214.6.72 GB +74.0.137.194 US +75.77.211.208 US +78.26.70.208 IT +81.2.69.160 GB +82.99.17.96 NO +83.206.36.224 FR +85.88.2.224 DE +89.92.212.0 FR +89.92.212.32 FR +89.92.212.80 FR +89.92.212.94 FR +89.92.212.95 FR +89.92.212.96 FR +89.92.212.144 FR +89.92.212.224 FR +89.92.212.248 FR +89.92.212.252 FR +89.92.213.0 FR +89.92.213.16 FR +89.92.213.32 FR +89.92.213.44 FR +89.92.213.48 FR +89.92.213.64 FR +89.92.213.80 FR +89.92.213.88 FR +89.92.213.96 FR +89.92.213.104 FR +89.92.213.108 FR +89.92.213.110 FR +89.92.213.112 FR +89.92.213.166 FR +89.92.213.167 FR +89.92.213.168 FR +89.92.213.176 FR +89.92.213.192 FR +89.92.213.200 FR +89.92.213.224 FR +89.160.20.112 SE +142.217.214.0 CA +143.217.214.0 VN +204.128.241.208 CA +208.110.217.107 US +216.83.171.192 US +216.160.83.56 US +222.230.136.0 JP +222.230.137.0 JP +223.0.0.0 FR diff --git a/test/country_test_name.txt b/test/country_test_name.txt new file mode 100644 index 0000000..ce71409 --- /dev/null +++ b/test/country_test_name.txt @@ -0,0 +1 @@ +yahoo.com US diff --git a/test/fail_test.txt b/test/fail_test.txt new file mode 100644 index 0000000..902ee09 --- /dev/null +++ b/test/fail_test.txt @@ -0,0 +1 @@ +136.253.10.148 AU diff --git a/test/proxy_test.txt b/test/proxy_test.txt new file mode 100644 index 0000000..b11a2e1 --- /dev/null +++ b/test/proxy_test.txt @@ -0,0 +1,17 @@ +66.119.33.170 3 +139.134.64.157 2 +12.148.160.0 1 +24.24.24.21 0 +24.24.24.22 0 +24.24.24.23 0 +24.24.24.24 0 +24.24.24.25 0 +24.24.24.26 0 +145.253.2.25 1 +203.26.24.212 1 +195.229.241.233 1 +200.158.23.208 2 +80.247.152.5 2 +200.161.189.226 2 +66.119.33.135 3 +80.58.39.42 3 diff --git a/test/region_test.txt b/test/region_test.txt new file mode 100644 index 0000000..2828a57 --- /dev/null +++ b/test/region_test.txt @@ -0,0 +1,24 @@ +216.236.135.152 US USA +24.24.24.24 US USA +147.251.48.1 CZ CZE +203.174.65.12 JP JPN +212.208.74.140 FR FRA +200.219.192.106 BR BRA +134.102.101.18 DE DEU +193.75.148.28 BE BEL +194.244.83.2 IT ITA +203.15.106.23 AU AUS +196.31.1.1 ZA ZAF +151.28.39.114 IT ITA +151.38.70.94 IT ITA +193.56.4.124 FR FRA +195.142.146.198 TR TUR +211.232.0.0 KR KOR +211.240.0.0 KR KOR +193.194.4.0 MA MAR +139.20.112.104 DE DEU +139.20.112.3 DE DEU +145.236.125.211 HU HUN +yahoo.com US USA +amazon.com US USA +www.uspto.gov US USA diff --git a/test/test-geoip-asnum.c b/test/test-geoip-asnum.c new file mode 100644 index 0000000..56d1cc8 --- /dev/null +++ b/test/test-geoip-asnum.c @@ -0,0 +1,56 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-asnum.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *org; + char host[50]; + + gi = GeoIP_open("../data/GeoIPASNum.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("asnum_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening asnum_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_org_by_name(gi, (const char *)host); + + if (org != NULL) { + printf("%s\t%s\n", host, _mk_NA(org)); + } + } + + GeoIP_delete(gi); + fclose(f); + return 0; +} diff --git a/test/test-geoip-city.c b/test/test-geoip-city.c new file mode 100644 index 0000000..93568e0 --- /dev/null +++ b/test/test-geoip-city.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-city.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include "GeoIPCity.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + GeoIPRecord *gir; + char host[50]; + const char *time_zone = NULL; + char **ret; + + gi = GeoIP_open("../data/GeoIPCity.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("city_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening city_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + gir = GeoIP_record_by_name(gi, (const char *)host); + + if (gir != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *)host); + time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, + gir->region); + printf("%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\t%s\n", + host, + _mk_NA(gir->country_code), + _mk_NA(gir->region), + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(gir->city), + _mk_NA(gir->postal_code), + gir->latitude, + gir->longitude, + gir->metro_code, + gir->area_code, + _mk_NA(time_zone), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + GeoIPRecord_delete(gir); + } + } + GeoIP_delete(gi); + fclose(f); + return 0; +} diff --git a/test/test-geoip-domain.c b/test/test-geoip-domain.c new file mode 100644 index 0000000..d8ac609 --- /dev/null +++ b/test/test-geoip-domain.c @@ -0,0 +1,67 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-org.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *domain; + char host[50]; + char **ret; + + gi = GeoIP_open("../data/GeoIPDomain.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("domain_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening domain_test.txt\n"); + exit(1); + } + + printf("IP\tdomain\tnetmask\tbeginIp\tendIp\n"); + while (fscanf(f, "%s", host) != EOF) { + domain = GeoIP_name_by_name(gi, (const char *)host); + + if (domain != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *)host); + + printf("%s\t%s\t%d\t%s\t%s\n", + host, + _mk_NA(domain), + GeoIP_last_netmask(gi), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + free(domain); + } + } + + fclose(f); + GeoIP_delete(gi); + return 0; +} diff --git a/test/test-geoip-invalid-file.c b/test/test-geoip-invalid-file.c new file mode 100644 index 0000000..10fe246 --- /dev/null +++ b/test/test-geoip-invalid-file.c @@ -0,0 +1,29 @@ +#include "GeoIP.h" + +int main(void) { + GeoIP *gi = GeoIP_open(SRCDIR "/README.md", GEOIP_MEMORY_CACHE); + + /* We don't detect invalid files at load, unfortunately. */ + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + return 1; + } + + const char *country = GeoIP_country_code_by_addr(gi, "24.24.24.24"); + if (country != NULL) { + fprintf(stderr, + "Received a non-NULL value on an invalid database from " + "GeoIP_country_code_by_addr\n"); + return 1; + } + + country = GeoIP_country_code_by_addr_v6(gi, "24.24.24.24"); + if (country != NULL) { + fprintf(stderr, + "Received a non-NULL value on an invalid database from " + "GeoIP_country_code_by_addr_v6\n"); + return 1; + } + + return 0; +} diff --git a/test/test-geoip-isp.c b/test/test-geoip-isp.c new file mode 100644 index 0000000..e4c3bb4 --- /dev/null +++ b/test/test-geoip-isp.c @@ -0,0 +1,58 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-isp.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *org; + char host[50]; + + gi = GeoIP_open("../data/GeoIPISP.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("isp_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening isp_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_org_by_name(gi, (const char *)host); + + if (org != NULL) { + printf("%s\t%s\n", host, _mk_NA(org)); + free(org); + } + } + + fclose(f); + GeoIP_delete(gi); + + return 0; +} diff --git a/test/test-geoip-netspeed.c b/test/test-geoip-netspeed.c new file mode 100644 index 0000000..44aac64 --- /dev/null +++ b/test/test-geoip-netspeed.c @@ -0,0 +1,59 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-netspeed.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + int netspeed; + char host[50]; + + gi = GeoIP_open("../data/GeoIPNetSpeed.dat", GEOIP_STANDARD); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("netspeed_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening netspeed_test.txt\n"); + exit(1); + } + + while (fscanf(f, "%s", host) != EOF) { + netspeed = GeoIP_id_by_name(gi, (const char *)host); + if (netspeed == GEOIP_UNKNOWN_SPEED) { + printf("%s\tUnknown\n", host); + } else if (netspeed == GEOIP_DIALUP_SPEED) { + printf("%s\tDialup\n", host); + } else if (netspeed == GEOIP_CABLEDSL_SPEED) { + printf("%s\tCable/DSL\n", host); + } else if (netspeed == GEOIP_CORPORATE_SPEED) { + printf("%s\tCorporate\n", host); + } + } + fclose(f); + GeoIP_delete(gi); + + return 0; +} diff --git a/test/test-geoip-org.c b/test/test-geoip-org.c new file mode 100644 index 0000000..e42ed53 --- /dev/null +++ b/test/test-geoip-org.c @@ -0,0 +1,67 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-org.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(int argc, char *argv[]) { + FILE *f; + GeoIP *gi; + char *org; + char host[50]; + char **ret; + + gi = GeoIP_open("../data/GeoIPOrg.dat", GEOIP_INDEX_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("org_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening org_test.txt\n"); + exit(1); + } + + printf("IP\torganization\tnetmask\tbeginIp\tendIp\n"); + while (fscanf(f, "%s", host) != EOF) { + org = GeoIP_name_by_name(gi, (const char *)host); + + if (org != NULL) { + ret = GeoIP_range_by_ip(gi, (const char *)host); + + printf("%s\t%s\t%d\t%s\t%s\n", + host, + _mk_NA(org), + GeoIP_last_netmask(gi), + ret[0], + ret[1]); + GeoIP_range_by_ip_delete(ret); + free(org); + } + } + + fclose(f); + GeoIP_delete(gi); + return 0; +} diff --git a/test/test-geoip-region.c b/test/test-geoip-region.c new file mode 100644 index 0000000..839bf45 --- /dev/null +++ b/test/test-geoip-region.c @@ -0,0 +1,118 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip-region.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" +#include /* For uint32_t */ +#ifdef HAVE_STDINT_H +#include /* For uint32_t */ +#endif +#if !defined(_WIN32) +#include /* For gethostbyname */ +#include /* For ntohl */ +#else +#include +#include +#endif +#include + +unsigned long inetaddr(const char *name) { + struct hostent *host; + struct in_addr inaddr; + + host = gethostbyname(name); + assert(host); + inaddr.s_addr = *((uint32_t *)host->h_addr_list[0]); + return inaddr.s_addr; +} + +static const char *_mk_NA(const char *p) { return p ? p : "N/A"; } + +int main(void) { + GeoIP *gi; + GeoIPRegion *gir, giRegion; + + FILE *f; + char ipAddress[30]; + char expectedCountry[3]; + char expectedCountry3[4]; + const char *time_zone; + + gi = GeoIP_open("../data/GeoIPRegion.dat", GEOIP_MEMORY_CACHE); + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + f = fopen("region_test.txt", "r"); + + if (f == NULL) { + fprintf(stderr, "Error opening region_test.txt\n"); + exit(1); + } + + gir = GeoIP_region_by_addr(gi, "10.0.0.0"); + if (gir != NULL) { + printf("lookup of private IP address: country = %s, region = %s\n", + gir->country_code, + gir->region); + } + + while (fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3) != + EOF) { + printf("ip = %s\n", ipAddress); + + gir = GeoIP_region_by_name(gi, ipAddress); + if (gir != NULL) { + time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, + gir->region); + printf("%s, %s, %s, %s\n", + gir->country_code, + (!gir->region[0]) ? "N/A" : gir->region, + _mk_NA(GeoIP_region_name_by_code(gir->country_code, + gir->region)), + _mk_NA(time_zone)); + } else { + printf("NULL!\n"); + } + + GeoIP_assign_region_by_inetaddr(gi, inetaddr(ipAddress), &giRegion); + if (gir != NULL) { + assert(giRegion.country_code[0]); + assert(!strcmp(gir->country_code, giRegion.country_code)); + if (gir->region[0]) { + assert(giRegion.region[0]); + assert(!strcmp(gir->region, giRegion.region)); + } else { + assert(!giRegion.region[0]); + } + } else { + assert(!giRegion.country_code[0]); + } + + if (gir != NULL) { + GeoIPRegion_delete(gir); + } + } + + GeoIP_delete(gi); + fclose(f); + return 0; +} diff --git a/test/test-geoip.c b/test/test-geoip.c new file mode 100644 index 0000000..909e63c --- /dev/null +++ b/test/test-geoip.c @@ -0,0 +1,146 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* test-geoip.c + * + * Copyright (C) 2016 MaxMind, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "GeoIP.h" + +int main(void) { + FILE *f; + char *db_info; + char ipAddress[30]; + char expectedCountry[3]; + char expectedCountry3[4]; + const char *returnedCountry; + GeoIP *gi; + int failed = 0; + int test_num = 1; + + int i; + for (i = 0; i < 2; ++i) { + if (0 == i) { + /* Read from filesystem, check for updated file */ + gi = GeoIP_open(SRCDIR "/data/GeoIP.dat", + GEOIP_STANDARD | GEOIP_CHECK_CACHE); + } else { + /* Read from memory, faster but takes up more memory */ + gi = GeoIP_open(SRCDIR "/data/GeoIP.dat", GEOIP_MEMORY_CACHE); + } + + if (gi == NULL) { + fprintf(stderr, "Error opening database\n"); + exit(1); + } + + db_info = GeoIP_database_info(gi); + if (!db_info || strcmp(db_info, + "GEO-106 20160621 Build 1 Copyright (c) 2016 " + "MaxMind Inc All Rights Reserved")) { + fprintf(stderr, "Error reading database info (got %s).\n", db_info); + free(db_info); + failed = 1; + } + + /* make sure GeoIP deals with invalid query gracefully */ + returnedCountry = GeoIP_country_code_by_addr(gi, NULL); + if (returnedCountry != NULL) { + fprintf(stderr, + "Invalid Query test failed, got non NULL, expected NULL\n"); + failed = 1; + } + + returnedCountry = GeoIP_country_code_by_name(gi, NULL); + if (returnedCountry != NULL) { + fprintf(stderr, + "Invalid Query test failed, got non NULL, expected NULL\n"); + failed = 1; + } + + f = fopen(SRCDIR "/test/country_test.txt", "r"); + + while ( + fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3) != + EOF) { + returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr, + "Test addr %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code_by_name(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr, + "Test name %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code3_by_addr(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry3) != 0) { + fprintf(stderr, + "Test addr %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + returnedCountry = GeoIP_country_code3_by_name(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry3) != 0) { + fprintf(stderr, + "Test name %d for %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + test_num++; + } + fclose(f); + + f = fopen(SRCDIR "/test/country_test2.txt", "r"); + while (fscanf(f, "%s%s", ipAddress, expectedCountry) != EOF) { + returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress); + if (returnedCountry == NULL || + strcmp(returnedCountry, expectedCountry) != 0) { + fprintf(stderr, + "Test addr %d %s failed, got %s, expected %s\n", + test_num, + ipAddress, + returnedCountry, + expectedCountry); + failed = 1; + } + test_num++; + } + fclose(f); + GeoIP_delete(gi); + } + return failed; +} diff --git a/timezone/generate_timeZone.pl b/timezone/generate_timeZone.pl new file mode 100755 index 0000000..8c4c742 --- /dev/null +++ b/timezone/generate_timeZone.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl +use strict; +use warnings; +use autodie; + +use Text::CSV_XS (); + +# Obtain timezone.txt from http://www.maxmind.com/timezone.txt + +# Used to generate timeZone.c +# usage: ./generate_timeZone.pl > ../libGeoIP/timeZone.c + +my $tz; + +open my $fh, '<:encoding(latin1)', 'timezone.txt'; + +my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 1 } ); + +print "#include \n"; +print + "const char* GeoIP_time_zone_by_country_and_region(const char * country,const char * region) {\n"; +print " const char* timezone = NULL;\n"; +print " if (country == NULL) {\n"; +print " return NULL;\n"; +print " }\n"; +print " if (region == NULL) {\n"; +print ' region = "";', "\n"; +print " }\n"; + +<$fh>; # skip first line +while ( my $row = $csv->getline($fh) ) { + my ( $country, $region, $timezone ) = @{$row}; + die "$_ $.\n" unless $timezone; + $tz->{$country}->{ $region || q{} } = $timezone; +} + +my $first_country; + +$first_country = 0; +for my $c ( sort keys %$tz ) { + print(' if'); + $first_country ||= $c; + my $def = delete $tz->{$c}->{q{}}; + if ( my @reg = sort keys %{ $tz->{$c} } ) { + my @tz = map { $tz->{$c}->{$_} } @reg; + + printf( qq! ( strcmp (country, "%s") == 0 ) {\n!, $c ); + for ( 0 .. $#reg ) { + + # have regions + + print( ( $_ == 0 ) ? ' if' : ' else if' ); + printf( qq! ( strcmp (region, "%s") == 0 ) {\n!, $reg[$_] ); + printf( qq! return "%s";\n!, $tz[$_] ); + printf(qq! }\n!); + } + if ( defined $def ) { + printf( qq! else { return "%s"; }\n!, $def ); + } + else { + print " else {\n return NULL;\n }\n"; + } + print qq[ }\n]; + } + else { + + # only default tz + printf( qq! ( strcmp (country, "%s") == 0 ) {\n!, $c ); + printf( qq! return "%s";\n!, $def ); + printf(qq! }\n!); + + } +} + +print qq[ return timezone;\n}\n]; diff --git a/timezone/timezone.txt b/timezone/timezone.txt new file mode 100644 index 0000000..e35c760 --- /dev/null +++ b/timezone/timezone.txt @@ -0,0 +1,717 @@ +"country","region","timezone" +AD,,"Europe/Andorra" +AE,,"Asia/Dubai" +AF,,"Asia/Kabul" +AG,,"America/Antigua" +AI,,"America/Anguilla" +AL,,"Europe/Tirane" +AM,,"Asia/Yerevan" +AN,,"America/Curacao" +AO,,"Africa/Luanda" +AQ,,"Antarctica/South_Pole" +AR,01,"America/Argentina/Buenos_Aires" +AR,02,"America/Argentina/Catamarca" +AR,03,"America/Argentina/Tucuman" +AR,04,"America/Argentina/Rio_Gallegos" +AR,05,"America/Argentina/Cordoba" +AR,06,"America/Argentina/Tucuman" +AR,07,"America/Argentina/Buenos_Aires" +AR,08,"America/Argentina/Buenos_Aires" +AR,09,"America/Argentina/Tucuman" +AR,10,"America/Argentina/Jujuy" +AR,11,"America/Argentina/San_Luis" +AR,12,"America/Argentina/La_Rioja" +AR,13,"America/Argentina/Mendoza" +AR,14,"America/Argentina/Buenos_Aires" +AR,15,"America/Argentina/San_Luis" +AR,16,"America/Argentina/Buenos_Aires" +AR,17,"America/Argentina/Salta" +AR,18,"America/Argentina/San_Juan" +AR,19,"America/Argentina/San_Luis" +AR,20,"America/Argentina/Rio_Gallegos" +AR,21,"America/Argentina/Buenos_Aires" +AR,22,"America/Argentina/Catamarca" +AR,23,"America/Argentina/Ushuaia" +AR,24,"America/Argentina/Tucuman" +AS,,"Pacific/Pago_Pago" +AT,,"Europe/Vienna" +AU,01,"Australia/Sydney" +AU,02,"Australia/Sydney" +AU,03,"Australia/Darwin" +AU,04,"Australia/Brisbane" +AU,05,"Australia/Adelaide" +AU,06,"Australia/Hobart" +AU,07,"Australia/Melbourne" +AU,08,"Australia/Perth" +AW,,"America/Aruba" +AX,,"Europe/Mariehamn" +AZ,,"Asia/Baku" +BA,,"Europe/Sarajevo" +BB,,"America/Barbados" +BD,,"Asia/Dhaka" +BE,,"Europe/Brussels" +BF,,"Africa/Ouagadougou" +BG,,"Europe/Sofia" +BH,,"Asia/Bahrain" +BI,,"Africa/Bujumbura" +BJ,,"Africa/Porto-Novo" +BL,,"America/St_Barthelemy" +BM,,"Atlantic/Bermuda" +BN,,"Asia/Brunei" +BO,,"America/La_Paz" +BQ,,"America/Curacao" +BR,01,"America/Rio_Branco" +BR,02,"America/Maceio" +BR,03,"America/Sao_Paulo" +BR,04,"America/Manaus" +BR,05,"America/Bahia" +BR,06,"America/Fortaleza" +BR,07,"America/Sao_Paulo" +BR,08,"America/Sao_Paulo" +BR,11,"America/Campo_Grande" +BR,13,"America/Belem" +BR,14,"America/Cuiaba" +BR,15,"America/Sao_Paulo" +BR,16,"America/Belem" +BR,17,"America/Recife" +BR,18,"America/Sao_Paulo" +BR,20,"America/Fortaleza" +BR,21,"America/Sao_Paulo" +BR,22,"America/Recife" +BR,23,"America/Sao_Paulo" +BR,24,"America/Porto_Velho" +BR,25,"America/Boa_Vista" +BR,26,"America/Sao_Paulo" +BR,27,"America/Sao_Paulo" +BR,28,"America/Maceio" +BR,29,"America/Sao_Paulo" +BR,30,"America/Recife" +BR,31,"America/Araguaina" +BS,,"America/Nassau" +BT,,"Asia/Thimphu" +BV,,"Antarctica/Syowa" +BW,,"Africa/Gaborone" +BY,,"Europe/Minsk" +BZ,,"America/Belize" +CA,AB,"America/Edmonton" +CA,BC,"America/Vancouver" +CA,MB,"America/Winnipeg" +CA,NB,"America/Halifax" +CA,NL,"America/St_Johns" +CA,NS,"America/Halifax" +CA,NT,"America/Yellowknife" +CA,NU,"America/Rankin_Inlet" +CA,ON,"America/Toronto" +CA,PE,"America/Halifax" +CA,QC,"America/Montreal" +CA,SK,"America/Regina" +CA,YT,"America/Whitehorse" +CC,,"Indian/Cocos" +CD,01,"Africa/Kinshasa" +CD,02,"Africa/Kinshasa" +CD,03,"Africa/Kinshasa" +CD,04,"Africa/Lubumbashi" +CD,05,"Africa/Lubumbashi" +CD,06,"Africa/Kinshasa" +CD,07,"Africa/Lubumbashi" +CD,08,"Africa/Kinshasa" +CD,09,"Africa/Lubumbashi" +CD,10,"Africa/Lubumbashi" +CD,11,"Africa/Lubumbashi" +CD,12,"Africa/Lubumbashi" +CF,,"Africa/Bangui" +CG,,"Africa/Brazzaville" +CH,,"Europe/Zurich" +CI,,"Africa/Abidjan" +CK,,"Pacific/Rarotonga" +CL,,"America/Santiago" +CM,,"Africa/Lagos" +CN,01,"Asia/Shanghai" +CN,02,"Asia/Shanghai" +CN,03,"Asia/Shanghai" +CN,04,"Asia/Shanghai" +CN,05,"Asia/Harbin" +CN,06,"Asia/Chongqing" +CN,07,"Asia/Shanghai" +CN,08,"Asia/Harbin" +CN,09,"Asia/Shanghai" +CN,10,"Asia/Shanghai" +CN,11,"Asia/Chongqing" +CN,12,"Asia/Shanghai" +CN,13,"Asia/Urumqi" +CN,14,"Asia/Chongqing" +CN,15,"Asia/Chongqing" +CN,16,"Asia/Chongqing" +CN,18,"Asia/Chongqing" +CN,19,"Asia/Harbin" +CN,20,"Asia/Harbin" +CN,21,"Asia/Chongqing" +CN,22,"Asia/Harbin" +CN,23,"Asia/Shanghai" +CN,24,"Asia/Chongqing" +CN,25,"Asia/Shanghai" +CN,26,"Asia/Chongqing" +CN,28,"Asia/Shanghai" +CN,29,"Asia/Chongqing" +CN,30,"Asia/Chongqing" +CN,31,"Asia/Chongqing" +CN,32,"Asia/Chongqing" +CN,33,"Asia/Chongqing" +CO,,"America/Bogota" +CR,,"America/Costa_Rica" +CU,,"America/Havana" +CV,,"Atlantic/Cape_Verde" +CW,,"America/Curacao" +CX,,"Indian/Christmas" +CY,,"Asia/Nicosia" +CZ,,"Europe/Prague" +DE,,"Europe/Berlin" +DJ,,"Africa/Djibouti" +DK,,"Europe/Copenhagen" +DM,,"America/Dominica" +DO,,"America/Santo_Domingo" +DZ,,"Africa/Algiers" +EC,01,"Pacific/Galapagos" +EC,02,"America/Guayaquil" +EC,03,"America/Guayaquil" +EC,04,"America/Guayaquil" +EC,05,"America/Guayaquil" +EC,06,"America/Guayaquil" +EC,07,"America/Guayaquil" +EC,08,"America/Guayaquil" +EC,09,"America/Guayaquil" +EC,10,"America/Guayaquil" +EC,11,"America/Guayaquil" +EC,12,"America/Guayaquil" +EC,13,"America/Guayaquil" +EC,14,"America/Guayaquil" +EC,15,"America/Guayaquil" +EC,17,"America/Guayaquil" +EC,18,"America/Guayaquil" +EC,19,"America/Guayaquil" +EC,20,"America/Guayaquil" +EC,22,"America/Guayaquil" +EC,24,"America/Guayaquil" +EE,,"Europe/Tallinn" +EG,,"Africa/Cairo" +EH,,"Africa/El_Aaiun" +ER,,"Africa/Asmara" +ES,07,"Europe/Madrid" +ES,27,"Europe/Madrid" +ES,29,"Europe/Madrid" +ES,31,"Europe/Madrid" +ES,32,"Europe/Madrid" +ES,34,"Europe/Madrid" +ES,39,"Europe/Madrid" +ES,51,"Africa/Ceuta" +ES,52,"Europe/Madrid" +ES,53,"Atlantic/Canary" +ES,54,"Europe/Madrid" +ES,55,"Europe/Madrid" +ES,56,"Europe/Madrid" +ES,57,"Europe/Madrid" +ES,58,"Europe/Madrid" +ES,59,"Europe/Madrid" +ES,60,"Europe/Madrid" +ET,,"Africa/Addis_Ababa" +FI,,"Europe/Helsinki" +FJ,,"Pacific/Fiji" +FK,,"Atlantic/Stanley" +FM,,"Pacific/Pohnpei" +FO,,"Atlantic/Faroe" +FR,,"Europe/Paris" +FX,,"Europe/Paris" +GA,,"Africa/Libreville" +GB,,"Europe/London" +GD,,"America/Grenada" +GE,,"Asia/Tbilisi" +GF,,"America/Cayenne" +GG,,"Europe/Guernsey" +GH,,"Africa/Accra" +GI,,"Europe/Gibraltar" +GL,01,"America/Thule" +GL,02,"America/Godthab" +GL,03,"America/Godthab" +GM,,"Africa/Banjul" +GN,,"Africa/Conakry" +GP,,"America/Guadeloupe" +GQ,,"Africa/Malabo" +GR,,"Europe/Athens" +GS,,"Atlantic/South_Georgia" +GT,,"America/Guatemala" +GU,,"Pacific/Guam" +GW,,"Africa/Bissau" +GY,,"America/Guyana" +HK,,"Asia/Hong_Kong" +HN,,"America/Tegucigalpa" +HR,,"Europe/Zagreb" +HT,,"America/Port-au-Prince" +HU,,"Europe/Budapest" +ID,01,"Asia/Pontianak" +ID,02,"Asia/Makassar" +ID,03,"Asia/Jakarta" +ID,04,"Asia/Jakarta" +ID,05,"Asia/Jakarta" +ID,06,"Asia/Jakarta" +ID,07,"Asia/Jakarta" +ID,08,"Asia/Jakarta" +ID,09,"Asia/Jayapura" +ID,10,"Asia/Jakarta" +ID,11,"Asia/Pontianak" +ID,12,"Asia/Makassar" +ID,13,"Asia/Makassar" +ID,14,"Asia/Makassar" +ID,15,"Asia/Jakarta" +ID,16,"Asia/Makassar" +ID,17,"Asia/Makassar" +ID,18,"Asia/Makassar" +ID,19,"Asia/Pontianak" +ID,20,"Asia/Makassar" +ID,21,"Asia/Makassar" +ID,22,"Asia/Makassar" +ID,23,"Asia/Makassar" +ID,24,"Asia/Jakarta" +ID,25,"Asia/Pontianak" +ID,26,"Asia/Pontianak" +ID,28,"Asia/Jayapura" +ID,29,"Asia/Makassar" +ID,30,"Asia/Jakarta" +ID,31,"Asia/Makassar" +ID,32,"Asia/Jakarta" +ID,33,"Asia/Jakarta" +ID,34,"Asia/Makassar" +ID,35,"Asia/Pontianak" +ID,36,"Asia/Jayapura" +ID,37,"Asia/Pontianak" +ID,38,"Asia/Makassar" +ID,39,"Asia/Jayapura" +ID,40,"Asia/Pontianak" +ID,41,"Asia/Makassar" +IE,,"Europe/Dublin" +IL,,"Asia/Jerusalem" +IM,,"Europe/Isle_of_Man" +IN,,"Asia/Kolkata" +IO,,"Indian/Chagos" +IQ,,"Asia/Baghdad" +IR,,"Asia/Tehran" +IS,,"Atlantic/Reykjavik" +IT,,"Europe/Rome" +JE,,"Europe/Jersey" +JM,,"America/Jamaica" +JO,,"Asia/Amman" +JP,,"Asia/Tokyo" +KE,,"Africa/Nairobi" +KG,,"Asia/Bishkek" +KH,,"Asia/Phnom_Penh" +KI,,"Pacific/Tarawa" +KM,,"Indian/Comoro" +KN,,"America/St_Kitts" +KP,,"Asia/Pyongyang" +KR,,"Asia/Seoul" +KW,,"Asia/Kuwait" +KY,,"America/Cayman" +KZ,01,"Asia/Almaty" +KZ,02,"Asia/Almaty" +KZ,03,"Asia/Qyzylorda" +KZ,04,"Asia/Aqtobe" +KZ,05,"Asia/Qyzylorda" +KZ,06,"Asia/Aqtau" +KZ,07,"Asia/Oral" +KZ,08,"Asia/Qyzylorda" +KZ,09,"Asia/Aqtau" +KZ,10,"Asia/Qyzylorda" +KZ,11,"Asia/Almaty" +KZ,12,"Asia/Qyzylorda" +KZ,13,"Asia/Aqtobe" +KZ,14,"Asia/Qyzylorda" +KZ,15,"Asia/Almaty" +KZ,16,"Asia/Aqtobe" +KZ,17,"Asia/Almaty" +LA,,"Asia/Vientiane" +LB,,"Asia/Beirut" +LC,,"America/St_Lucia" +LI,,"Europe/Vaduz" +LK,,"Asia/Colombo" +LR,,"Africa/Monrovia" +LS,,"Africa/Maseru" +LT,,"Europe/Vilnius" +LU,,"Europe/Luxembourg" +LV,,"Europe/Riga" +LY,,"Africa/Tripoli" +MA,,"Africa/Casablanca" +MC,,"Europe/Monaco" +MD,,"Europe/Chisinau" +ME,,"Europe/Podgorica" +MF,,"America/Marigot" +MG,,"Indian/Antananarivo" +MH,,"Pacific/Kwajalein" +MK,,"Europe/Skopje" +ML,,"Africa/Bamako" +MM,,"Asia/Rangoon" +MN,06,"Asia/Choibalsan" +MN,11,"Asia/Ulaanbaatar" +MN,17,"Asia/Choibalsan" +MN,19,"Asia/Hovd" +MN,20,"Asia/Ulaanbaatar" +MN,21,"Asia/Ulaanbaatar" +MN,25,"Asia/Ulaanbaatar" +MO,,"Asia/Macau" +MP,,"Pacific/Saipan" +MQ,,"America/Martinique" +MR,,"Africa/Nouakchott" +MS,,"America/Montserrat" +MT,,"Europe/Malta" +MU,,"Indian/Mauritius" +MV,,"Indian/Maldives" +MW,,"Africa/Blantyre" +MX,01,"America/Mexico_City" +MX,02,"America/Tijuana" +MX,03,"America/Hermosillo" +MX,04,"America/Merida" +MX,05,"America/Mexico_City" +MX,06,"America/Chihuahua" +MX,07,"America/Monterrey" +MX,08,"America/Mexico_City" +MX,09,"America/Mexico_City" +MX,10,"America/Mazatlan" +MX,11,"America/Mexico_City" +MX,12,"America/Mexico_City" +MX,13,"America/Mexico_City" +MX,14,"America/Mazatlan" +MX,15,"America/Chihuahua" +MX,16,"America/Mexico_City" +MX,17,"America/Mexico_City" +MX,18,"America/Mazatlan" +MX,19,"America/Monterrey" +MX,20,"America/Mexico_City" +MX,21,"America/Mexico_City" +MX,22,"America/Mexico_City" +MX,23,"America/Cancun" +MX,24,"America/Mexico_City" +MX,25,"America/Mazatlan" +MX,26,"America/Hermosillo" +MX,27,"America/Merida" +MX,28,"America/Monterrey" +MX,29,"America/Mexico_City" +MX,30,"America/Mexico_City" +MX,31,"America/Merida" +MX,32,"America/Monterrey" +MY,01,"Asia/Kuala_Lumpur" +MY,02,"Asia/Kuala_Lumpur" +MY,03,"Asia/Kuala_Lumpur" +MY,04,"Asia/Kuala_Lumpur" +MY,05,"Asia/Kuala_Lumpur" +MY,06,"Asia/Kuala_Lumpur" +MY,07,"Asia/Kuala_Lumpur" +MY,08,"Asia/Kuala_Lumpur" +MY,09,"Asia/Kuala_Lumpur" +MY,11,"Asia/Kuching" +MY,12,"Asia/Kuala_Lumpur" +MY,13,"Asia/Kuala_Lumpur" +MY,14,"Asia/Kuala_Lumpur" +MY,15,"Asia/Kuching" +MY,16,"Asia/Kuching" +MZ,,"Africa/Maputo" +NA,,"Africa/Windhoek" +NC,,"Pacific/Noumea" +NE,,"Africa/Niamey" +NF,,"Pacific/Norfolk" +NG,,"Africa/Lagos" +NI,,"America/Managua" +NL,,"Europe/Amsterdam" +NO,,"Europe/Oslo" +NP,,"Asia/Kathmandu" +NR,,"Pacific/Nauru" +NU,,"Pacific/Niue" +NZ,85,"Pacific/Auckland" +NZ,E7,"Pacific/Auckland" +NZ,E8,"Pacific/Auckland" +NZ,E9,"Pacific/Auckland" +NZ,F1,"Pacific/Auckland" +NZ,F2,"Pacific/Auckland" +NZ,F3,"Pacific/Auckland" +NZ,F4,"Pacific/Auckland" +NZ,F5,"Pacific/Auckland" +NZ,F6,"Pacific/Auckland" +NZ,F7,"Pacific/Chatham" +NZ,F8,"Pacific/Auckland" +NZ,F9,"Pacific/Auckland" +NZ,G1,"Pacific/Auckland" +NZ,G2,"Pacific/Auckland" +NZ,G3,"Pacific/Auckland" +OM,,"Asia/Muscat" +PA,,"America/Panama" +PE,,"America/Lima" +PF,,"Pacific/Marquesas" +PG,,"Pacific/Port_Moresby" +PH,,"Asia/Manila" +PK,,"Asia/Karachi" +PL,,"Europe/Warsaw" +PM,,"America/Miquelon" +PN,,"Pacific/Pitcairn" +PR,,"America/Puerto_Rico" +PS,,"Asia/Gaza" +PT,02,"Europe/Lisbon" +PT,03,"Europe/Lisbon" +PT,04,"Europe/Lisbon" +PT,05,"Europe/Lisbon" +PT,06,"Europe/Lisbon" +PT,07,"Europe/Lisbon" +PT,08,"Europe/Lisbon" +PT,09,"Europe/Lisbon" +PT,10,"Atlantic/Madeira" +PT,11,"Europe/Lisbon" +PT,13,"Europe/Lisbon" +PT,14,"Europe/Lisbon" +PT,16,"Europe/Lisbon" +PT,17,"Europe/Lisbon" +PT,18,"Europe/Lisbon" +PT,19,"Europe/Lisbon" +PT,20,"Europe/Lisbon" +PT,21,"Europe/Lisbon" +PT,22,"Europe/Lisbon" +PT,23,"Atlantic/Azores" +PW,,"Pacific/Palau" +PY,,"America/Asuncion" +QA,,"Asia/Qatar" +RE,,"Indian/Reunion" +RO,,"Europe/Bucharest" +RS,,"Europe/Belgrade" +RU,01,"Europe/Volgograd" +RU,02,"Asia/Irkutsk" +RU,03,"Asia/Novokuznetsk" +RU,04,"Asia/Novosibirsk" +RU,05,"Asia/Vladivostok" +RU,06,"Europe/Moscow" +RU,07,"Europe/Volgograd" +RU,08,"Europe/Samara" +RU,09,"Europe/Moscow" +RU,10,"Europe/Moscow" +RU,11,"Asia/Irkutsk" +RU,12,"Europe/Volgograd" +RU,13,"Asia/Yekaterinburg" +RU,14,"Asia/Irkutsk" +RU,15,"Asia/Anadyr" +RU,16,"Europe/Samara" +RU,17,"Europe/Volgograd" +RU,18,"Asia/Krasnoyarsk" +RU,20,"Asia/Irkutsk" +RU,21,"Europe/Moscow" +RU,22,"Europe/Volgograd" +RU,23,"Europe/Kaliningrad" +RU,24,"Europe/Volgograd" +RU,25,"Europe/Moscow" +RU,26,"Asia/Kamchatka" +RU,27,"Europe/Volgograd" +RU,28,"Europe/Moscow" +RU,29,"Asia/Novokuznetsk" +RU,30,"Asia/Vladivostok" +RU,31,"Asia/Krasnoyarsk" +RU,32,"Asia/Omsk" +RU,33,"Asia/Yekaterinburg" +RU,34,"Asia/Yekaterinburg" +RU,35,"Asia/Yekaterinburg" +RU,36,"Asia/Anadyr" +RU,37,"Europe/Moscow" +RU,38,"Europe/Volgograd" +RU,39,"Asia/Krasnoyarsk" +RU,40,"Asia/Yekaterinburg" +RU,41,"Europe/Moscow" +RU,42,"Europe/Moscow" +RU,43,"Europe/Moscow" +RU,44,"Asia/Magadan" +RU,45,"Europe/Samara" +RU,46,"Europe/Samara" +RU,47,"Europe/Moscow" +RU,48,"Europe/Moscow" +RU,49,"Europe/Moscow" +RU,50,"Asia/Yekaterinburg" +RU,51,"Europe/Moscow" +RU,52,"Europe/Moscow" +RU,53,"Asia/Novosibirsk" +RU,54,"Asia/Omsk" +RU,55,"Europe/Samara" +RU,56,"Europe/Moscow" +RU,57,"Europe/Samara" +RU,58,"Asia/Yekaterinburg" +RU,59,"Asia/Vladivostok" +RU,60,"Europe/Kaliningrad" +RU,61,"Europe/Volgograd" +RU,62,"Europe/Moscow" +RU,63,"Asia/Yakutsk" +RU,64,"Asia/Sakhalin" +RU,65,"Europe/Samara" +RU,66,"Europe/Moscow" +RU,67,"Europe/Samara" +RU,68,"Europe/Volgograd" +RU,69,"Europe/Moscow" +RU,70,"Europe/Volgograd" +RU,71,"Asia/Yekaterinburg" +RU,72,"Europe/Moscow" +RU,73,"Europe/Samara" +RU,74,"Asia/Krasnoyarsk" +RU,75,"Asia/Novosibirsk" +RU,76,"Europe/Moscow" +RU,77,"Europe/Moscow" +RU,78,"Asia/Yekaterinburg" +RU,79,"Asia/Irkutsk" +RU,80,"Asia/Yekaterinburg" +RU,81,"Europe/Samara" +RU,82,"Asia/Irkutsk" +RU,83,"Europe/Moscow" +RU,84,"Europe/Volgograd" +RU,85,"Europe/Moscow" +RU,86,"Europe/Moscow" +RU,87,"Asia/Novosibirsk" +RU,88,"Europe/Moscow" +RU,89,"Asia/Vladivostok" +RU,90,"Asia/Yekaterinburg" +RU,91,"Asia/Krasnoyarsk" +RU,92,"Asia/Anadyr" +RU,93,"Asia/Irkutsk" +RW,,"Africa/Kigali" +SA,,"Asia/Riyadh" +SB,,"Pacific/Guadalcanal" +SC,,"Indian/Mahe" +SD,,"Africa/Khartoum" +SE,,"Europe/Stockholm" +SG,,"Asia/Singapore" +SH,,"Atlantic/St_Helena" +SI,,"Europe/Ljubljana" +SJ,,"Arctic/Longyearbyen" +SK,,"Europe/Bratislava" +SL,,"Africa/Freetown" +SM,,"Europe/San_Marino" +SN,,"Africa/Dakar" +SO,,"Africa/Mogadishu" +SR,,"America/Paramaribo" +SS,,"Africa/Juba" +ST,,"Africa/Sao_Tome" +SV,,"America/El_Salvador" +SX,,"America/Curacao" +SY,,"Asia/Damascus" +SZ,,"Africa/Mbabane" +TC,,"America/Grand_Turk" +TD,,"Africa/Ndjamena" +TF,,"Indian/Kerguelen" +TG,,"Africa/Lome" +TH,,"Asia/Bangkok" +TJ,,"Asia/Dushanbe" +TK,,"Pacific/Fakaofo" +TL,,"Asia/Dili" +TM,,"Asia/Ashgabat" +TN,,"Africa/Tunis" +TO,,"Pacific/Tongatapu" +TR,,"Asia/Istanbul" +TT,,"America/Port_of_Spain" +TV,,"Pacific/Funafuti" +TW,,"Asia/Taipei" +TZ,,"Africa/Dar_es_Salaam" +UA,01,"Europe/Kiev" +UA,02,"Europe/Kiev" +UA,03,"Europe/Uzhgorod" +UA,04,"Europe/Zaporozhye" +UA,05,"Europe/Zaporozhye" +UA,06,"Europe/Uzhgorod" +UA,07,"Europe/Zaporozhye" +UA,08,"Europe/Simferopol" +UA,09,"Europe/Kiev" +UA,10,"Europe/Zaporozhye" +UA,11,"Europe/Simferopol" +UA,12,"Europe/Kiev" +UA,13,"Europe/Kiev" +UA,14,"Europe/Zaporozhye" +UA,15,"Europe/Uzhgorod" +UA,16,"Europe/Zaporozhye" +UA,17,"Europe/Simferopol" +UA,18,"Europe/Zaporozhye" +UA,19,"Europe/Kiev" +UA,20,"Europe/Simferopol" +UA,21,"Europe/Kiev" +UA,22,"Europe/Uzhgorod" +UA,23,"Europe/Kiev" +UA,24,"Europe/Uzhgorod" +UA,25,"Europe/Uzhgorod" +UA,26,"Europe/Zaporozhye" +UA,27,"Europe/Kiev" +UG,,"Africa/Kampala" +UM,,"Pacific/Wake" +US,AK,"America/Anchorage" +US,AL,"America/Chicago" +US,AR,"America/Chicago" +US,AZ,"America/Phoenix" +US,CA,"America/Los_Angeles" +US,CO,"America/Denver" +US,CT,"America/New_York" +US,DC,"America/New_York" +US,DE,"America/New_York" +US,FL,"America/New_York" +US,GA,"America/New_York" +US,HI,"Pacific/Honolulu" +US,IA,"America/Chicago" +US,ID,"America/Denver" +US,IL,"America/Chicago" +US,IN,"America/Indiana/Indianapolis" +US,KS,"America/Chicago" +US,KY,"America/New_York" +US,LA,"America/Chicago" +US,MA,"America/New_York" +US,MD,"America/New_York" +US,ME,"America/New_York" +US,MI,"America/New_York" +US,MN,"America/Chicago" +US,MO,"America/Chicago" +US,MS,"America/Chicago" +US,MT,"America/Denver" +US,NC,"America/New_York" +US,ND,"America/Chicago" +US,NE,"America/Chicago" +US,NH,"America/New_York" +US,NJ,"America/New_York" +US,NM,"America/Denver" +US,NV,"America/Los_Angeles" +US,NY,"America/New_York" +US,OH,"America/New_York" +US,OK,"America/Chicago" +US,OR,"America/Los_Angeles" +US,PA,"America/New_York" +US,RI,"America/New_York" +US,SC,"America/New_York" +US,SD,"America/Chicago" +US,TN,"America/Chicago" +US,TX,"America/Chicago" +US,UT,"America/Denver" +US,VA,"America/New_York" +US,VT,"America/New_York" +US,WA,"America/Los_Angeles" +US,WI,"America/Chicago" +US,WV,"America/New_York" +US,WY,"America/Denver" +UY,,"America/Montevideo" +UZ,01,"Asia/Tashkent" +UZ,02,"Asia/Samarkand" +UZ,03,"Asia/Tashkent" +UZ,05,"Asia/Samarkand" +UZ,06,"Asia/Tashkent" +UZ,07,"Asia/Samarkand" +UZ,08,"Asia/Samarkand" +UZ,09,"Asia/Samarkand" +UZ,10,"Asia/Samarkand" +UZ,12,"Asia/Samarkand" +UZ,13,"Asia/Tashkent" +UZ,14,"Asia/Tashkent" +VA,,"Europe/Vatican" +VC,,"America/St_Vincent" +VE,,"America/Caracas" +VG,,"America/Tortola" +VI,,"America/St_Thomas" +VN,,"Asia/Phnom_Penh" +VU,,"Pacific/Efate" +WF,,"Pacific/Wallis" +WS,,"Pacific/Pago_Pago" +YE,,"Asia/Aden" +YT,,"Indian/Mayotte" +YU,,"Europe/Belgrade" +ZA,,"Africa/Johannesburg" +ZM,,"Africa/Lusaka" +ZW,,"Africa/Harare" -- cgit v1.2.3