strcompat.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  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. * .. and lots of other functions too.
  21. */
  22. /*** MODULEINFO
  23. <support_level>core</support_level>
  24. ***/
  25. #include "asterisk.h"
  26. #include <ctype.h>
  27. #include <sys/time.h> /* for getrlimit(2) */
  28. #include <sys/resource.h> /* for getrlimit(2) */
  29. #include <sys/types.h> /* for opendir(3) */
  30. #include <dirent.h> /* for opendir(3) */
  31. #include <unistd.h> /* for fcntl(2) */
  32. #include <fcntl.h> /* for fcntl(2) */
  33. #include "asterisk/utils.h"
  34. #ifndef HAVE_STRSEP
  35. char *strsep(char **str, const char *delims)
  36. {
  37. char *token;
  38. if (!*str) {
  39. /* No more tokens */
  40. return NULL;
  41. }
  42. token = *str;
  43. while (**str != '\0') {
  44. if (strchr(delims, **str)) {
  45. **str = '\0';
  46. (*str)++;
  47. return token;
  48. }
  49. (*str)++;
  50. }
  51. /* There is no other token */
  52. *str = NULL;
  53. return token;
  54. }
  55. #endif
  56. #ifndef HAVE_SETENV
  57. int setenv(const char *name, const char *value, int overwrite)
  58. {
  59. unsigned char *buf;
  60. int buflen;
  61. if (!overwrite && getenv(name))
  62. return 0;
  63. buflen = strlen(name) + strlen(value) + 2;
  64. buf = ast_alloca(buflen);
  65. snprintf(buf, buflen, "%s=%s", name, value);
  66. return putenv(buf);
  67. }
  68. #endif
  69. #ifndef HAVE_UNSETENV
  70. int unsetenv(const char *name)
  71. {
  72. return setenv(name, "", 0);
  73. }
  74. #endif
  75. #ifndef HAVE_STRCASESTR
  76. static char *upper(const char *orig, char *buf, int bufsize)
  77. {
  78. int i = 0;
  79. while (i < (bufsize - 1) && orig[i]) {
  80. buf[i] = toupper(orig[i]);
  81. i++;
  82. }
  83. buf[i] = '\0';
  84. return buf;
  85. }
  86. char *strcasestr(const char *haystack, const char *needle)
  87. {
  88. char *u1, *u2;
  89. char *offset;
  90. int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
  91. if (u2len > u1len) {
  92. /* Needle bigger than haystack */
  93. return NULL;
  94. }
  95. u1 = ast_alloca(u1len);
  96. u2 = ast_alloca(u2len);
  97. offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
  98. if (offset) {
  99. /* Return the offset into the original string */
  100. return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
  101. } else {
  102. return NULL;
  103. }
  104. }
  105. #endif /* !HAVE_STRCASESTR */
  106. #ifndef HAVE_STRNLEN
  107. size_t strnlen(const char *s, size_t n)
  108. {
  109. size_t len;
  110. for (len = 0; len < n; len++)
  111. if (s[len] == '\0')
  112. break;
  113. return len;
  114. }
  115. #endif /* !HAVE_STRNLEN */
  116. #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
  117. char *strndup(const char *s, size_t n)
  118. {
  119. size_t len = strnlen(s, n);
  120. char *new = malloc(len + 1);
  121. if (!new)
  122. return NULL;
  123. new[len] = '\0';
  124. return memcpy(new, s, len);
  125. }
  126. #endif /* !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC) */
  127. #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
  128. int vasprintf(char **strp, const char *fmt, va_list ap)
  129. {
  130. int size;
  131. va_list ap2;
  132. char s;
  133. *strp = NULL;
  134. va_copy(ap2, ap);
  135. size = vsnprintf(&s, 1, fmt, ap2);
  136. va_end(ap2);
  137. *strp = malloc(size + 1);
  138. if (!*strp)
  139. return -1;
  140. vsnprintf(*strp, size + 1, fmt, ap);
  141. return size;
  142. }
  143. #endif /* !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
  144. #ifndef HAVE_TIMERSUB
  145. void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
  146. {
  147. tvdiff->tv_sec = tvend->tv_sec - tvstart->tv_sec;
  148. tvdiff->tv_usec = tvend->tv_usec - tvstart->tv_usec;
  149. if (tvdiff->tv_usec < 0) {
  150. tvdiff->tv_sec --;
  151. tvdiff->tv_usec += 1000000;
  152. }
  153. }
  154. #endif
  155. /*
  156. * Based on Code from bsd-asprintf from OpenSSH
  157. * Copyright (c) 2004 Darren Tucker.
  158. *
  159. * Based originally on asprintf.c from OpenBSD:
  160. * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
  161. *
  162. * Permission to use, copy, modify, and distribute this software for any
  163. * purpose with or without fee is hereby granted, provided that the above
  164. * copyright notice and this permission notice appear in all copies.
  165. *
  166. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  167. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  168. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  169. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  170. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  171. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  172. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  173. */
  174. #if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
  175. int asprintf(char **str, const char *fmt, ...)
  176. {
  177. va_list ap;
  178. int ret;
  179. *str = NULL;
  180. va_start(ap, fmt);
  181. ret = vasprintf(str, fmt, ap);
  182. va_end(ap);
  183. return ret;
  184. }
  185. #endif /* !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC) */
  186. #ifndef HAVE_STRTOQ
  187. #ifndef LONG_MIN
  188. #define LONG_MIN (-9223372036854775807L-1L)
  189. /* min value of a "long int" */
  190. #endif
  191. #ifndef LONG_MAX
  192. #define LONG_MAX 9223372036854775807L
  193. /* max value of a "long int" */
  194. #endif
  195. /*! \brief
  196. * Convert a string to a quad integer.
  197. *
  198. * \note Ignores `locale' stuff. Assumes that the upper and lower case
  199. * alphabets and digits are each contiguous.
  200. */
  201. uint64_t strtoq(const char *nptr, char **endptr, int base)
  202. {
  203. const char *s;
  204. uint64_t acc;
  205. unsigned char c;
  206. uint64_t qbase, cutoff;
  207. int neg, any, cutlim;
  208. /*
  209. * Skip white space and pick up leading +/- sign if any.
  210. * If base is 0, allow 0x for hex and 0 for octal, else
  211. * assume decimal; if base is already 16, allow 0x.
  212. */
  213. s = nptr;
  214. do {
  215. c = *s++;
  216. } while (isspace(c));
  217. if (c == '-') {
  218. neg = 1;
  219. c = *s++;
  220. } else {
  221. neg = 0;
  222. if (c == '+')
  223. c = *s++;
  224. }
  225. if ((base == 0 || base == 16) &&
  226. c == '\0' && (*s == 'x' || *s == 'X')) {
  227. c = s[1];
  228. s += 2;
  229. base = 16;
  230. }
  231. if (base == 0)
  232. base = c == '\0' ? 8 : 10;
  233. /*
  234. * Compute the cutoff value between legal numbers and illegal
  235. * numbers. That is the largest legal value, divided by the
  236. * base. An input number that is greater than this value, if
  237. * followed by a legal input character, is too big. One that
  238. * is equal to this value may be valid or not; the limit
  239. * between valid and invalid numbers is then based on the last
  240. * digit. For instance, if the range for quads is
  241. * [-9223372036854775808..9223372036854775807] and the input base
  242. * is 10, cutoff will be set to 922337203685477580 and cutlim to
  243. * either 7 (neg==0) or 8 (neg==1), meaning that if we have
  244. * accumulated a value > 922337203685477580, or equal but the
  245. * next digit is > 7 (or 8), the number is too big, and we will
  246. * return a range error.
  247. *
  248. * Set any if any `digits' consumed; make it negative to indicate
  249. * overflow.
  250. */
  251. qbase = (unsigned)base;
  252. cutoff = neg ? (uint64_t)-(LONG_MIN + LONG_MAX) + LONG_MAX : LONG_MAX;
  253. cutlim = cutoff % qbase;
  254. cutoff /= qbase;
  255. for (acc = 0, any = 0;; c = *s++) {
  256. if (!isascii(c))
  257. break;
  258. if (isdigit(c))
  259. c -= '\0';
  260. else if (isalpha(c))
  261. c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  262. else
  263. break;
  264. if (c >= base)
  265. break;
  266. if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
  267. any = -1;
  268. else {
  269. any = 1;
  270. acc *= qbase;
  271. acc += c;
  272. }
  273. }
  274. if (any < 0) {
  275. acc = neg ? LONG_MIN : LONG_MAX;
  276. } else if (neg)
  277. acc = -acc;
  278. if (endptr != 0)
  279. *((const char **)endptr) = any ? s - 1 : nptr;
  280. return acc;
  281. }
  282. #endif /* !HAVE_STRTOQ */
  283. #ifndef HAVE_GETLOADAVG
  284. #ifdef linux
  285. /*! \brief Alternative method of getting load avg on Linux only */
  286. int getloadavg(double *list, int nelem)
  287. {
  288. FILE *LOADAVG;
  289. double avg[3] = { 0.0, 0.0, 0.0 };
  290. int i, res = -1;
  291. if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
  292. fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
  293. res = 0;
  294. fclose(LOADAVG);
  295. }
  296. for (i = 0; (i < nelem) && (i < 3); i++) {
  297. list[i] = avg[i];
  298. }
  299. return res;
  300. }
  301. #else /* !linux */
  302. /*! \brief Return something that won't cancel the call, but still return -1, in case
  303. * we correct the implementation to check return value */
  304. int getloadavg(double *list, int nelem)
  305. {
  306. int i;
  307. for (i = 0; i < nelem; i++) {
  308. list[i] = 0.1;
  309. }
  310. return -1;
  311. }
  312. #endif /* linux */
  313. #endif /* !HAVE_GETLOADAVG */
  314. #ifndef HAVE_NTOHLL
  315. uint64_t ntohll(uint64_t net64)
  316. {
  317. #if BYTE_ORDER == BIG_ENDIAN
  318. return net64;
  319. #elif BYTE_ORDER == LITTLE_ENDIAN
  320. union {
  321. unsigned char c[8];
  322. uint64_t u;
  323. } number;
  324. number.u = net64;
  325. return
  326. (((uint64_t) number.c[0]) << 56) |
  327. (((uint64_t) number.c[1]) << 48) |
  328. (((uint64_t) number.c[2]) << 40) |
  329. (((uint64_t) number.c[3]) << 32) |
  330. (((uint64_t) number.c[4]) << 24) |
  331. (((uint64_t) number.c[5]) << 16) |
  332. (((uint64_t) number.c[6]) << 8) |
  333. (((uint64_t) number.c[7]) << 0);
  334. #else
  335. #error "Unknown byte order"
  336. #endif
  337. }
  338. #endif
  339. #ifndef HAVE_HTONLL
  340. uint64_t htonll(uint64_t host64)
  341. {
  342. #if BYTE_ORDER == BIG_ENDIAN
  343. return host64;
  344. #elif BYTE_ORDER == LITTLE_ENDIAN
  345. union {
  346. unsigned char c[8];
  347. uint64_t u;
  348. } number;
  349. number.u = host64;
  350. return
  351. (((uint64_t) number.c[0]) << 56) |
  352. (((uint64_t) number.c[1]) << 48) |
  353. (((uint64_t) number.c[2]) << 40) |
  354. (((uint64_t) number.c[3]) << 32) |
  355. (((uint64_t) number.c[4]) << 24) |
  356. (((uint64_t) number.c[5]) << 16) |
  357. (((uint64_t) number.c[6]) << 8) |
  358. (((uint64_t) number.c[7]) << 0);
  359. #else
  360. #error "Unknown byte order"
  361. #endif
  362. }
  363. #endif
  364. #ifndef HAVE_FFSLL
  365. int ffsll(long long n)
  366. {
  367. int i;
  368. for (i = 0; i < 64; i++) {
  369. if ((1LL << i) & n) {
  370. return i + 1;
  371. }
  372. }
  373. return 0;
  374. }
  375. #endif
  376. #ifndef HAVE_CLOSEFROM
  377. void closefrom(int n)
  378. {
  379. long x;
  380. struct rlimit rl;
  381. DIR *dir;
  382. char path[16], *result;
  383. struct dirent *entry;
  384. snprintf(path, sizeof(path), "/proc/%d/fd", (int) getpid());
  385. if ((dir = opendir(path))) {
  386. while ((entry = readdir(dir))) {
  387. /* Skip . and .. */
  388. if (entry->d_name[0] == '.') {
  389. continue;
  390. }
  391. if ((x = strtol(entry->d_name, &result, 10)) && x >= n) {
  392. #ifdef STRICT_COMPAT
  393. close(x);
  394. #else
  395. /* This isn't strictly compatible, but it's actually faster
  396. * for our purposes to set the CLOEXEC flag than to close
  397. * file descriptors.
  398. */
  399. long flags = fcntl(x, F_GETFD);
  400. if (flags == -1 && errno == EBADF) {
  401. continue;
  402. }
  403. fcntl(x, F_SETFD, flags | FD_CLOEXEC);
  404. #endif
  405. }
  406. }
  407. closedir(dir);
  408. } else {
  409. getrlimit(RLIMIT_NOFILE, &rl);
  410. if (rl.rlim_cur > 65535) {
  411. /* A more reasonable value. Consider that the primary source of
  412. * file descriptors in Asterisk are UDP sockets, of which we are
  413. * limited to 65,535 per address. We additionally limit that down
  414. * to about 10,000 sockets per protocol. While the kernel will
  415. * allow us to set the fileno limit higher (up to 4.2 billion),
  416. * there really is no practical reason for it to be that high.
  417. */
  418. rl.rlim_cur = 65535;
  419. }
  420. for (x = n; x < rl.rlim_cur; x++) {
  421. #ifdef STRICT_COMPAT
  422. close(x);
  423. #else
  424. long flags = fcntl(x, F_GETFD);
  425. if (flags == -1 && errno == EBADF) {
  426. continue;
  427. }
  428. fcntl(x, F_SETFD, flags | FD_CLOEXEC);
  429. #endif
  430. }
  431. }
  432. }
  433. #endif
  434. #ifndef HAVE_MKDTEMP
  435. /* $OpenBSD: mktemp.c,v 1.30 2010/03/21 23:09:30 schwarze Exp $ */
  436. /*
  437. * Copyright (c) 1996-1998, 2008 Theo de Raadt
  438. * Copyright (c) 1997, 2008-2009 Todd C. Miller
  439. *
  440. * Permission to use, copy, modify, and distribute this software for any
  441. * purpose with or without fee is hereby granted, provided that the above
  442. * copyright notice and this permission notice appear in all copies.
  443. *
  444. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  445. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  446. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  447. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  448. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  449. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  450. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  451. */
  452. #define MKTEMP_NAME 0
  453. #define MKTEMP_FILE 1
  454. #define MKTEMP_DIR 2
  455. #define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_."
  456. #define NUM_CHARS (sizeof(TEMPCHARS) - 1)
  457. static int mktemp_internal(char *path, int slen, int mode)
  458. {
  459. char *start, *cp, *ep;
  460. const char *tempchars = TEMPCHARS;
  461. unsigned int r, tries;
  462. struct stat sb;
  463. size_t len;
  464. int fd;
  465. len = strlen(path);
  466. if (len == 0 || slen >= len) {
  467. errno = EINVAL;
  468. return(-1);
  469. }
  470. ep = path + len - slen;
  471. tries = 1;
  472. for (start = ep; start > path && start[-1] == 'X'; start--) {
  473. if (tries < INT_MAX / NUM_CHARS) {
  474. tries *= NUM_CHARS;
  475. }
  476. }
  477. tries *= 2;
  478. do {
  479. for (cp = start; cp != ep; cp++) {
  480. r = ast_random() % NUM_CHARS;
  481. *cp = tempchars[r];
  482. }
  483. switch (mode) {
  484. case MKTEMP_NAME:
  485. if (lstat(path, &sb) != 0) {
  486. return (errno == ENOENT ? 0 : -1);
  487. }
  488. break;
  489. case MKTEMP_FILE:
  490. fd = open(path, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
  491. if (fd != -1 || errno != EEXIST) {
  492. return (fd);
  493. }
  494. break;
  495. case MKTEMP_DIR:
  496. if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0) {
  497. return (0);
  498. }
  499. if (errno != EEXIST) {
  500. return (-1);
  501. }
  502. break;
  503. }
  504. } while (--tries);
  505. errno = EEXIST;
  506. return(-1);
  507. }
  508. char *mkdtemp(char *path)
  509. {
  510. return mktemp_internal(path, 0, MKTEMP_DIR) ? NULL : path;
  511. }
  512. #endif
  513. #ifndef HAVE_ROUNDF
  514. #ifndef HAVE_ROUND
  515. float roundf(float x) {
  516. if (x < 0.0) {
  517. return (float)(int)((x) - 0.5);
  518. } else {
  519. return (float)(int)((x) + 0.5);
  520. }
  521. }
  522. #endif
  523. #endif