]> jfr.im git - irc/quakenet/newserv.git/blame - geoip/geoip.c
Large reorganisation of all Makefiles, including new configure script.
[irc/quakenet/newserv.git] / geoip / geoip.c
CommitLineData
cc3768c4
CP
1/*
2 Geoip module
3 Copyright (C) 2004-2006 Chris Porter.
4*/
5
6#include "../nick/nick.h"
7#include "../core/error.h"
8#include "../core/config.h"
9#include "../core/hooks.h"
10#include "../control/control.h"
87698d77 11#include "../lib/version.h"
cc3768c4 12
4e4920a4
CP
13#include <strings.h>
14
b2182a68 15#include "libGeoIP/GeoIP.h"
cc3768c4
CP
16#include "geoip.h"
17
4e4920a4 18#warning This module is GPLed. Load/link at your peril.
df3bf970 19
70b0a4e5 20MODULE_VERSION("");
87698d77 21
cc3768c4
CP
22int geoip_totals[COUNTRY_MAX + 1];
23int geoip_nickext = -1;
24GeoIP *gi = NULL;
25
26void geoip_setupuser(nick *np);
27
28void geoip_new_nick(int hook, void *args);
29void geoip_quit(int hook, void *args);
30void geoip_whois_handler(int hooknum, void *arg);
31
32void _init(void) {
33 int i;
34 nick *np;
35 sstring *filename;
36
37 filename = getcopyconfigitem("geoip", "db", "GeoIP.dat", 256);
38 gi = GeoIP_new(GEOIP_MEMORY_CACHE, filename->content);
39 freesstring(filename);
40
41 if(!gi)
42 return;
43
44 geoip_nickext = registernickext("geoip");
45 if(geoip_nickext == -1)
46 return; /* PPA: registerchanext produces an error, however the module should stop loading */
47
48 memset(geoip_totals, 0, sizeof(geoip_totals));
49
50 for(i=0;i<NICKHASHSIZE;i++)
51 for(np=nicktable[i];np;np=np->next)
52 geoip_setupuser(np);
53
54 registerhook(HOOK_NICK_LOSTNICK, &geoip_quit);
55 registerhook(HOOK_NICK_NEWNICK, &geoip_new_nick);
56 registerhook(HOOK_CONTROL_WHOISREQUEST, &geoip_whois_handler);
57}
58
59void _fini(void) {
60 if(gi)
61 GeoIP_delete(gi);
62
63 if(geoip_nickext == -1)
64 return;
65
66 releasenickext(geoip_nickext);
67
68 deregisterhook(HOOK_NICK_NEWNICK, &geoip_new_nick);
69 deregisterhook(HOOK_NICK_LOSTNICK, &geoip_quit);
70 deregisterhook(HOOK_CONTROL_WHOISREQUEST, &geoip_whois_handler);
71}
72
73void geoip_setupuser(nick *np) {
20554f73
P
74 if (!irc_in_addr_is_ipv4(&np->p_ipaddr))
75 return; /* geoip only supports ipv4 */
76
77 unsigned int ip = irc_in_addr_v4_to_int(&np->p_ipaddr);
78 int country = GeoIP_id_by_ipnum(gi, ip);
cc3768c4
CP
79 if((country < COUNTRY_MIN) || (country > COUNTRY_MAX))
80 return;
81
82 geoip_totals[country]++;
83 np->exts[geoip_nickext] = (void *)(long)country;
84}
85
86void geoip_new_nick(int hook, void *args) {
87 geoip_setupuser((nick *)args);
88}
89
90void geoip_quit(int hook, void *args) {
91 int item;
92 nick *np = (nick *)args;
93
94 item = (int)((long)np->exts[geoip_nickext]);
95
96 if((item < COUNTRY_MIN) || (item > COUNTRY_MAX))
97 return;
98
99 geoip_totals[item]--;
100}
101
102void geoip_whois_handler(int hooknum, void *arg) {
103 int item;
104 char message[512], *longcountry, *shortcountry, *shortcountry3;
105 nick *np = (nick *)arg;
106
107 if(!np)
108 return;
109
110 item = (int)((long)np->exts[geoip_nickext]);
111 if((item < COUNTRY_MIN) || (item > COUNTRY_MAX))
112 return;
113
114 if(GeoIP_country_info_by_id(item, &shortcountry, &shortcountry3, &longcountry)) {
115 snprintf(message, sizeof(message), "Country : %s (%s)", shortcountry, longcountry);
116 triggerhook(HOOK_CONTROL_WHOISREPLY, message);
117 }
118}
119
4e4920a4
CP
120int geoip_lookupcode(char *code) {
121 int i;
122 for(i=COUNTRY_MIN;i<COUNTRY_MAX;i++)
123 if(!strcasecmp(code, GeoIP_country_code[i]))
124 return i;
125
126 return -1;
127}