Fix searching for ASes
[people/ms/libloc.git] / src / as.c
CommitLineData
a5db3e49
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2017 IPFire Development Team <info@ipfire.org>
5
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.
10
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.
15*/
16
d3d8ede6 17#include <ctype.h>
29bd8211 18#include <endian.h>
a5db3e49
MT
19#include <errno.h>
20#include <stdint.h>
21#include <stdlib.h>
29bd8211 22#include <string.h>
a5db3e49
MT
23
24#include <loc/libloc.h>
9fc7f001 25#include <loc/as.h>
a5db3e49 26#include <loc/format.h>
9fc7f001
MT
27#include <loc/private.h>
28#include <loc/stringpool.h>
a5db3e49
MT
29
30struct loc_as {
31 struct loc_ctx* ctx;
32 int refcount;
33
a5db3e49 34 uint32_t number;
29bd8211 35 char* name;
a5db3e49
MT
36};
37
29bd8211 38LOC_EXPORT int loc_as_new(struct loc_ctx* ctx, struct loc_as** as, uint32_t number) {
a5db3e49
MT
39 struct loc_as* a = calloc(1, sizeof(*a));
40 if (!a)
41 return -ENOMEM;
42
43 a->ctx = loc_ref(ctx);
44 a->refcount = 1;
a5db3e49
MT
45
46 a->number = number;
29bd8211 47 a->name = NULL;
a5db3e49
MT
48
49 DEBUG(a->ctx, "AS%u allocated at %p\n", a->number, a);
50 *as = a;
51
52 return 0;
53}
54
55LOC_EXPORT struct loc_as* loc_as_ref(struct loc_as* as) {
56 as->refcount++;
57
58 return as;
59}
60
61static void loc_as_free(struct loc_as* as) {
62 DEBUG(as->ctx, "Releasing AS%u %p\n", as->number, as);
63
29bd8211
MT
64 if (as->name)
65 free(as->name);
a5db3e49 66
29bd8211 67 loc_unref(as->ctx);
a5db3e49
MT
68 free(as);
69}
70
71LOC_EXPORT struct loc_as* loc_as_unref(struct loc_as* as) {
72 if (--as->refcount > 0)
73 return NULL;
74
75 loc_as_free(as);
76
77 return NULL;
78}
79
80LOC_EXPORT uint32_t loc_as_get_number(struct loc_as* as) {
81 return as->number;
82}
83
84LOC_EXPORT const char* loc_as_get_name(struct loc_as* as) {
29bd8211 85 return as->name;
a5db3e49
MT
86}
87
88LOC_EXPORT int loc_as_set_name(struct loc_as* as, const char* name) {
29bd8211 89 as->name = strdup(name);
a5db3e49 90
a5db3e49
MT
91 return 0;
92}
93
94LOC_EXPORT int loc_as_cmp(struct loc_as* as1, struct loc_as* as2) {
95 if (as1->number > as2->number)
96 return 1;
97
98 if (as1->number < as2->number)
99 return -1;
100
101 return 0;
102}
103
104int loc_as_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool,
105 struct loc_as** as, const struct loc_database_as_v0* dbobj) {
29bd8211 106 uint32_t number = be32toh(dbobj->number);
a5db3e49 107
29bd8211 108 int r = loc_as_new(ctx, as, number);
a5db3e49
MT
109 if (r)
110 return r;
111
29bd8211
MT
112 const char* name = loc_stringpool_get(pool, be32toh(dbobj->name));
113 r = loc_as_set_name(*as, name);
114 if (r) {
115 loc_as_unref(*as);
116 return r;
117 }
a5db3e49
MT
118
119 return 0;
120}
121
29bd8211
MT
122int loc_as_to_database_v0(struct loc_as* as, struct loc_stringpool* pool,
123 struct loc_database_as_v0* dbobj) {
124 dbobj->number = htobe32(as->number);
125
126 // Save the name string in the string pool
127 off_t name = loc_stringpool_add(pool, as->name ? as->name : "");
128 dbobj->name = htobe32(name);
a5db3e49
MT
129
130 return 0;
131}
d3d8ede6
MT
132
133int loc_as_match_string(struct loc_as* as, const char* string) {
d3d8ede6 134 // Search if string is in name
273948cf
MT
135 if (strcasestr(as->name, string) != NULL)
136 return 1;
d3d8ede6 137
273948cf 138 return 0;
d3d8ede6 139}