-
Notifications
You must be signed in to change notification settings - Fork 3
/
geoip.c
100 lines (86 loc) · 2.23 KB
/
geoip.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <GeoIP.h>
#include <GeoIPCity.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
#include "geoip.h"
#include "config.h"
#include "string.h"
#include "wrapper.h"
#include "misc.h"
#include "debug.h"
#define GEOIP_WARNING "Warning: Could not open geoip database. To use geoip you " \
"need the geoip city database stored in " GEOIP_PATH ". On Arch Linux this " \
"can be installed from the geoip-database-extra package."
static GeoIP *gip;
void geoip_init(void)
{
/* libGeoIP writes to stderr by default instead of letting users handle this
as appropriate. Need to add GEOIP_SILENCE to shut them up. */
if (!(gip = GeoIP_open(GEOIP_PATH, GEOIP_STANDARD | GEOIP_SILENCE))) {
if (errno == ENOENT) {
errno = 0;
err_msg(GEOIP_WARNING);
}
DEBUG("Error opening %s - disabling geoip", GEOIP_PATH);
}
}
void geoip_free(void)
{
if (gip)
GeoIP_delete(gip);
}
char *geoip_get_location(char *addr, char *buf, int len)
{
GeoIPRecord *record;
if (!gip)
return NULL;
record = GeoIP_record_by_addr(gip, addr);
if (!record) {
strlcpy(buf, "Unknown", len);
return buf;
}
if (record->city && record->country_name) {
snprintf(buf, len, "%s, %s", record->city, record->country_name);
} else if (record->country_name) {
snprintf(buf, len, "%s", record->country_name);
} else {
strlcpy(buf, "Unknown", len);
}
GeoIPRecord_delete(record);
return buf;
}
char *geoip_get_country(char *addr)
{
char *name;
GeoIPRecord *record;
if (!gip)
return NULL;
name = NULL;
record = GeoIP_record_by_addr(gip, addr);
if (record) {
if (record->country_name)
name = xstrdup(record->country_name);
GeoIPRecord_delete(record);
}
return name;
}
char *geoip_get_city(char *addr)
{
char *city;
GeoIPRecord *record;
if (!gip)
return NULL;
city = NULL;
record = GeoIP_record_by_addr(gip, addr);
if (record) {
if (record->city)
city = xstrdup(record->city);
GeoIPRecord_delete(record);
}
return city;
}
void geoip_print_version(void)
{
printf("libGeoIP %s\n", GeoIP_lib_version());
}