2 * copyright (c) 2001-2006 Emil Mikulic.
4 * ncache.c: cache of protocol and service names.
6 * You may use, modify and redistribute this file under the terms of the
7 * GNU General Public License version 2. (see COPYING.GPL)
16 #include <netinet/in.h> /* ntohs */
22 RB_ENTRY(name_rec) ptree;
28 rec_cmp(struct name_rec *a, struct name_rec *b)
30 if (a->num < b->num) return (-1); else
31 if (a->num > b->num) return (+1); else
35 RB_HEAD(nc_tree, name_rec);
36 RB_GENERATE(nc_tree, name_rec, ptree, rec_cmp)
39 t_proto = RB_INITIALIZER(&name_rec),
40 t_servtcp = RB_INITIALIZER(&name_rec),
41 t_servudp = RB_INITIALIZER(&name_rec);
44 add_rec(struct nc_tree *tree, const int num, const char *name)
46 struct name_rec *e, *r = xmalloc(sizeof(*r));
49 e = RB_INSERT(nc_tree, tree, r);
54 /* record exists: append service name, free record */
55 newlen = strlen(e->name) + strlen(name) + 2;
56 e->name = xrealloc(e->name, newlen);
57 strlcat(e->name, " ", newlen);
58 strlcat(e->name, name, newlen);
62 /* record added: fill out name field */
63 r->name = xstrdup(name);
72 int count, ctcp, cudp;
76 while ((pe = getprotoent()) != NULL) {
77 add_rec(&t_proto, pe->p_proto, pe->p_name);
81 verbosef("loaded %d protos", count);
83 count = ctcp = cudp = 0;
85 while ((se = getservent()) != NULL) {
86 if (strcmp(se->s_proto, "tcp") == 0) {
87 add_rec(&t_servtcp, ntohs(se->s_port), se->s_name);
90 else if (strcmp(se->s_proto, "udp") == 0) {
91 add_rec(&t_servudp, ntohs(se->s_port), se->s_name);
97 verbosef("loaded %d tcp and %d udp servs, from total %d",
102 tree_free(struct nc_tree *tree)
104 struct name_rec *curr, *next;
106 for (curr = RB_MIN(nc_tree, tree); curr != NULL; curr = next) {
107 next = RB_NEXT(nc_tree, tree, curr);
108 RB_REMOVE(nc_tree, tree, curr);
118 tree_free(&t_servtcp);
119 tree_free(&t_servudp);
122 #define FIND(tree,n) { \
123 struct name_rec r, *f; \
125 f = RB_FIND(nc_tree, &tree, &r); \
133 getproto(const int proto)
137 getservtcp(const int port)
138 FIND(t_servtcp, port)
141 getservudp(const int port)
142 FIND(t_servudp, port)
144 /* vim:set ts=3 sw=3 tw=78 expandtab: */