1 //
2 // Copyright (C) 2013 Nick Gasson
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17
18 #include "netdb.h"
19 #include "util.h"
20
21 #include <stdlib.h>
22 #include <assert.h>
23
netdb_open(tree_t top)24 netdb_t *netdb_open(tree_t top)
25 {
26 char *name = xasprintf("_%s.netdb", istr(tree_ident(top)));
27 fbuf_t *f = lib_fbuf_open(lib_work(), name, FBUF_IN);
28 if (f == NULL)
29 fatal("failed to open net database file %s", name);
30 free(name);
31
32 netdb_t *db = xmalloc(sizeof(struct netdb));
33 db->groups = NULL;
34 db->max = 0;
35 db->nnets = 0;
36
37 groupid_t gid;
38 while ((gid = read_u32(f)) != GROUPID_INVALID) {
39 group_t *g = xmalloc(sizeof(struct group));
40 g->next = db->groups;
41 g->gid = gid;
42 g->first = read_u32(f);
43 g->length = read_u32(f);
44
45 db->groups = g;
46 db->max = MAX(db->max, gid);
47 db->nnets = MAX(db->nnets, g->first + g->length);
48 }
49
50 fbuf_close(f);
51
52 db->map = xmalloc(sizeof(groupid_t) * db->nnets);
53 for (netid_t i = 0; i < db->nnets; i++)
54 db->map[i] = GROUPID_INVALID;
55
56 for (group_t *it = db->groups; it != NULL; it = it->next) {
57 for (netid_t i = it->first; i < it->first + it->length; i++)
58 db->map[i] = it->gid;
59 }
60
61 return db;
62 }
63
netdb_close(netdb_t * db)64 void netdb_close(netdb_t *db)
65 {
66 while (db->groups != NULL) {
67 group_t *next = db->groups->next;
68 free(db->groups);
69 db->groups = next;
70 }
71
72 free(db->map);
73 free(db);
74 }
75
netdb_size(netdb_t * db)76 unsigned netdb_size(netdb_t *db)
77 {
78 return db->max + 1;
79 }
80
netdb_walk(netdb_t * db,netdb_walk_fn_t fn)81 void netdb_walk(netdb_t *db, netdb_walk_fn_t fn)
82 {
83 for (group_t *it = db->groups; it != NULL; it = it->next)
84 (*fn)(it->gid, it->first, it->length);
85 }
86