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