2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
24 #if !defined(HAVE_GNUTLS)
33 #include "OSXGNUReplacements.h"
35 size_t strnlen(const char *s, size_t n)
38 for (i=0; i<n && s[i] != '\0'; i++)
43 char* strndup(char const *s, size_t n)
45 size_t len = strnlen(s, n);
46 char *new_str = (char*)malloc(len + 1);
51 return (char*)memcpy(new_str, s, len);
55 From http://svn.digium.com/view/asterisk/trunk/main/utils.c
56 GNU General Public License Version 2
57 Brief Reentrant replacement for gethostbyname for BSD-based systems. Note This
58 routine is derived from code originally written and placed in the public
59 domain by Enzo Michelangeli <em@em.no-ip.com>
61 static pthread_mutex_t gethostbyname_r_mutex = PTHREAD_MUTEX_INITIALIZER;
63 int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
64 size_t buflen, struct hostent **result, int *h_errnop)
68 pthread_mutex_lock(&gethostbyname_r_mutex); /* begin critical area */
71 ph = gethostbyname(name);
72 *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
79 int naddr = 0, naliases = 0;
80 /* determine if we have enough space in buf */
82 /* count how many addresses */
83 for (p = ph->h_addr_list; *p != 0; p++) {
84 nbytes += ph->h_length; /* addresses */
85 nbytes += sizeof(*p); /* pointers */
88 nbytes += sizeof(*p); /* one more for the terminating NULL */
90 /* count how many aliases, and total length of strings */
91 for (p = ph->h_aliases; *p != 0; p++) {
92 nbytes += (strlen(*p)+1); /* aliases */
93 nbytes += sizeof(*p); /* pointers */
96 nbytes += sizeof(*p); /* one more for the terminating NULL */
98 /* here nbytes is the number of bytes required in buffer */
99 /* as a terminator must be there, the minimum value is ph->h_length */
100 if (nbytes > (int)buflen) {
102 pthread_mutex_unlock(&gethostbyname_r_mutex); /* end critical area */
103 return ERANGE; /* not enough space in buf!! */
106 /* There is enough space. Now we need to do a deep copy! */
107 /* Allocation in buffer:
108 from [0] to [(naddr-1) * sizeof(*p)]:
109 pointers to addresses
110 at [naddr * sizeof(*p)]:
112 from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
114 at [(naddr+naliases+1) * sizeof(*p)]:
116 then naddr addresses (fixed length), and naliases aliases (asciiz).
119 *ret = *ph; /* copy whole structure (not its address!) */
122 q = (char **)buf; /* pointer to pointers area (type: char **) */
123 ret->h_addr_list = q; /* update pointer to address list */
124 pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
125 for (p = ph->h_addr_list; *p != 0; p++) {
126 memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
127 *q++ = pbuf; /* the pointer is the one inside buf... */
128 pbuf += ph->h_length; /* advance pbuf */
130 *q++ = NULL; /* address list terminator */
133 ret->h_aliases = q; /* update pointer to aliases list */
134 for (p = ph->h_aliases; *p != 0; p++) {
135 strcpy(pbuf, *p); /* copy alias strings */
136 *q++ = pbuf; /* the pointer is the one inside buf... */
137 pbuf += strlen(*p); /* advance pbuf */
138 *pbuf++ = 0; /* string terminator */
140 *q++ = NULL; /* terminator */
142 strcpy(pbuf, ph->h_name); /* copy alias strings */
144 pbuf += strlen(ph->h_name); /* advance pbuf */
145 *pbuf++ = 0; /* string terminator */
147 *result = ret; /* and let *result point to structure */
150 h_errno = hsave; /* restore h_errno */
151 pthread_mutex_unlock(&gethostbyname_r_mutex); /* end critical area */
153 return (*result == NULL); /* return 0 on success, non-zero on error */
156 /* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
157 This file is part of the GNU C Library.
159 The GNU C Library is free software; you can redistribute it and/or
160 modify it under the terms of the GNU Library General Public License as
161 published by the Free Software Foundation; either version 2 of the
162 License, or (at your option) any later version.
164 The GNU C Library is distributed in the hope that it will be useful,
165 but WITHOUT ANY WARRANTY; without even the implied warranty of
166 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
167 Library General Public License for more details.
169 You should have received a copy of the GNU Library General Public
170 License along with the GNU C Library; see the file COPYING.LIB. If not,
171 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
172 Boston, MA 02111-1307, USA.
182 /* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
183 (and null-terminate it). *LINEPTR is a pointer returned from malloc (or
184 NULL), pointing to *N characters of space. It is realloc'd as
185 necessary. Returns the number of characters read (not including the
186 null terminator), or -1 on error or EOF. */
189 getdelim (lineptr, n, terminator, stream)
198 if (stream == NULL || lineptr == NULL || n == NULL)
207 /* Make sure we have a line buffer to start with. */
208 if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars. */
211 #define MAX_CANON 256
213 line = realloc (*lineptr, MAX_CANON);
232 register int c = getc (stream);
235 else if ((*p++ = c) == terminator)
239 /* Need to enlarge the line buffer. */
242 line = realloc (line, size);
254 /* Return a partial line since we got an error in the middle. */
261 getline (char **lineptr, size_t *n, FILE *stream)
263 return getdelim (lineptr, n, '\n', stream);
266 /* Compare strings while treating digits characters numerically.
267 Copyright (C) 1997, 2000 Free Software Foundation, Inc.
268 This file is part of the GNU C Library.
269 Contributed by Jean-Franois Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
271 The GNU C Library is free software; you can redistribute it and/or
272 modify it under the terms of the GNU Library General Public License as
273 published by the Free Software Foundation; either version 2 of the
274 License, or (at your option) any later version.
276 The GNU C Library is distributed in the hope that it will be useful,
277 but WITHOUT ANY WARRANTY; without even the implied warranty of
278 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
279 Library General Public License for more details.
281 You should have received a copy of the GNU Library General Public
282 License along with the GNU C Library; see the file COPYING.LIB. If not,
283 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
284 Boston, MA 02111-1307, USA. */
290 /* states: S_N: normal, S_I: comparing integral part, S_F: comparing
291 fractional parts, S_Z: idem but with leading Zeroes only */
297 /* result_type: CMP: return diff; LEN: compare using len_diff/diff */
302 /* ISDIGIT differs from isdigit, as follows:
303 - Its arg may be any int or unsigned int; it need not be an unsigned char.
304 - It's guaranteed to evaluate its argument exactly once.
305 - It's typically faster.
306 Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
307 only '0' through '9' are digits. Prefer ISDIGIT to isdigit unless
308 it's important to use the locale's definition of `digit' even when the
309 host does not conform to Posix. */
310 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
312 /*#undef __strverscmp
315 #define __strverscmp strverscmp
317 /* Compare S1 and S2 as strings holding indices/version numbers,
318 returning less than, equal to or greater than zero if S1 is less than,
319 equal to or greater than S2 (for more info, see the texinfo doc).
323 strverscmp (const char *s1, const char *s2)
325 const unsigned char *p1 = (const unsigned char *) s1;
326 const unsigned char *p2 = (const unsigned char *) s2;
327 unsigned char c1, c2;
331 /* Symbol(s) 0 [1-9] others (padding)
332 Transition (10) 0 (01) d (00) x (11) - */
333 static const unsigned int next_state[] =
336 /* S_N */ S_N, S_I, S_Z, S_N,
337 /* S_I */ S_N, S_I, S_I, S_I,
338 /* S_F */ S_N, S_F, S_F, S_F,
339 /* S_Z */ S_N, S_F, S_Z, S_Z
342 static const int result_type[] =
344 /* state x/x x/d x/0 x/- d/x d/d d/0 d/-
345 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
347 /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
348 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
349 /* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP,
350 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
351 /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
352 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
353 /* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP,
362 /* Hint: '0' is a digit too. */
363 state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
365 while ((diff = c1 - c2) == 0 && c1 != '\0')
367 state = next_state[state];
370 state |= (c1 == '0') + (ISDIGIT (c1) != 0);
373 state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
381 while (ISDIGIT (*p1++))
382 if (!ISDIGIT (*p2++))
385 return ISDIGIT (*p2) ? -1 : diff;