2 * copyright (c) 2001-2014 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)
14 #include "bsd.h" /* for strlcpy */
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_STATIC(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: */