]> jfr.im git - irc/quakenet/newserv.git/blame_incremental - geoip/geoip.c
CHANSERV: add missing error statements.
[irc/quakenet/newserv.git] / geoip / geoip.c
... / ...
CommitLineData
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"
11#include "../lib/version.h"
12
13#include <strings.h>
14
15#include "libGeoIP/GeoIP.h"
16#include "geoip.h"
17
18MODULE_VERSION("");
19
20int geoip_totals[COUNTRY_MAX + 1];
21static int geoip_nickext = -1;
22static GeoIP *gi = NULL;
23
24static void geoip_setupuser(nick *np);
25
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);
29
30void _init(void) {
31 int i;
32 nick *np;
33 sstring *filename;
34
35 filename = getcopyconfigitem("geoip", "db", "GeoIP.dat", 256);
36 gi = GeoIP_open(filename->content, GEOIP_MEMORY_CACHE);
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
71static void geoip_setupuser(nick *np) {
72 if (!irc_in_addr_is_ipv4(&np->ipaddress))
73 return; /* geoip only supports ipv4 */
74
75 unsigned int ip = irc_in_addr_v4_to_int(&np->ipaddress);
76 int country = GeoIP_id_by_ipnum(gi, ip);
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
84static void geoip_new_nick(int hook, void *args) {
85 geoip_setupuser((nick *)args);
86}
87
88static void geoip_quit(int hook, void *args) {
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
100static void geoip_whois_handler(int hooknum, void *arg) {
101 int item;
102 char message[512];
103 const char *longcountry, *shortcountry;
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
113 shortcountry = GeoIP_code_by_id(item);
114 longcountry = GeoIP_name_by_id(item);
115
116 if(shortcountry && longcountry) {
117 snprintf(message, sizeof(message), "Country : %s (%s)", shortcountry, longcountry);
118 triggerhook(HOOK_CONTROL_WHOISREPLY, message);
119 }
120}
121
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}