7 /* internet address list manager
9 /* #include <inet_addr_list.h>
11 /* void inet_addr_list_init(list)
12 /* INET_ADDR_LIST *list;
14 /* void inet_addr_list_append(list,addr)
15 /* INET_ADDR_LIST *list;
16 /* struct sockaddr *addr;
18 /* void inet_addr_list_uniq(list)
19 /* INET_ADDR_LIST *list;
21 /* void inet_addr_list_free(list)
22 /* INET_ADDR_LIST *list;
24 /* This module maintains simple lists of internet addresses.
26 /* inet_addr_list_init() initializes a user-provided structure
27 /* so that it can be used by inet_addr_list_append() and by
28 /* inet_addr_list_free().
30 /* inet_addr_list_append() appends the specified address to
31 /* the specified list, extending the list on the fly.
33 /* inet_addr_list_uniq() sorts the specified address list and
34 /* eliminates duplicates.
36 /* inet_addr_list_free() reclaims memory used for the
37 /* specified address list.
41 /* The Secure Mailer license must be distributed with this software.
44 /* IBM T.J. Watson Research
46 /* Yorktown Heights, NY 10598, USA
52 #include <sys/socket.h>
53 #include <netinet/in.h>
54 #include <arpa/inet.h>
58 /* Utility library. */
62 #include <myaddrinfo.h>
63 #include <sock_addr.h>
64 #include <inet_addr_list.h>
66 /* inet_addr_list_init - initialize internet address list */
68 void inet_addr_list_init(INET_ADDR_LIST
*list
)
75 list
->addrs
= (struct sockaddr_storage
*)
76 mymalloc(sizeof(*list
->addrs
) * init_size
);
77 list
->size
= init_size
;
80 /* inet_addr_list_append - append address to internet address list */
82 void inet_addr_list_append(INET_ADDR_LIST
*list
,
83 struct sockaddr
* addr
)
85 const char *myname
= "inet_addr_list_append";
86 MAI_HOSTADDR_STR hostaddr
;
89 if (msg_verbose
> 1) {
90 SOCKADDR_TO_HOSTADDR(addr
, SOCK_ADDR_LEN(addr
),
91 &hostaddr
, (MAI_SERVPORT_STR
*) 0, 0);
92 msg_info("%s: %s", myname
, hostaddr
.buf
);
94 if (list
->used
>= list
->size
) {
95 new_size
= list
->size
* 2;
96 list
->addrs
= (struct sockaddr_storage
*)
97 myrealloc((char *) list
->addrs
, sizeof(*list
->addrs
) * new_size
);
98 list
->size
= new_size
;
100 memcpy(list
->addrs
+ list
->used
++, addr
, SOCK_ADDR_LEN(addr
));
103 /* inet_addr_list_comp - compare addresses */
105 static int inet_addr_list_comp(const void *a
, const void *b
)
109 * In case (struct *) != (void *).
111 return (sock_addr_cmp_addr(SOCK_ADDR_PTR(a
), SOCK_ADDR_PTR(b
)));
114 /* inet_addr_list_uniq - weed out duplicates */
116 void inet_addr_list_uniq(INET_ADDR_LIST
*list
)
122 * Put the identical members right next to each other.
124 qsort((void *) list
->addrs
, list
->used
,
125 sizeof(list
->addrs
[0]), inet_addr_list_comp
);
128 * Nuke the duplicates. Postcondition after while loop: m is the largest
129 * index for which list->addrs[n] == list->addrs[m].
131 for (m
= n
= 0; m
< list
->used
; m
++, n
++) {
133 list
->addrs
[n
] = list
->addrs
[m
];
134 while (m
+ 1 < list
->used
135 && inet_addr_list_comp((void *) &(list
->addrs
[n
]),
136 (void *) &(list
->addrs
[m
+ 1])) == 0)
142 /* inet_addr_list_free - destroy internet address list */
144 void inet_addr_list_free(INET_ADDR_LIST
*list
)
146 myfree((char *) list
->addrs
);
150 #include <inet_proto.h>
153 * Duplicate elimination needs to be tested.
155 #include <inet_addr_host.h>
157 static void inet_addr_list_print(INET_ADDR_LIST
*list
)
159 MAI_HOSTADDR_STR hostaddr
;
160 struct sockaddr_storage
*sa
;
162 for (sa
= list
->addrs
; sa
< list
->addrs
+ list
->used
; sa
++) {
163 SOCKADDR_TO_HOSTADDR(SOCK_ADDR_PTR(sa
), SOCK_ADDR_LEN(sa
),
164 &hostaddr
, (MAI_SERVPORT_STR
*) 0, 0);
165 msg_info("%s", hostaddr
.buf
);
169 int main(int argc
, char **argv
)
172 INET_PROTO_INFO
*proto_info
;
174 proto_info
= inet_proto_init(argv
[0], INET_PROTO_NAME_ALL
);
175 inet_addr_list_init(&list
);
176 while (--argc
&& *++argv
)
177 if (inet_addr_host(&list
, *argv
) == 0)
178 msg_fatal("host not found: %s", *argv
);
179 msg_info("list before sort/uniq");
180 inet_addr_list_print(&list
);
181 inet_addr_list_uniq(&list
);
182 msg_info("list after sort/uniq");
183 inet_addr_list_print(&list
);
184 inet_addr_list_free(&list
);