Remove LiveTV menu.
[vuplus_xbmc] / xbmc / osx / OSXGNUReplacements.c
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20 #if HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #if !defined(HAVE_GNUTLS)
25
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <netdb.h>
30 #include <pthread.h>
31 #include <errno.h>
32
33 #include "OSXGNUReplacements.h"
34
35 size_t strnlen(const char *s, size_t n)
36 {
37   size_t i;
38   for (i=0; i<n && s[i] != '\0'; i++)
39     /* noop */ ;
40   return i;
41 }
42
43 char* strndup(char const *s, size_t n)
44 {
45   size_t len = strnlen(s, n);
46   char *new_str = (char*)malloc(len + 1);
47   if (new_str == NULL)
48     return NULL;
49   new_str[len] = '\0';
50   
51   return (char*)memcpy(new_str, s, len);
52
53
54 /*
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> 
60 */
61 static pthread_mutex_t gethostbyname_r_mutex = PTHREAD_MUTEX_INITIALIZER;
62 //
63 int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
64                 size_t buflen, struct hostent **result, int *h_errnop) 
65 {
66   int hsave;
67   struct hostent *ph;
68   pthread_mutex_lock(&gethostbyname_r_mutex); /* begin critical area */
69   hsave = h_errno;
70
71   ph = gethostbyname(name);
72   *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
73   if (ph == NULL) {
74       *result = NULL;
75   } else {
76     char **p, **q;
77     char *pbuf;
78     int nbytes = 0;
79     int naddr = 0, naliases = 0;
80     /* determine if we have enough space in buf */
81
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 */
86       naddr++;
87     }
88     nbytes += sizeof(*p); /* one more for the terminating NULL */
89
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 */
94       naliases++;
95     }
96     nbytes += sizeof(*p); /* one more for the terminating NULL */
97
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) {
101       *result = NULL;
102       pthread_mutex_unlock(&gethostbyname_r_mutex); /* end critical area */
103       return ERANGE; /* not enough space in buf!! */
104     }
105
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)]:
111         NULL
112         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
113         pointers to aliases
114         at [(naddr+naliases+1) * sizeof(*p)]:
115         NULL
116         then naddr addresses (fixed length), and naliases aliases (asciiz).
117     */
118
119     *ret = *ph;   /* copy whole structure (not its address!) */
120
121     /* copy addresses */
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 */
129     }
130     *q++ = NULL; /* address list terminator */
131
132     /* copy aliases */
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 */
139     }
140     *q++ = NULL; /* terminator */
141
142     strcpy(pbuf, ph->h_name); /* copy alias strings */
143     ret->h_name = pbuf;
144     pbuf += strlen(ph->h_name); /* advance pbuf */
145     *pbuf++ = 0; /* string terminator */
146
147     *result = ret;  /* and let *result point to structure */
148
149   }
150   h_errno = hsave;  /* restore h_errno */
151   pthread_mutex_unlock(&gethostbyname_r_mutex); /* end critical area */
152
153   return (*result == NULL); /* return 0 on success, non-zero on error */
154 }
155
156 /* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
157    This file is part of the GNU C Library.
158
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.
163
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.
168
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.
173 */
174
175 #include <stddef.h>
176 #include <stdio.h>
177 #include <stdlib.h>
178 #include <string.h>
179 #include <limits.h>
180 #include <errno.h>
181
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.  */
187
188 ssize_t
189 getdelim (lineptr, n, terminator, stream)
190      char **lineptr;
191      size_t *n;
192      int terminator;
193      FILE *stream;
194 {
195   char *line, *p;
196   size_t size, copy;
197
198   if (stream == NULL || lineptr == NULL || n == NULL)
199     {
200       errno = EINVAL;
201       return -1;
202     }
203
204   if (ferror (stream))
205     return -1;
206
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.  */
209     {
210 #ifndef MAX_CANON
211 #define MAX_CANON       256
212 #endif
213       line = realloc (*lineptr, MAX_CANON);
214       if (line == NULL)
215         return -1;
216       *lineptr = line;
217       *n = MAX_CANON;
218     }
219
220   line = *lineptr;
221   size = *n;
222
223   copy = size;
224   p = line;
225
226       while (1)
227         {
228           size_t len;
229
230           while (--copy > 0)
231             {
232               register int c = getc (stream);
233               if (c == EOF)
234                 goto lose;
235               else if ((*p++ = c) == terminator)
236                 goto win;
237             }
238
239           /* Need to enlarge the line buffer.  */
240           len = p - line;
241           size *= 2;
242           line = realloc (line, size);
243           if (line == NULL)
244             goto lose;
245           *lineptr = line;
246           *n = size;
247           p = line + len;
248           copy = size - len;
249         }
250
251  lose:
252   if (p == *lineptr)
253     return -1;
254   /* Return a partial line since we got an error in the middle.  */
255  win:
256   *p = '\0';
257   return p - *lineptr;
258 }
259
260 ssize_t
261 getline (char **lineptr, size_t *n, FILE *stream)
262 {
263   return getdelim (lineptr, n, '\n', stream);
264 }
265
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.
270
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.
275
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.
280
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.  */
285
286
287 #include <string.h>
288 #include <ctype.h>
289
290 /* states: S_N: normal, S_I: comparing integral part, S_F: comparing
291            fractional parts, S_Z: idem but with leading Zeroes only */
292 #define S_N    0x0
293 #define S_I    0x4
294 #define S_F    0x8
295 #define S_Z    0xC
296
297 /* result_type: CMP: return diff; LEN: compare using len_diff/diff */
298 #define CMP    2
299 #define LEN    3
300
301
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)
311
312 /*#undef __strverscmp
313 #undef strverscmp
314
315 #define __strverscmp strverscmp
316 */
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).
320 */
321
322 int
323 strverscmp (const char *s1, const char *s2)
324 {
325   const unsigned char *p1 = (const unsigned char *) s1;
326   const unsigned char *p2 = (const unsigned char *) s2;
327   unsigned char c1, c2;
328   int state;
329   int diff;
330
331   /* Symbol(s)    0       [1-9]   others  (padding)
332      Transition   (10) 0  (01) d  (00) x  (11) -   */
333   static const unsigned int next_state[] =
334   {
335       /* state    x    d    0    - */
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
340   };
341
342   static const int result_type[] =
343   {
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  -/- */
346
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,
354                  -1,  CMP, CMP, CMP
355   };
356
357   if (p1 == p2)
358     return 0;
359
360   c1 = *p1++;
361   c2 = *p2++;
362   /* Hint: '0' is a digit too.  */
363   state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
364
365   while ((diff = c1 - c2) == 0 && c1 != '\0')
366     {
367       state = next_state[state];
368       c1 = *p1++;
369       c2 = *p2++;
370       state |= (c1 == '0') + (ISDIGIT (c1) != 0);
371     }
372
373   state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
374
375   switch (state)
376     {
377     case CMP:
378       return diff;
379
380     case LEN:
381       while (ISDIGIT (*p1++))
382         if (!ISDIGIT (*p2++))
383           return 1;
384
385       return ISDIGIT (*p2) ? -1 : diff;
386
387     default:
388       return state;
389     }
390 }
391 #endif