]> jfr.im git - irc/quakenet/newserv.git/blame - geoip/geoip.c
BUILD: improve workspace mechanism
[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
69793602 15#include "libGeoIP/GeoIP.h"
cc3768c4
CP
16#include "geoip.h"
17
70b0a4e5 18MODULE_VERSION("");
87698d77 19
cc3768c4 20int geoip_totals[COUNTRY_MAX + 1];
69793602
CP
21static int geoip_nickext = -1;
22static GeoIP *gi = NULL;
cc3768c4 23
69793602 24static void geoip_setupuser(nick *np);
cc3768c4 25
69793602
CP
26static void geoip_new_nick(int hook, void *args);
27static void geoip_quit(int hook, void *args);
28static void geoip_whois_handler(int hooknum, void *arg);
cc3768c4
CP
29
30void _init(void) {
31 int i;
32 nick *np;
33 sstring *filename;
34
35 filename = getcopyconfigitem("geoip", "db", "GeoIP.dat", 256);
69793602 36 gi = GeoIP_open(filename->content, GEOIP_MEMORY_CACHE);
cc3768c4
CP
37 freesstring(filename);
38
39 if(!gi)
40 return;
41
42 geoip_nickext = registernickext("geoip");
43 if(geoip_nickext == -1)
44 return; /* PPA: registerchanext produces an error, however the module should stop loading */
45
46 memset(geoip_totals, 0, sizeof(geoip_totals));
47
48 for(i=0;i<NICKHASHSIZE;i++)
49 for(np=nicktable[i];np;np=np->next)
50 geoip_setupuser(np);
51
52 registerhook(HOOK_NICK_LOSTNICK, &geoip_quit);
53 registerhook(HOOK_NICK_NEWNICK, &geoip_new_nick);
54 registerhook(HOOK_CONTROL_WHOISREQUEST, &geoip_whois_handler);
55}
56
57void _fini(void) {
58 if(gi)
59 GeoIP_delete(gi);
60
61 if(geoip_nickext == -1)
62 return;
63
64 releasenickext(geoip_nickext);
65
66 deregisterhook(HOOK_NICK_NEWNICK, &geoip_new_nick);
67 deregisterhook(HOOK_NICK_LOSTNICK, &geoip_quit);
68 deregisterhook(HOOK_CONTROL_WHOISREQUEST, &geoip_whois_handler);
69}
70
69793602 71static void geoip_setupuser(nick *np) {
fdcb5d66 72 if (!irc_in_addr_is_ipv4(&np->ipaddress))
20554f73
P
73 return; /* geoip only supports ipv4 */
74
fdcb5d66 75 unsigned int ip = irc_in_addr_v4_to_int(&np->ipaddress);
20554f73 76 int country = GeoIP_id_by_ipnum(gi, ip);
cc3768c4
CP
77 if((country < COUNTRY_MIN) || (country > COUNTRY_MAX))
78 return;
79
80 geoip_totals[country]++;
81 np->exts[geoip_nickext] = (void *)(long)country;
82}
83
69793602 84static void geoip_new_nick(int hook, void *args) {
cc3768c4
CP
85 geoip_setupuser((nick *)args);
86}
87
69793602 88static void geoip_quit(int hook, void *args) {
cc3768c4
CP
89 int item;
90 nick *np = (nick *)args;
91
92 item = (int)((long)np->exts[geoip_nickext]);
93
94 if((item < COUNTRY_MIN) || (item > COUNTRY_MAX))
95 return;
96
97 geoip_totals[item]--;
98}
99
69793602 100static void geoip_whois_handler(int hooknum, void *arg) {
cc3768c4 101 int item;
69793602
CP
102 char message[512];
103 const char *longcountry, *shortcountry;
cc3768c4
CP
104 nick *np = (nick *)arg;
105
106 if(!np)
107 return;
108
109 item = (int)((long)np->exts[geoip_nickext]);
110 if((item < COUNTRY_MIN) || (item > COUNTRY_MAX))
111 return;
112
69793602
CP
113 shortcountry = GeoIP_code_by_id(item);
114 longcountry = GeoIP_name_by_id(item);
115
116 if(shortcountry && longcountry) {
cc3768c4
CP
117 snprintf(message, sizeof(message), "Country : %s (%s)", shortcountry, longcountry);
118 triggerhook(HOOK_CONTROL_WHOISREPLY, message);
119 }
120}
121
4e4920a4
CP
122int geoip_lookupcode(char *code) {
123 int i;
124 for(i=COUNTRY_MIN;i<COUNTRY_MAX;i++)
125 if(!strcasecmp(code, GeoIP_country_code[i]))
126 return i;
127
128 return -1;
129}