• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/iserver/avahi-0.6.25/avahi-compat-libdns_sd/

Lines Matching defs:*

0 /* $Id$ */
4 This file is part of avahi.
6 avahi is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 avahi is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14 Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with avahi; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <stdlib.h>
27 #include <sys/types.h>
28 #include <assert.h>
29 #include <string.h>
31 #include <avahi-common/malloc.h>
33 #include "dns_sd.h"
34 #include "warn.h"
36 typedef struct TXTRecordInternal {
37 uint8_t *buffer, *malloc_buffer;
38 size_t size, max_size;
39 } TXTRecordInternal;
41 #define INTERNAL_PTR(txtref) (* (TXTRecordInternal**) (txtref))
42 #define INTERNAL_PTR_CONST(txtref) (* (const TXTRecordInternal* const *) (txtref))
44 void DNSSD_API TXTRecordCreate(
45 TXTRecordRef *txtref,
46 uint16_t length,
47 void *buffer) {
49 TXTRecordInternal *t;
51 AVAHI_WARN_LINKAGE;
53 assert(txtref);
55 /* Apple's API design is flawed in so many ways, including the
56 * fact that it isn't compatible with 64 bit processors. To work
57 * around this we need some magic here which involves allocating
58 * our own memory. Please, Apple, do your homework next time
59 * before designing an API! */
61 if ((t = avahi_new(TXTRecordInternal, 1))) {
62 t->buffer = buffer;
63 t->max_size = buffer ? length : (size_t)0;
64 t->size = 0;
65 t->malloc_buffer = NULL;
68 /* If we were unable to allocate memory, we store a NULL pointer
69 * and return a NoMemory error later, is somewhat unclean, but
70 * should work. */
71 INTERNAL_PTR(txtref) = t;
74 void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtref) {
75 TXTRecordInternal *t;
77 AVAHI_WARN_LINKAGE;
79 assert(txtref);
80 t = INTERNAL_PTR(txtref);
81 if (!t)
82 return;
84 avahi_free(t->malloc_buffer);
85 avahi_free(t);
87 /* Just in case ... */
88 INTERNAL_PTR(txtref) = NULL;
91 static int make_sure_fits_in(TXTRecordInternal *t, size_t size) {
92 uint8_t *n;
93 size_t nsize;
95 assert(t);
97 if (t->size + size <= t->max_size)
98 return 0;
100 nsize = t->size + size + 100;
102 if (nsize > 0xFFFF)
103 return -1;
105 if (!(n = avahi_realloc(t->malloc_buffer, nsize)))
106 return -1;
108 if (!t->malloc_buffer && t->size)
109 memcpy(n, t->buffer, t->size);
111 t->buffer = t->malloc_buffer = n;
112 t->max_size = nsize;
114 return 0;
117 static int remove_key(TXTRecordInternal *t, const char *key) {
118 size_t i;
119 uint8_t *p;
120 size_t key_len;
121 int found = 0;
123 key_len = strlen(key);
124 assert(key_len <= 0xFF);
126 p = t->buffer;
127 i = 0;
129 while (i < t->size) {
131 /* Does the item fit in? */
132 assert(*p <= t->size - i - 1);
134 /* Key longer than buffer */
135 if (key_len > t->size - i - 1)
136 break;
138 if (key_len <= *p &&
139 strncmp(key, (char*) p+1, key_len) == 0 &&
140 (key_len == *p || p[1+key_len] == '=')) {
142 uint8_t s;
144 /* Key matches, so let's remove it */
146 s = *p;
147 memmove(p, p + 1 + *p, t->size - i - *p -1);
148 t->size -= s + 1;
150 found = 1;
151 } else {
152 /* Skip to next */
154 i += *p +1;
155 p += *p +1;
159 return found;
162 DNSServiceErrorType DNSSD_API TXTRecordSetValue(
163 TXTRecordRef *txtref,
164 const char *key,
165 uint8_t length,
166 const void *value) {
168 TXTRecordInternal *t;
169 uint8_t *p;
170 size_t l, n;
172 AVAHI_WARN_LINKAGE;
174 assert(key);
175 assert(txtref);
177 l = strlen(key);
179 if (*key == 0 || strchr(key, '=') || l > 0xFF) /* Empty or invalid key */
180 return kDNSServiceErr_Invalid;
182 if (!(t = INTERNAL_PTR(txtref)))
183 return kDNSServiceErr_NoMemory;
185 n = l + (value ? length + 1 : 0);
187 if (n > 0xFF)
188 return kDNSServiceErr_Invalid;
190 if (make_sure_fits_in(t, 1 + n) < 0)
191 return kDNSServiceErr_NoMemory;
193 remove_key(t, key);
195 p = t->buffer + t->size;
197 *(p++) = (uint8_t) n;
198 t->size ++;
200 memcpy(p, key, l);
201 p += l;
202 t->size += l;
204 if (value) {
205 *(p++) = '=';
206 memcpy(p, value, length);
207 t->size += length + 1;
210 assert(t->size <= t->max_size);
212 return kDNSServiceErr_NoError;
215 DNSServiceErrorType DNSSD_API TXTRecordRemoveValue(TXTRecordRef *txtref, const char *key) {
216 TXTRecordInternal *t;
217 int found;
219 AVAHI_WARN_LINKAGE;
221 assert(key);
222 assert(txtref);
224 if (*key == 0 || strchr(key, '=') || strlen(key) > 0xFF) /* Empty or invalid key */
225 return kDNSServiceErr_Invalid;
227 if (!(t = INTERNAL_PTR(txtref)))
228 return kDNSServiceErr_NoError;
230 found = remove_key(t, key);
232 return found ? kDNSServiceErr_NoError : kDNSServiceErr_NoSuchKey;
235 uint16_t DNSSD_API TXTRecordGetLength(const TXTRecordRef *txtref) {
236 const TXTRecordInternal *t;
238 AVAHI_WARN_LINKAGE;
240 assert(txtref);
242 if (!(t = INTERNAL_PTR_CONST(txtref)))
243 return 0;
245 assert(t->size <= 0xFFFF);
246 return (uint16_t) t->size;
249 const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtref) {
250 const TXTRecordInternal *t;
252 AVAHI_WARN_LINKAGE;
254 assert(txtref);
256 if (!(t = INTERNAL_PTR_CONST(txtref)) || !t->buffer)
257 return "";
259 return t->buffer;
262 static const uint8_t *find_key(const uint8_t *buffer, size_t size, const char *key) {
263 size_t i;
264 const uint8_t *p;
265 size_t key_len;
267 key_len = strlen(key);
269 assert(key_len <= 0xFF);
271 p = buffer;
272 i = 0;
274 while (i < size) {
276 /* Does the item fit in? */
277 if (*p > size - i - 1)
278 return NULL;
280 /* Key longer than buffer */
281 if (key_len > size - i - 1)
282 return NULL;
284 if (key_len <= *p &&
285 strncmp(key, (const char*) p+1, key_len) == 0 &&
286 (key_len == *p || p[1+key_len] == '=')) {
288 /* Key matches, so let's return it */
290 return p;
293 /* Skip to next */
294 i += *p +1;
295 p += *p +1;
298 return NULL;
301 int DNSSD_API TXTRecordContainsKey (
302 uint16_t size,
303 const void *buffer,
304 const char *key) {
306 AVAHI_WARN_LINKAGE;
308 assert(key);
310 if (!size)
311 return 0;
313 assert(buffer);
315 if (!(find_key(buffer, size, key)))
316 return 0;
318 return 1;
321 const void * DNSSD_API TXTRecordGetValuePtr(
322 uint16_t size,
323 const void *buffer,
324 const char *key,
325 uint8_t *value_len) {
327 const uint8_t *p;
328 size_t n, l;
330 AVAHI_WARN_LINKAGE;
332 assert(key);
334 if (!size)
335 goto fail;
337 if (*key == 0 || strchr(key, '=') || strlen(key) > 0xFF) /* Empty or invalid key */
338 return NULL;
340 assert(buffer);
342 if (!(p = find_key(buffer, size, key)))
343 goto fail;
345 n = *p;
346 l = strlen(key);
348 assert(n >= l);
349 p += 1 + l;
350 n -= l;
352 if (n <= 0)
353 goto fail;
355 assert(*p == '=');
356 p++;
357 n--;
359 if (value_len)
360 *value_len = n;
362 return p;
364 fail:
365 if (value_len)
366 *value_len = 0;
368 return NULL;
372 uint16_t DNSSD_API TXTRecordGetCount(
373 uint16_t size,
374 const void *buffer) {
376 const uint8_t *p;
377 unsigned n = 0;
378 size_t i;
380 AVAHI_WARN_LINKAGE;
382 if (!size)
383 return 0;
385 assert(buffer);
387 p = buffer;
388 i = 0;
390 while (i < size) {
392 /* Does the item fit in? */
393 if (*p > size - i - 1)
394 break;
396 n++;
398 /* Skip to next */
399 i += *p +1;
400 p += *p +1;
403 assert(n <= 0xFFFF);
405 return (uint16_t) n;
408 DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex(
409 uint16_t size,
410 const void *buffer,
411 uint16_t idx,
412 uint16_t key_len,
413 char *key,
414 uint8_t *value_len,
415 const void **value) {
417 const uint8_t *p;
418 size_t i;
419 unsigned n = 0;
420 DNSServiceErrorType ret = kDNSServiceErr_Invalid;
422 AVAHI_WARN_LINKAGE;
424 if (!size)
425 goto fail;
427 assert(buffer);
429 p = buffer;
430 i = 0;
432 while (i < size) {
434 /* Does the item fit in? */
435 if (*p > size - i - 1)
436 goto fail;
438 if (n >= idx) {
439 size_t l;
440 const uint8_t *d;
442 d = memchr(p+1, '=', *p);
444 /* Length of key */
445 l = d ? d - p - 1 : *p;
447 if (key_len < l+1) {
448 ret = kDNSServiceErr_NoMemory;
449 goto fail;
452 strncpy(key, (const char*) p + 1, l);
453 key[l] = 0;
455 if (d) {
456 if (value_len)
457 *value_len = *p - l - 1;
459 if (value)
460 *value = d + 1;
461 } else {
463 if (value_len)
464 *value_len = 0;
466 if (value)
467 *value = NULL;
470 return kDNSServiceErr_NoError;
473 n++;
475 /* Skip to next */
476 i += *p +1;
477 p += *p +1;
481 fail:
483 if (value)
484 *value = NULL;
486 if (value_len)
487 *value_len = 0;
489 return ret;