]>
git.ipfire.org Git - people/ms/libloc.git/blob - src/libloc.c
2 libloc - A library to determine the location of someone on the Internet
4 Copyright (C) 2017 IPFire Development Team <info@ipfire.org>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
17 #include <arpa/inet.h>
18 #include <netinet/in.h>
28 #include <loc/libloc.h>
29 #include <loc/database.h>
30 #include <loc/private.h>
34 void (*log_fn
)(struct loc_ctx
* ctx
,
35 int priority
, const char *file
, int line
, const char *fn
,
36 const char *format
, va_list args
);
39 struct loc_database
* db
;
42 void loc_log(struct loc_ctx
* ctx
,
43 int priority
, const char* file
, int line
, const char* fn
,
44 const char* format
, ...) {
47 va_start(args
, format
);
48 ctx
->log_fn(ctx
, priority
, file
, line
, fn
, format
, args
);
52 static void log_stderr(struct loc_ctx
* ctx
,
53 int priority
, const char* file
, int line
, const char* fn
,
54 const char* format
, va_list args
) {
55 fprintf(stderr
, "libloc: %s: ", fn
);
56 vfprintf(stderr
, format
, args
);
59 static int log_priority(const char* priority
) {
62 int prio
= strtol(priority
, &endptr
, 10);
64 if (endptr
[0] == '\0' || isspace(endptr
[0]))
67 if (strncmp(priority
, "err", 3) == 0)
70 if (strncmp(priority
, "info", 4) == 0)
73 if (strncmp(priority
, "debug", 5) == 0)
79 LOC_EXPORT
int loc_new(struct loc_ctx
** ctx
) {
80 struct loc_ctx
* c
= calloc(1, sizeof(*c
));
85 c
->log_fn
= log_stderr
;
86 c
->log_priority
= LOG_ERR
;
90 const char* env
= secure_getenv("LOC_LOG");
92 loc_set_log_priority(c
, log_priority(env
));
94 INFO(c
, "ctx %p created\n", c
);
95 DEBUG(c
, "log_priority=%d\n", c
->log_priority
);
101 LOC_EXPORT
struct loc_ctx
* loc_ref(struct loc_ctx
* ctx
) {
110 LOC_EXPORT
struct loc_ctx
* loc_unref(struct loc_ctx
* ctx
) {
114 if (--ctx
->refcount
> 0)
117 // Release any loaded databases
119 loc_database_unref(ctx
->db
);
121 INFO(ctx
, "context %p released\n", ctx
);
127 LOC_EXPORT
void loc_set_log_fn(struct loc_ctx
* ctx
,
128 void (*log_fn
)(struct loc_ctx
* ctx
, int priority
, const char* file
,
129 int line
, const char* fn
, const char* format
, va_list args
)) {
130 ctx
->log_fn
= log_fn
;
131 INFO(ctx
, "custom logging function %p registered\n", log_fn
);
134 LOC_EXPORT
int loc_get_log_priority(struct loc_ctx
* ctx
) {
135 return ctx
->log_priority
;
138 LOC_EXPORT
void loc_set_log_priority(struct loc_ctx
* ctx
, int priority
) {
139 ctx
->log_priority
= priority
;
142 LOC_EXPORT
int loc_load(struct loc_ctx
* ctx
, const char* path
) {
143 FILE* f
= fopen(path
, "r");
147 // Release any previously openend database
149 loc_database_unref(ctx
->db
);
151 // Open the new database
152 int r
= loc_database_new(ctx
, &ctx
->db
, f
);
162 LOC_EXPORT
int loc_parse_address(struct loc_ctx
* ctx
, const char* string
, struct in6_addr
* address
) {
163 DEBUG(ctx
, "Paring IP address %s\n", string
);
165 // Try parsing this as an IPv6 address
166 int r
= inet_pton(AF_INET6
, string
, address
);
168 // If inet_pton returns one it has been successful
170 DEBUG(ctx
, "%s is an IPv6 address\n", string
);
174 // Try parsing this as an IPv4 address
175 struct in_addr ipv4_address
;
176 r
= inet_pton(AF_INET
, string
, &ipv4_address
);
178 DEBUG(ctx
, "%s is an IPv4 address\n", string
);
180 // Convert to IPv6-mapped address
181 address
->s6_addr32
[0] = htonl(0x0000);
182 address
->s6_addr32
[1] = htonl(0x0000);
183 address
->s6_addr32
[2] = htonl(0xffff);
184 address
->s6_addr32
[3] = ipv4_address
.s_addr
;
189 DEBUG(ctx
, "%s is not an valid IP address\n", string
);