env.c revision 1.1 1 #include <errno.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <util.h>
5
6 #include <net/if.h>
7 #include <sys/socket.h>
8 #include <sys/ioctl.h>
9
10 #include "env.h"
11 #include "util.h"
12
13 prop_dictionary_t
14 prop_dictionary_augment(prop_dictionary_t bottom, prop_dictionary_t top)
15 {
16 prop_object_iterator_t i;
17 prop_dictionary_t d;
18 prop_object_t ko, o;
19 prop_dictionary_keysym_t k;
20 const char *key;
21
22 d = prop_dictionary_copy_mutable(bottom);
23
24 i = prop_dictionary_iterator(top);
25
26 while ((ko = prop_object_iterator_next(i)) != NULL) {
27 k = (prop_dictionary_keysym_t)ko;
28 key = prop_dictionary_keysym_cstring_nocopy(k);
29 o = prop_dictionary_get_keysym(top, k);
30 if (o == NULL || !prop_dictionary_set(d, key, o)) {
31 prop_object_release((prop_object_t)d);
32 d = NULL;
33 break;
34 }
35 }
36 prop_object_iterator_release(i);
37 prop_dictionary_make_immutable(d);
38 return d;
39 }
40
41 int
42 getifflags(prop_dictionary_t env, prop_dictionary_t oenv,
43 unsigned short *flagsp)
44 {
45 struct ifreq ifr;
46 prop_number_t num;
47 const char *ifname;
48 int s;
49
50 num = (prop_number_t)prop_dictionary_get(env, "ifflags");
51
52 if (num != NULL) {
53 *flagsp = (unsigned short)prop_number_integer_value(num);
54 return 0;
55 }
56
57 if ((s = getsock(AF_UNSPEC)) == -1)
58 return -1;
59
60 if ((ifname = getifname(env)) == NULL)
61 return -1;
62
63 memset(&ifr, 0, sizeof(ifr));
64 estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
65 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1)
66 return -1;
67
68 *flagsp = (unsigned short)ifr.ifr_flags;
69
70 num = prop_number_create_unsigned_integer(
71 (unsigned short)ifr.ifr_flags);
72 (void)prop_dictionary_set(oenv, "ifflags", num);
73 prop_object_release((prop_object_t)num);
74
75 return 0;
76 }
77
78 const char *
79 getifinfo(prop_dictionary_t env, prop_dictionary_t oenv, unsigned short *flagsp)
80 {
81 if (getifflags(env, oenv, flagsp) == -1)
82 return NULL;
83
84 return getifname(env);
85 }
86
87 const char *
88 getifname(prop_dictionary_t env)
89 {
90 prop_string_t str;
91
92 str = (prop_string_t)prop_dictionary_get(env, "if");
93 if (str == NULL)
94 return NULL;
95 return prop_string_cstring_nocopy(str);
96 }
97
98 ssize_t
99 getargdata(prop_dictionary_t env, const char *key, uint8_t *buf, size_t buflen)
100 {
101 prop_data_t data;
102 size_t datalen;
103
104 data = (prop_data_t)prop_dictionary_get(env, key);
105 if (data == NULL) {
106 errno = ENOENT;
107 return -1;
108 }
109 datalen = prop_data_size(data);
110 if (datalen > buflen) {
111 errno = ENAMETOOLONG;
112 return -1;
113 }
114 memset(buf, 0, buflen);
115 memcpy(buf, prop_data_data_nocopy(data), datalen);
116 return datalen;
117 }
118
119 ssize_t
120 getargstr(prop_dictionary_t env, const char *key, char *buf, size_t buflen)
121 {
122 prop_data_t data;
123 size_t datalen;
124
125 data = (prop_data_t)prop_dictionary_get(env, "bssid");
126 if (data == NULL) {
127 errno = ENOENT;
128 return -1;
129 }
130 datalen = prop_data_size(data);
131 if (datalen >= buflen) {
132 errno = ENAMETOOLONG;
133 return -1;
134 }
135 memset(buf, 0, buflen);
136 memcpy(buf, prop_data_data_nocopy(data), datalen);
137 return datalen;
138 }
139
140 int
141 getaf(prop_dictionary_t env)
142 {
143 prop_number_t num;
144
145 num = (prop_number_t)prop_dictionary_get(env, "af");
146 if (num == NULL) {
147 errno = ENOENT;
148 return -1;
149 }
150 return (int)prop_number_integer_value(num);
151 }
152