fixed/cleanup osx xcode project/make
[xbmc:xbmc-antiquated.git] / XBMC / xbmc / osx / OSXGNUReplacements.c
1 /*
2  *      Copyright (C) 2005-2009 Team XBMC
3  *      http://www.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, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <netdb.h>
26 #include <pthread.h>
27 #include <errno.h>
28
29 #include "OSXGNUReplacements.h"
30
31 size_t strnlen(const char *s, size_t n)
32 {
33   size_t i;
34   for (i=0; i<n && s[i] != '\0'; i++)
35     /* noop */ ;
36   return i;
37 }
38
39 char* strndup(char const *s, size_t n)
40 {
41   size_t len = strnlen(s, n);
42   char *new_str = (char*)malloc(len + 1);
43   if (new_str == NULL)
44     return NULL;
45   new_str[len] = '\0';
46   
47   return (char*)memcpy(new_str, s, len);
48
49
50 /*
51 From http://svn.digium.com/view/asterisk/trunk/main/utils.c
52 GNU General Public License Version 2
53 Brief Reentrant replacement for gethostbyname for BSD-based systems. Note This
54 routine is derived from code originally written and placed in the public 
55 domain by Enzo Michelangeli <em@em.no-ip.com> 
56 */
57 static pthread_mutex_t gethostbyname_r_mutex = PTHREAD_MUTEX_INITIALIZER;
58 //
59 int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
60                 size_t buflen, struct hostent **result, int *h_errnop) 
61 {
62   int hsave;
63   struct hostent *ph;
64   pthread_mutex_lock(&gethostbyname_r_mutex); /* begin critical area */
65   hsave = h_errno;
66
67   ph = gethostbyname(name);
68   *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
69   if (ph == NULL) {
70       *result = NULL;
71   } else {
72     char **p, **q;
73     char *pbuf;
74     int nbytes = 0;
75     int naddr = 0, naliases = 0;
76     /* determine if we have enough space in buf */
77
78     /* count how many addresses */
79     for (p = ph->h_addr_list; *p != 0; p++) {
80       nbytes += ph->h_length; /* addresses */
81       nbytes += sizeof(*p); /* pointers */
82       naddr++;
83     }
84     nbytes += sizeof(*p); /* one more for the terminating NULL */
85
86     /* count how many aliases, and total length of strings */
87     for (p = ph->h_aliases; *p != 0; p++) {
88       nbytes += (strlen(*p)+1); /* aliases */
89       nbytes += sizeof(*p);  /* pointers */
90       naliases++;
91     }
92     nbytes += sizeof(*p); /* one more for the terminating NULL */
93
94     /* here nbytes is the number of bytes required in buffer */
95     /* as a terminator must be there, the minimum value is ph->h_length */
96     if (nbytes > buflen) {
97       *result = NULL;
98       pthread_mutex_unlock(&gethostbyname_r_mutex); /* end critical area */
99       return ERANGE; /* not enough space in buf!! */
100     }
101
102     /* There is enough space. Now we need to do a deep copy! */
103     /* Allocation in buffer:
104         from [0] to [(naddr-1) * sizeof(*p)]:
105         pointers to addresses
106         at [naddr * sizeof(*p)]:
107         NULL
108         from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
109         pointers to aliases
110         at [(naddr+naliases+1) * sizeof(*p)]:
111         NULL
112         then naddr addresses (fixed length), and naliases aliases (asciiz).
113     */
114
115     *ret = *ph;   /* copy whole structure (not its address!) */
116
117     /* copy addresses */
118     q = (char **)buf; /* pointer to pointers area (type: char **) */
119     ret->h_addr_list = q; /* update pointer to address list */
120     pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
121     for (p = ph->h_addr_list; *p != 0; p++) {
122       memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
123       *q++ = pbuf; /* the pointer is the one inside buf... */
124       pbuf += ph->h_length; /* advance pbuf */
125     }
126     *q++ = NULL; /* address list terminator */
127
128     /* copy aliases */
129     ret->h_aliases = q; /* update pointer to aliases list */
130     for (p = ph->h_aliases; *p != 0; p++) {
131       strcpy(pbuf, *p); /* copy alias strings */
132       *q++ = pbuf; /* the pointer is the one inside buf... */
133       pbuf += strlen(*p); /* advance pbuf */
134       *pbuf++ = 0; /* string terminator */
135     }
136     *q++ = NULL; /* terminator */
137
138     strcpy(pbuf, ph->h_name); /* copy alias strings */
139     ret->h_name = pbuf;
140     pbuf += strlen(ph->h_name); /* advance pbuf */
141     *pbuf++ = 0; /* string terminator */
142
143     *result = ret;  /* and let *result point to structure */
144
145   }
146   h_errno = hsave;  /* restore h_errno */
147   pthread_mutex_unlock(&gethostbyname_r_mutex); /* end critical area */
148
149   return (*result == NULL); /* return 0 on success, non-zero on error */
150 }
151
152 /* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
153    This file is part of the GNU C Library.
154
155    The GNU C Library is free software; you can redistribute it and/or
156    modify it under the terms of the GNU Library General Public License as
157    published by the Free Software Foundation; either version 2 of the
158    License, or (at your option) any later version.
159
160    The GNU C Library is distributed in the hope that it will be useful,
161    but WITHOUT ANY WARRANTY; without even the implied warranty of
162    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
163    Library General Public License for more details.
164
165    You should have received a copy of the GNU Library General Public
166    License along with the GNU C Library; see the file COPYING.LIB.  If not,
167    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
168    Boston, MA 02111-1307, USA.
169 */
170
171 #include <stddef.h>
172 #include <stdio.h>
173 #include <stdlib.h>
174 #include <string.h>
175 #include <limits.h>
176 #include <errno.h>
177
178 /* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
179    (and null-terminate it). *LINEPTR is a pointer returned from malloc (or
180    NULL), pointing to *N characters of space.  It is realloc'd as
181    necessary.  Returns the number of characters read (not including the
182    null terminator), or -1 on error or EOF.  */
183
184 ssize_t
185 getdelim (lineptr, n, terminator, stream)
186      char **lineptr;
187      size_t *n;
188      int terminator;
189      FILE *stream;
190 {
191   char *line, *p;
192   size_t size, copy;
193
194   if (stream == NULL || lineptr == NULL || n == NULL)
195     {
196       errno = EINVAL;
197       return -1;
198     }
199
200   if (ferror (stream))
201     return -1;
202
203   /* Make sure we have a line buffer to start with.  */
204   if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars.  */
205     {
206 #ifndef MAX_CANON
207 #define MAX_CANON       256
208 #endif
209       line = realloc (*lineptr, MAX_CANON);
210       if (line == NULL)
211         return -1;
212       *lineptr = line;
213       *n = MAX_CANON;
214     }
215
216   line = *lineptr;
217   size = *n;
218
219   copy = size;
220   p = line;
221
222       while (1)
223         {
224           size_t len;
225
226           while (--copy > 0)
227             {
228               register int c = getc (stream);
229               if (c == EOF)
230                 goto lose;
231               else if ((*p++ = c) == terminator)
232                 goto win;
233             }
234
235           /* Need to enlarge the line buffer.  */
236           len = p - line;
237           size *= 2;
238           line = realloc (line, size);
239           if (line == NULL)
240             goto lose;
241           *lineptr = line;
242           *n = size;
243           p = line + len;
244           copy = size - len;
245         }
246
247  lose:
248   if (p == *lineptr)
249     return -1;
250   /* Return a partial line since we got an error in the middle.  */
251  win:
252   *p = '\0';
253   return p - *lineptr;
254 }
255