Fix mdoc(7)/man(7) mix up.
[netbsd-mini2440.git] / lib / libbluetooth / bluetooth.c
blob31dbb238ad4c8ef2bd0439049ae35f0f6a5bc0a2
1 /* $NetBSD: bluetooth.c$ */
3 /*
4 * bluetooth.c
6 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
30 * $Id: bluetooth.c,v 1.1 2006/06/19 15:44:36 gdamore Exp $
31 * $FreeBSD: src/lib/libbluetooth/bluetooth.c,v 1.2 2004/03/05 08:10:17 markm Exp $
34 #include <sys/cdefs.h>
35 __RCSID("$NetBSD: bluetooth.c$");
37 #include <bluetooth.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
42 #define _PATH_BT_HOSTS "/etc/bluetooth/hosts"
43 #define _PATH_BT_PROTOCOLS "/etc/bluetooth/protocols"
44 #define MAXALIASES 35
46 static FILE *hostf = NULL;
47 static int host_stayopen = 0;
48 static struct hostent host;
49 static bdaddr_t host_addr;
50 static char *host_addr_ptrs[2];
51 static char *host_aliases[MAXALIASES];
53 static FILE *protof = NULL;
54 static int proto_stayopen = 0;
55 static struct protoent proto;
56 static char *proto_aliases[MAXALIASES];
58 static char buf[BUFSIZ + 1];
60 static int bt_hex_byte (char const *str);
61 static int bt_hex_nibble (char nibble);
63 struct hostent *
64 bt_gethostbyname(char const *name)
66 struct hostent *p;
67 char **cp;
69 bt_sethostent(host_stayopen);
70 while ((p = bt_gethostent()) != NULL) {
71 if (strcasecmp(p->h_name, name) == 0)
72 break;
73 for (cp = p->h_aliases; *cp != 0; cp++)
74 if (strcasecmp(*cp, name) == 0)
75 goto found;
77 found:
78 bt_endhostent();
80 return (p);
83 struct hostent *
84 bt_gethostbyaddr(char const *addr, socklen_t len, int type)
86 struct hostent *p;
88 if (type != AF_BLUETOOTH || len != sizeof(bdaddr_t)) {
89 h_errno = NO_RECOVERY;
90 return (NULL);
93 bt_sethostent(host_stayopen);
94 while ((p = bt_gethostent()) != NULL)
95 if (p->h_addrtype == type && memcmp(p->h_addr, addr, len) == 0)
96 break;
97 bt_endhostent();
99 return (p);
102 struct hostent *
103 bt_gethostent(void)
105 char *p, *cp, **q;
107 if (hostf == NULL)
108 hostf = fopen(_PATH_BT_HOSTS, "r");
110 if (hostf == NULL) {
111 h_errno = NETDB_INTERNAL;
112 return (NULL);
114 again:
115 if ((p = fgets(buf, sizeof(buf), hostf)) == NULL) {
116 h_errno = HOST_NOT_FOUND;
117 return (NULL);
119 if (*p == '#')
120 goto again;
121 if ((cp = strpbrk(p, "#\n")) == NULL)
122 goto again;
123 *cp = 0;
124 if ((cp = strpbrk(p, " \t")) == NULL)
125 goto again;
126 *cp++ = 0;
127 if (bt_aton(p, &host_addr) == 0)
128 goto again;
129 host_addr_ptrs[0] = (char *) &host_addr;
130 host_addr_ptrs[1] = NULL;
131 host.h_addr_list = host_addr_ptrs;
132 host.h_length = sizeof(host_addr);
133 host.h_addrtype = AF_BLUETOOTH;
134 while (*cp == ' ' || *cp == '\t')
135 cp++;
136 host.h_name = cp;
137 q = host.h_aliases = host_aliases;
138 if ((cp = strpbrk(cp, " \t")) != NULL)
139 *cp++ = 0;
140 while (cp != NULL && *cp != 0) {
141 if (*cp == ' ' || *cp == '\t') {
142 cp++;
143 continue;
145 if (q < &host_aliases[MAXALIASES - 1])
146 *q++ = cp;
147 if ((cp = strpbrk(cp, " \t")) != NULL)
148 *cp++ = 0;
150 *q = NULL;
151 h_errno = NETDB_SUCCESS;
153 return (&host);
156 void
157 bt_sethostent(int stayopen)
159 if (hostf == NULL)
160 hostf = fopen(_PATH_BT_HOSTS, "r");
161 else
162 rewind(hostf);
164 host_stayopen = stayopen;
167 void
168 bt_endhostent(void)
170 if (hostf != NULL && host_stayopen == 0) {
171 (void) fclose(hostf);
172 hostf = NULL;
176 struct protoent *
177 bt_getprotobyname(char const *name)
179 struct protoent *p;
180 char **cp;
182 bt_setprotoent(proto_stayopen);
183 while ((p = bt_getprotoent()) != NULL) {
184 if (strcmp(p->p_name, name) == 0)
185 break;
186 for (cp = p->p_aliases; *cp != 0; cp++)
187 if (strcmp(*cp, name) == 0)
188 goto found;
190 found:
191 bt_endprotoent();
193 return (p);
196 struct protoent *
197 bt_getprotobynumber(int num)
199 struct protoent *p;
201 bt_setprotoent(proto_stayopen);
202 while ((p = bt_getprotoent()) != NULL)
203 if (p->p_proto == num)
204 break;
205 bt_endprotoent();
207 return (p);
210 struct protoent *
211 bt_getprotoent(void)
213 char *p, *cp, **q;
215 if (protof == NULL)
216 protof = fopen(_PATH_BT_PROTOCOLS, "r");
218 if (protof == NULL)
219 return (NULL);
220 again:
221 if ((p = fgets(buf, sizeof(buf), protof)) == NULL)
222 return (NULL);
223 if (*p == '#')
224 goto again;
225 if ((cp = strpbrk(p, "#\n")) == NULL)
226 goto again;
227 *cp = '\0';
228 proto.p_name = p;
229 if ((cp = strpbrk(p, " \t")) == NULL)
230 goto again;
231 *cp++ = '\0';
232 while (*cp == ' ' || *cp == '\t')
233 cp++;
234 if ((p = strpbrk(cp, " \t")) != NULL)
235 *p++ = '\0';
236 proto.p_proto = (int)strtol(cp, NULL, 0);
237 q = proto.p_aliases = proto_aliases;
238 if (p != NULL) {
239 cp = p;
240 while (cp != NULL && *cp != 0) {
241 if (*cp == ' ' || *cp == '\t') {
242 cp++;
243 continue;
245 if (q < &proto_aliases[MAXALIASES - 1])
246 *q++ = cp;
247 if ((cp = strpbrk(cp, " \t")) != NULL)
248 *cp++ = '\0';
251 *q = NULL;
253 return (&proto);
256 void
257 bt_setprotoent(int stayopen)
259 if (protof == NULL)
260 protof = fopen(_PATH_BT_PROTOCOLS, "r");
261 else
262 rewind(protof);
264 proto_stayopen = stayopen;
267 void
268 bt_endprotoent(void)
270 if (protof != NULL) {
271 (void) fclose(protof);
272 protof = NULL;
276 char const *
277 bt_ntoa(bdaddr_t const *ba, char *str)
279 static char buffer[24];
281 if (str == NULL)
282 str = buffer;
284 sprintf(str, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
285 ba->b[5], ba->b[4], ba->b[3], ba->b[2], ba->b[1], ba->b[0]);
287 return (str);
291 bt_aton(char const *str, bdaddr_t *ba)
293 int i, b;
294 char *end = NULL;
296 memset(ba, 0, sizeof(*ba));
298 for (i = 5, end = strchr(str, ':');
299 i > 0 && *str != '\0' && end != NULL;
300 i --, str = end + 1, end = strchr(str, ':')) {
301 switch (end - str) {
302 case 1:
303 b = bt_hex_nibble(str[0]);
304 break;
306 case 2:
307 b = bt_hex_byte(str);
308 break;
310 default:
311 b = -1;
312 break;
315 if (b < 0)
316 return (0);
318 ba->b[i] = b;
321 if (i != 0 || end != NULL || *str == 0)
322 return (0);
324 switch (strlen(str)) {
325 case 1:
326 b = bt_hex_nibble(str[0]);
327 break;
329 case 2:
330 b = bt_hex_byte(str);
331 break;
333 default:
334 b = -1;
335 break;
338 if (b < 0)
339 return (0);
341 ba->b[i] = b;
343 return (1);
346 static int
347 bt_hex_byte(char const *str)
349 int n1, n2;
351 if ((n1 = bt_hex_nibble(str[0])) < 0)
352 return (-1);
354 if ((n2 = bt_hex_nibble(str[1])) < 0)
355 return (-1);
357 return ((((n1 & 0x0f) << 4) | (n2 & 0x0f)) & 0xff);
360 static int
361 bt_hex_nibble(char nibble)
363 if ('0' <= nibble && nibble <= '9')
364 return (nibble - '0');
366 if ('a' <= nibble && nibble <= 'f')
367 return (nibble - 'a' + 0xa);
369 if ('A' <= nibble && nibble <= 'F')
370 return (nibble - 'A' + 0xa);
372 return (-1);