1/*	$NetBSD: env.c,v 1.6 2008/07/02 07:44:14 dyoung Exp $	*/
2
3/*-
4 * Copyright (c) 2008 David Young.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29#ifndef lint
30__RCSID("$NetBSD: env.c,v 1.6 2008/07/02 07:44:14 dyoung Exp $");
31#endif /* not lint */
32
33#include <errno.h>
34#include <string.h>
35#include <stdlib.h>
36#include <util.h>
37
38#include <net/if.h>
39#include <sys/socket.h>
40#include <sys/ioctl.h>
41
42#include "env.h"
43#include "util.h"
44#include "prog_ops.h"
45
46prop_dictionary_t
47prop_dictionary_augment(prop_dictionary_t bottom, prop_dictionary_t top)
48{
49	prop_object_iterator_t i;
50	prop_dictionary_t d;
51	prop_object_t ko, o;
52	prop_dictionary_keysym_t k;
53	const char *key;
54
55	d = prop_dictionary_copy_mutable(bottom);
56
57	i = prop_dictionary_iterator(top);
58
59	while ((ko = prop_object_iterator_next(i)) != NULL) {
60		k = (prop_dictionary_keysym_t)ko;
61		key = prop_dictionary_keysym_cstring_nocopy(k);
62		o = prop_dictionary_get_keysym(top, k);
63		if (o == NULL || !prop_dictionary_set(d, key, o)) {
64			prop_object_release((prop_object_t)d);
65			d = NULL;
66			break;
67		}
68	}
69	prop_object_iterator_release(i);
70	prop_dictionary_make_immutable(d);
71	return d;
72}
73
74int
75getifflags(prop_dictionary_t env, prop_dictionary_t oenv,
76    unsigned short *flagsp)
77{
78	struct ifreq ifr;
79	const char *ifname;
80	uint64_t ifflags;
81	int s;
82
83	if (prop_dictionary_get_uint64(env, "ifflags", &ifflags)) {
84		*flagsp = (unsigned short)ifflags;
85		return 0;
86	}
87
88	if ((s = getsock(AF_UNSPEC)) == -1)
89		return -1;
90
91	if ((ifname = getifname(env)) == NULL)
92		return -1;
93
94	memset(&ifr, 0, sizeof(ifr));
95	estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
96	if (prog_ioctl(s, SIOCGIFFLAGS, &ifr) == -1)
97		return -1;
98
99	*flagsp = (unsigned short)ifr.ifr_flags;
100
101	prop_dictionary_set_uint64(oenv, "ifflags",
102	    (unsigned short)ifr.ifr_flags);
103
104	return 0;
105}
106
107const char *
108getifinfo(prop_dictionary_t env, prop_dictionary_t oenv, unsigned short *flagsp)
109{
110	if (getifflags(env, oenv, flagsp) == -1)
111		return NULL;
112
113	return getifname(env);
114}
115
116const char *
117getifname(prop_dictionary_t env)
118{
119	const char *s;
120
121	return prop_dictionary_get_cstring_nocopy(env, "if", &s) ? s : NULL;
122}
123
124ssize_t
125getargdata(prop_dictionary_t env, const char *key, uint8_t *buf, size_t buflen)
126{
127	prop_data_t data;
128	size_t datalen;
129
130	data = (prop_data_t)prop_dictionary_get(env, key);
131	if (data == NULL) {
132		errno = ENOENT;
133		return -1;
134	}
135	datalen = prop_data_size(data);
136	if (datalen > buflen) {
137		errno = ENAMETOOLONG;
138		return -1;
139	}
140	memset(buf, 0, buflen);
141	memcpy(buf, prop_data_data_nocopy(data), datalen);
142	return datalen;
143}
144
145ssize_t
146getargstr(prop_dictionary_t env, const char *key, char *buf, size_t buflen)
147{
148	prop_data_t data;
149	size_t datalen;
150
151	data = (prop_data_t)prop_dictionary_get(env, key);
152	if (data == NULL) {
153		errno = ENOENT;
154		return -1;
155	}
156	datalen = prop_data_size(data);
157	if (datalen >= buflen) {
158		errno = ENAMETOOLONG;
159		return -1;
160	}
161	memset(buf, 0, buflen);
162	memcpy(buf, prop_data_data_nocopy(data), datalen);
163	return datalen;
164}
165
166int
167getaf(prop_dictionary_t env)
168{
169	int64_t af;
170
171	if (!prop_dictionary_get_int64(env, "af", &af)) {
172		errno = ENOENT;
173		return -1;
174	}
175	return (int)af;
176}
177