Expand codec bitfield from 32 bits to 64 bits.
[asterisk/asterisk.git] / main / strcompat.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Compatibility functions for strsep and strtoq missing on Solaris 
20  */
21
22 #include "asterisk.h"
23
24 #include <ctype.h>
25
26 #ifndef HAVE_STRSEP
27 char *strsep(char **str, const char *delims)
28 {
29         char *token;
30
31         if (!*str) {
32                 /* No more tokens */
33                 return NULL;
34         }
35
36         token = *str;
37         while (**str != '\0') {
38                 if (strchr(delims, **str)) {
39                         **str = '\0';
40                         (*str)++;
41                         return token;
42                 }
43                 (*str)++;
44         }
45
46         /* There is no other token */
47         *str = NULL;
48
49         return token;
50 }
51 #endif
52
53 #ifndef HAVE_SETENV
54 int setenv(const char *name, const char *value, int overwrite)
55 {
56         unsigned char *buf;
57         int buflen;
58
59         buflen = strlen(name) + strlen(value) + 2;
60         buf = alloca(buflen);
61
62         if (!overwrite && getenv(name))
63                 return 0;
64
65         snprintf(buf, buflen, "%s=%s", name, value);
66
67         return putenv(buf);
68 }
69 #endif
70
71 #ifndef HAVE_UNSETENV
72 int unsetenv(const char *name)
73 {
74         return setenv(name, "", 0);
75 }
76 #endif
77
78 #ifndef HAVE_STRCASESTR
79 static char *upper(const char *orig, char *buf, int bufsize)
80 {
81         int i = 0;
82
83         while (i < (bufsize - 1) && orig[i]) {
84                 buf[i] = toupper(orig[i]);
85                 i++;
86         }
87
88         buf[i] = '\0';
89
90         return buf;
91 }
92
93 char *strcasestr(const char *haystack, const char *needle)
94 {
95         char *u1, *u2;
96         int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
97
98         u1 = alloca(u1len);
99         u2 = alloca(u2len);
100         if (u1 && u2) {
101                 char *offset;
102                 if (u2len > u1len) {
103                         /* Needle bigger than haystack */
104                         return NULL;
105                 }
106                 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
107                 if (offset) {
108                         /* Return the offset into the original string */
109                         return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
110                 } else {
111                         return NULL;
112                 }
113         } else {
114                 return NULL;
115         }
116 }
117 #endif /* !HAVE_STRCASESTR */
118
119 #ifndef HAVE_STRNLEN
120 size_t strnlen(const char *s, size_t n)
121 {
122         size_t len;
123
124         for (len = 0; len < n; len++)
125                 if (s[len] == '\0')
126                         break;
127
128         return len;
129 }
130 #endif /* !HAVE_STRNLEN */
131
132 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
133 char *strndup(const char *s, size_t n)
134 {
135         size_t len = strnlen(s, n);
136         char *new = malloc(len + 1);
137
138         if (!new)
139                 return NULL;
140
141         new[len] = '\0';
142         return memcpy(new, s, len);
143 }
144 #endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
145
146 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
147 int vasprintf(char **strp, const char *fmt, va_list ap)
148 {
149         int size;
150         va_list ap2;
151         char s;
152
153         *strp = NULL;
154         va_copy(ap2, ap);
155         size = vsnprintf(&s, 1, fmt, ap2);
156         va_end(ap2);
157         *strp = malloc(size + 1);
158         if (!*strp)
159                 return -1;
160         vsnprintf(*strp, size + 1, fmt, ap);
161
162         return size;
163 }
164 #endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
165
166 /*
167  * Based on Code from bsd-asprintf from OpenSSH
168  * Copyright (c) 2004 Darren Tucker.
169  *
170  * Based originally on asprintf.c from OpenBSD:
171  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
172  *
173  * Permission to use, copy, modify, and distribute this software for any
174  * purpose with or without fee is hereby granted, provided that the above
175  * copyright notice and this permission notice appear in all copies.
176  *
177  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
178  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
179  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
180  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
181  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
182  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
183  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
184  */
185 #if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) 
186 int asprintf(char **str, const char *fmt, ...)
187 {
188         va_list ap;
189         int ret;
190
191         *str = NULL;
192         va_start(ap, fmt);
193         ret = vasprintf(str, fmt, ap);
194         va_end(ap);
195
196         return ret;
197 }
198 #endif /* !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
199
200 #ifndef HAVE_STRTOQ
201 #ifndef LONG_MIN
202 #define LONG_MIN        (-9223372036854775807L-1L)
203                                          /* min value of a "long int" */
204 #endif
205 #ifndef LONG_MAX
206 #define LONG_MAX        9223372036854775807L
207                                          /* max value of a "long int" */
208 #endif
209
210 /*! \brief
211  * Convert a string to a quad integer.
212  *
213  * \note Ignores `locale' stuff.  Assumes that the upper and lower case
214  * alphabets and digits are each contiguous.
215  */
216 uint64_t strtoq(const char *nptr, char **endptr, int base)
217 {
218          const char *s;
219          uint64_t acc;
220          unsigned char c;
221          uint64_t qbase, cutoff;
222          int neg, any, cutlim;
223
224          /*
225           * Skip white space and pick up leading +/- sign if any.
226           * If base is 0, allow 0x for hex and 0 for octal, else
227           * assume decimal; if base is already 16, allow 0x.
228           */
229          s = nptr;
230          do {
231                  c = *s++;
232          } while (isspace(c));
233          if (c == '-') {
234                  neg = 1;
235                  c = *s++;
236          } else {
237                  neg = 0;
238                  if (c == '+')
239                          c = *s++;
240          }
241          if ((base == 0 || base == 16) &&
242              c == '\0' && (*s == 'x' || *s == 'X')) {
243                  c = s[1];
244                  s += 2;
245                  base = 16;
246          }
247          if (base == 0)
248                  base = c == '\0' ? 8 : 10;
249
250          /*
251           * Compute the cutoff value between legal numbers and illegal
252           * numbers.  That is the largest legal value, divided by the
253           * base.  An input number that is greater than this value, if
254           * followed by a legal input character, is too big.  One that
255           * is equal to this value may be valid or not; the limit
256           * between valid and invalid numbers is then based on the last
257           * digit.  For instance, if the range for quads is
258           * [-9223372036854775808..9223372036854775807] and the input base
259           * is 10, cutoff will be set to 922337203685477580 and cutlim to
260           * either 7 (neg==0) or 8 (neg==1), meaning that if we have
261           * accumulated a value > 922337203685477580, or equal but the
262           * next digit is > 7 (or 8), the number is too big, and we will
263           * return a range error.
264           *
265           * Set any if any `digits' consumed; make it negative to indicate
266           * overflow.
267           */
268          qbase = (unsigned)base;
269          cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
270          cutlim = cutoff % qbase;
271          cutoff /= qbase;
272          for (acc = 0, any = 0;; c = *s++) {
273                  if (!isascii(c))
274                          break;
275                  if (isdigit(c))
276                          c -= '\0';
277                  else if (isalpha(c))
278                          c -= isupper(c) ? 'A' - 10 : 'a' - 10;
279                  else
280                          break;
281                  if (c >= base)
282                          break;
283                  if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
284                          any = -1;
285                  else {
286                          any = 1;
287                          acc *= qbase;
288                          acc += c;
289                  }
290          }
291          if (any < 0) {
292                  acc = neg ? LONG_MIN : LONG_MAX;
293          } else if (neg)
294                  acc = -acc;
295          if (endptr != 0)
296                  *((const char **)endptr) = any ? s - 1 : nptr;
297          return acc;
298 }
299 #endif /* !HAVE_STRTOQ */
300
301 #ifndef HAVE_GETLOADAVG
302 #ifdef linux
303 /*! \brief Alternative method of getting load avg on Linux only */
304 int getloadavg(double *list, int nelem)
305 {
306         FILE *LOADAVG;
307         double avg[3] = { 0.0, 0.0, 0.0 };
308         int i, res = -1;
309
310         if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
311                 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
312                 res = 0;
313                 fclose(LOADAVG);
314         }
315
316         for (i = 0; (i < nelem) && (i < 3); i++) {
317                 list[i] = avg[i];
318         }
319
320         return res;
321 }
322 #else /* !linux */
323 /*! \brief Return something that won't cancel the call, but still return -1, in case
324  * we correct the implementation to check return value */
325 int getloadavg(double *list, int nelem)
326 {
327         int i;
328
329         for (i = 0; i < nelem; i++) {
330                 list[i] = 0.1;
331         }
332         return -1;
333 }
334 #endif /* linux */
335 #endif /* !HAVE_GETLOADAVG */
336
337 #ifndef HAVE_NTOHLL
338 uint64_t ntohll(uint64_t net64)
339 {
340 #if BYTE_ORDER == BIG_ENDIAN
341         return net64;
342 #elif BYTE_ORDER == LITTLE_ENDIAN
343         union {
344                 unsigned char c[8];
345                 uint64_t u;
346         } number;
347         number.u = net64;
348         return
349                 (((uint64_t) number.c[0]) <<  0) |
350                 (((uint64_t) number.c[1]) <<  8) |
351                 (((uint64_t) number.c[2]) << 16) |
352                 (((uint64_t) number.c[3]) << 24) |
353                 (((uint64_t) number.c[4]) << 32) |
354                 (((uint64_t) number.c[5]) << 40) |
355                 (((uint64_t) number.c[6]) << 48) |
356                 (((uint64_t) number.c[7]) << 56);
357 #else
358         #error "Unknown byte order"
359 #endif
360 }
361 #endif
362
363 #ifndef HAVE_HTONLL
364 uint64_t htonll(uint64_t host64)
365 {
366 #if BYTE_ORDER == BIG_ENDIAN
367         return host64;
368 #elif BYTE_ORDER == LITTLE_ENDIAN
369         union {
370                 unsigned char c[8];
371                 uint64_t u;
372         } number;
373         number.u = host64;
374         return
375                 (((uint64_t) number.c[0]) <<  0) |
376                 (((uint64_t) number.c[1]) <<  8) |
377                 (((uint64_t) number.c[2]) << 16) |
378                 (((uint64_t) number.c[3]) << 24) |
379                 (((uint64_t) number.c[4]) << 32) |
380                 (((uint64_t) number.c[5]) << 40) |
381                 (((uint64_t) number.c[6]) << 48) |
382                 (((uint64_t) number.c[7]) << 56);
383 #else
384         #error "Unknown byte order"
385 #endif
386 }
387 #endif
388