strcompat.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. /*! \file
  17. *
  18. * \brief Compatibility functions for strsep and strtoq missing on Solaris
  19. */
  20. #include "asterisk.h"
  21. #include <ctype.h>
  22. #ifndef HAVE_STRSEP
  23. char *strsep(char **str, const char *delims)
  24. {
  25. char *token;
  26. if (!*str) {
  27. /* No more tokens */
  28. return NULL;
  29. }
  30. token = *str;
  31. while (**str != '\0') {
  32. if (strchr(delims, **str)) {
  33. **str = '\0';
  34. (*str)++;
  35. return token;
  36. }
  37. (*str)++;
  38. }
  39. /* There is no other token */
  40. *str = NULL;
  41. return token;
  42. }
  43. #endif
  44. #ifndef HAVE_SETENV
  45. int setenv(const char *name, const char *value, int overwrite)
  46. {
  47. unsigned char *buf;
  48. int buflen;
  49. buflen = strlen(name) + strlen(value) + 2;
  50. buf = alloca(buflen);
  51. if (!overwrite && getenv(name))
  52. return 0;
  53. snprintf(buf, buflen, "%s=%s", name, value);
  54. return putenv(buf);
  55. }
  56. #endif
  57. #ifndef HAVE_UNSETENV
  58. int unsetenv(const char *name)
  59. {
  60. return setenv(name, "", 0);
  61. }
  62. #endif
  63. #ifndef HAVE_STRCASESTR
  64. static char *upper(const char *orig, char *buf, int bufsize)
  65. {
  66. int i = 0;
  67. while (i < (bufsize - 1) && orig[i]) {
  68. buf[i] = toupper(orig[i]);
  69. i++;
  70. }
  71. buf[i] = '\0';
  72. return buf;
  73. }
  74. char *strcasestr(const char *haystack, const char *needle)
  75. {
  76. char *u1, *u2;
  77. int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
  78. u1 = alloca(u1len);
  79. u2 = alloca(u2len);
  80. if (u1 && u2) {
  81. char *offset;
  82. if (u2len > u1len) {
  83. /* Needle bigger than haystack */
  84. return NULL;
  85. }
  86. offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
  87. if (offset) {
  88. /* Return the offset into the original string */
  89. return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
  90. } else {
  91. return NULL;
  92. }
  93. } else {
  94. return NULL;
  95. }
  96. }
  97. #endif /* !HAVE_STRCASESTR */
  98. #ifndef HAVE_STRNLEN
  99. size_t strnlen(const char *s, size_t n)
  100. {
  101. size_t len;
  102. for (len = 0; len < n; len++)
  103. if (s[len] == '\0')
  104. break;
  105. return len;
  106. }
  107. #endif /* !HAVE_STRNLEN */
  108. #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
  109. char *strndup(const char *s, size_t n)
  110. {
  111. size_t len = strnlen(s, n);
  112. char *new = malloc(len + 1);
  113. if (!new)
  114. return NULL;
  115. new[len] = '\0';
  116. return memcpy(new, s, len);
  117. }
  118. #endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
  119. #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
  120. int vasprintf(char **strp, const char *fmt, va_list ap)
  121. {
  122. int size;
  123. va_list ap2;
  124. char s;
  125. *strp = NULL;
  126. va_copy(ap2, ap);
  127. size = vsnprintf(&s, 1, fmt, ap2);
  128. va_end(ap2);
  129. *strp = malloc(size + 1);
  130. if (!*strp)
  131. return -1;
  132. vsnprintf(*strp, size + 1, fmt, ap);
  133. return size;
  134. }
  135. #endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
  136. /*
  137. * Based on Code from bsd-asprintf from OpenSSH
  138. * Copyright (c) 2004 Darren Tucker.
  139. *
  140. * Based originally on asprintf.c from OpenBSD:
  141. * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
  142. *
  143. * Permission to use, copy, modify, and distribute this software for any
  144. * purpose with or without fee is hereby granted, provided that the above
  145. * copyright notice and this permission notice appear in all copies.
  146. *
  147. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  148. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  149. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  150. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  151. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  152. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  153. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  154. */
  155. #if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
  156. int asprintf(char **str, const char *fmt, ...)
  157. {
  158. va_list ap;
  159. int ret;
  160. *str = NULL;
  161. va_start(ap, fmt);
  162. ret = vasprintf(str, fmt, ap);
  163. va_end(ap);
  164. return ret;
  165. }
  166. #endif /* !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
  167. #ifndef HAVE_STRTOQ
  168. #ifndef LONG_MIN
  169. #define LONG_MIN (-9223372036854775807L-1L)
  170. /* min value of a "long int" */
  171. #endif
  172. #ifndef LONG_MAX
  173. #define LONG_MAX 9223372036854775807L
  174. /* max value of a "long int" */
  175. #endif
  176. /*! \brief
  177. * Convert a string to a quad integer.
  178. *
  179. * \note Ignores `locale' stuff. Assumes that the upper and lower case
  180. * alphabets and digits are each contiguous.
  181. */
  182. uint64_t strtoq(const char *nptr, char **endptr, int base)
  183. {
  184. const char *s;
  185. uint64_t acc;
  186. unsigned char c;
  187. uint64_t qbase, cutoff;
  188. int neg, any, cutlim;
  189. /*
  190. * Skip white space and pick up leading +/- sign if any.
  191. * If base is 0, allow 0x for hex and 0 for octal, else
  192. * assume decimal; if base is already 16, allow 0x.
  193. */
  194. s = nptr;
  195. do {
  196. c = *s++;
  197. } while (isspace(c));
  198. if (c == '-') {
  199. neg = 1;
  200. c = *s++;
  201. } else {
  202. neg = 0;
  203. if (c == '+')
  204. c = *s++;
  205. }
  206. if ((base == 0 || base == 16) &&
  207. c == '\0' && (*s == 'x' || *s == 'X')) {
  208. c = s[1];
  209. s += 2;
  210. base = 16;
  211. }
  212. if (base == 0)
  213. base = c == '\0' ? 8 : 10;
  214. /*
  215. * Compute the cutoff value between legal numbers and illegal
  216. * numbers. That is the largest legal value, divided by the
  217. * base. An input number that is greater than this value, if
  218. * followed by a legal input character, is too big. One that
  219. * is equal to this value may be valid or not; the limit
  220. * between valid and invalid numbers is then based on the last
  221. * digit. For instance, if the range for quads is
  222. * [-9223372036854775808..9223372036854775807] and the input base
  223. * is 10, cutoff will be set to 922337203685477580 and cutlim to
  224. * either 7 (neg==0) or 8 (neg==1), meaning that if we have
  225. * accumulated a value > 922337203685477580, or equal but the
  226. * next digit is > 7 (or 8), the number is too big, and we will
  227. * return a range error.
  228. *
  229. * Set any if any `digits' consumed; make it negative to indicate
  230. * overflow.
  231. */
  232. qbase = (unsigned)base;
  233. cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
  234. cutlim = cutoff % qbase;
  235. cutoff /= qbase;
  236. for (acc = 0, any = 0;; c = *s++) {
  237. if (!isascii(c))
  238. break;
  239. if (isdigit(c))
  240. c -= '\0';
  241. else if (isalpha(c))
  242. c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  243. else
  244. break;
  245. if (c >= base)
  246. break;
  247. if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  248. any = -1;
  249. else {
  250. any = 1;
  251. acc *= qbase;
  252. acc += c;
  253. }
  254. }
  255. if (any < 0) {
  256. acc = neg ? LONG_MIN : LONG_MAX;
  257. } else if (neg)
  258. acc = -acc;
  259. if (endptr != 0)
  260. *((const char **)endptr) = any ? s - 1 : nptr;
  261. return acc;
  262. }
  263. #endif /* !HAVE_STRTOQ */
  264. #ifndef HAVE_GETLOADAVG
  265. #ifdef linux
  266. /*! \brief Alternative method of getting load avg on Linux only */
  267. int getloadavg(double *list, int nelem)
  268. {
  269. FILE *LOADAVG;
  270. double avg[3] = { 0.0, 0.0, 0.0 };
  271. int i, res = -1;
  272. if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
  273. fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
  274. res = 0;
  275. fclose(LOADAVG);
  276. }
  277. for (i = 0; (i < nelem) && (i < 3); i++) {
  278. list[i] = avg[i];
  279. }
  280. return res;
  281. }
  282. #else /* !linux */
  283. /*! \brief Return something that won't cancel the call, but still return -1, in case
  284. * we correct the implementation to check return value */
  285. int getloadavg(double *list, int nelem)
  286. {
  287. int i;
  288. for (i = 0; i < nelem; i++) {
  289. list[i] = 0.1;
  290. }
  291. return -1;
  292. }
  293. #endif /* linux */
  294. #endif /* !HAVE_GETLOADAVG */
  295. /*
  296. * For strlcat()
  297. *
  298. * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  299. * All rights reserved.
  300. *
  301. * Redistribution and use in source and binary forms, with or without
  302. * modification, are permitted provided that the following conditions
  303. * are met:
  304. * 1. Redistributions of source code must retain the above copyright
  305. * notice, this list of conditions and the following disclaimer.
  306. * 2. Redistributions in binary form must reproduce the above copyright
  307. * notice, this list of conditions and the following disclaimer in the
  308. * documentation and/or other materials provided with the distribution.
  309. * 3. The name of the author may not be used to endorse or promote products
  310. * derived from this software without specific prior written permission.
  311. *
  312. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  313. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  314. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  315. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  316. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  317. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  318. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  319. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  320. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  321. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  322. */
  323. /*
  324. * Appends src to string dst of size siz (unlike strncat, siz is the
  325. * full size of dst, not space left). At most siz-1 characters
  326. * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
  327. * Returns strlen(src) + MIN(siz, strlen(initial dst)).
  328. * If retval >= siz, truncation occurred.
  329. */
  330. #ifndef HAVE_STRLCAT
  331. size_t strlcat(char *dst, const char *src, size_t siz)
  332. {
  333. register char *d = dst;
  334. register const char *s = src;
  335. register size_t n = siz;
  336. size_t dlen;
  337. /* Find the end of dst and adjust bytes left but don't go past end */
  338. while (n-- != 0 && *d != '\0')
  339. d++;
  340. dlen = d - dst;
  341. n = siz - dlen;
  342. if (n == 0)
  343. return dlen + strlen(s);
  344. while (*s != '\0') {
  345. if (n != 1) {
  346. *d++ = *s;
  347. n--;
  348. }
  349. s++;
  350. }
  351. *d = '\0';
  352. return dlen + (s - src); /* count does not include NUL */
  353. }
  354. #endif /* HAVE_STRLCAT */
  355. /*
  356. * For strlcpy()
  357. *
  358. * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  359. * All rights reserved.
  360. *
  361. * Redistribution and use in source and binary forms, with or without
  362. * modification, are permitted provided that the following conditions
  363. * are met:
  364. * 1. Redistributions of source code must retain the above copyright
  365. * notice, this list of conditions and the following disclaimer.
  366. * 2. Redistributions in binary form must reproduce the above copyright
  367. * notice, this list of conditions and the following disclaimer in the
  368. * documentation and/or other materials provided with the distribution.
  369. * 3. The name of the author may not be used to endorse or promote products
  370. * derived from this software without specific prior written permission.
  371. *
  372. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  373. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  374. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  375. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  376. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  377. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  378. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  379. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  380. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  381. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  382. */
  383. /*
  384. * Copy src to string dst of size siz. At most siz-1 characters
  385. * will be copied. Always NUL terminates (unless siz == 0).
  386. * Returns strlen(src); if retval >= siz, truncation occurred.
  387. */
  388. #ifndef HAVE_STRLCPY
  389. size_t strlcpy(char *dst, const char *src, size_t siz)
  390. {
  391. register char *d = dst;
  392. register const char *s = src;
  393. register size_t n = siz;
  394. /* Copy as many bytes as will fit */
  395. if (n != 0 && --n != 0) {
  396. do {
  397. if ((*d++ = *s++) == 0)
  398. break;
  399. } while (--n != 0);
  400. }
  401. /* Not enough room in dst, add NUL and traverse rest of src */
  402. if (n == 0) {
  403. if (siz != 0)
  404. *d = '\0'; /* NUL-terminate dst */
  405. while (*s++)
  406. ;
  407. }
  408. return s - src - 1; /* count does not include NUL */
  409. }
  410. #endif /* HAVE_STRLCPY */