1/*
2 *   $Id: util.c,v 1.10 2008/10/15 05:34:35 psavola Exp $
3 *
4 *   Authors:
5 *    Lars Fenneberg		<lf@elemental.net>
6 *
7 *   This software is Copyright 1996,1997 by the above mentioned author(s),
8 *   All Rights Reserved.
9 *
10 *   The license which is distributed with this software in the file COPYRIGHT
11 *   applies to this software. If your distribution is missing this file, you
12 *   may request it from <pekkas@netcore.fi>.
13 *
14 */
15
16#include <config.h>
17#include <includes.h>
18#include <radvd.h>
19
20void
21mdelay(double msecs)
22{
23	struct timeval tv;
24
25	tv.tv_sec = (time_t)(msecs / 1000.0);
26	tv.tv_usec = (suseconds_t)((msecs - tv.tv_sec * 1000.0) * 1000.0);
27
28	select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL, &tv);
29}
30
31double
32rand_between(double lower, double upper)
33{
34	return ((upper - lower) / (RAND_MAX + 1.0) * rand() + lower);
35}
36
37void
38print_addr(struct in6_addr *addr, char *str)
39{
40	const char *res;
41
42	/* XXX: overflows 'str' if it isn't big enough */
43	res = inet_ntop(AF_INET6, (void *)addr, str, INET6_ADDRSTRLEN);
44
45	if (res == NULL)
46	{
47		flog(LOG_ERR, "print_addr: inet_ntop: %s", strerror(errno));
48		strcpy(str, "[invalid address]");
49	}
50}
51
52/* Check if an in6_addr exists in the rdnss list */
53int
54check_rdnss_presence(struct AdvRDNSS *rdnss, struct in6_addr *addr)
55{
56	while (rdnss) {
57		if (    !memcmp(&rdnss->AdvRDNSSAddr1, addr, sizeof(struct in6_addr))
58		     || !memcmp(&rdnss->AdvRDNSSAddr2, addr, sizeof(struct in6_addr))
59		     || !memcmp(&rdnss->AdvRDNSSAddr3, addr, sizeof(struct in6_addr)) )
60			break; /* rdnss address found in the list */
61		else
62			rdnss = rdnss->next; /* no match */
63	}
64	return (rdnss != NULL);
65}
66
67/* Like read(), but retries in case of partial read */
68ssize_t
69readn(int fd, void *buf, size_t count)
70{
71	size_t n = 0;
72	while (count > 0) {
73		int r = read(fd, buf, count);
74		if (r < 0) {
75			if (errno == EINTR)
76				continue;
77			return r;
78		}
79		if (r == 0)
80			return n;
81		buf = (char *)buf + r;
82		count -= r;
83		n += r;
84	}
85	return n;
86}
87
88/* Like write(), but retries in case of partial write */
89ssize_t
90writen(int fd, const void *buf, size_t count)
91{
92	size_t n = 0;
93	while (count > 0) {
94		int r = write(fd, buf, count);
95		if (r < 0) {
96			if (errno == EINTR)
97				continue;
98			return r;
99		}
100		if (r == 0)
101			return n;
102		buf = (const char *)buf + r;
103		count -= r;
104		n += r;
105	}
106	return n;
107}
108