utils.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /*
  2. * Asterisk -- A telephony toolkit for Linux.
  3. *
  4. * Utility functions
  5. *
  6. * Copyright (C) 2004, Digium
  7. *
  8. * This program is free software, distributed under the terms of
  9. * the GNU General Public License
  10. */
  11. #ifdef Linux /* For strcasestr */
  12. #define __USE_GNU
  13. #endif
  14. #include <ctype.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <errno.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <arpa/inet.h>
  23. #include <asterisk/lock.h>
  24. #include <asterisk/utils.h>
  25. #include <asterisk/logger.h>
  26. static char base64[64];
  27. static char b2a[256];
  28. #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__)
  29. /* duh? ERANGE value copied from web... */
  30. #define ERANGE 34
  31. #undef gethostbyname
  32. AST_MUTEX_DEFINE_STATIC(__mutex);
  33. /* Recursive replacement for gethostbyname for BSD-based systems */
  34. static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
  35. size_t buflen, struct hostent **result,
  36. int *h_errnop)
  37. {
  38. int hsave;
  39. struct hostent *ph;
  40. ast_mutex_lock(&__mutex); /* begin critical area */
  41. hsave = h_errno;
  42. ph = gethostbyname(name);
  43. *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
  44. if (ph == NULL) {
  45. *result = NULL;
  46. } else {
  47. char **p, **q;
  48. char *pbuf;
  49. int nbytes=0;
  50. int naddr=0, naliases=0;
  51. /* determine if we have enough space in buf */
  52. /* count how many addresses */
  53. for (p = ph->h_addr_list; *p != 0; p++) {
  54. nbytes += ph->h_length; /* addresses */
  55. nbytes += sizeof(*p); /* pointers */
  56. naddr++;
  57. }
  58. nbytes += sizeof(*p); /* one more for the terminating NULL */
  59. /* count how many aliases, and total length of strings */
  60. for (p = ph->h_aliases; *p != 0; p++) {
  61. nbytes += (strlen(*p)+1); /* aliases */
  62. nbytes += sizeof(*p); /* pointers */
  63. naliases++;
  64. }
  65. nbytes += sizeof(*p); /* one more for the terminating NULL */
  66. /* here nbytes is the number of bytes required in buffer */
  67. /* as a terminator must be there, the minimum value is ph->h_length */
  68. if(nbytes > buflen) {
  69. *result = NULL;
  70. ast_mutex_unlock(&__mutex); /* end critical area */
  71. return ERANGE; /* not enough space in buf!! */
  72. }
  73. /* There is enough space. Now we need to do a deep copy! */
  74. /* Allocation in buffer:
  75. from [0] to [(naddr-1) * sizeof(*p)]:
  76. pointers to addresses
  77. at [naddr * sizeof(*p)]:
  78. NULL
  79. from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
  80. pointers to aliases
  81. at [(naddr+naliases+1) * sizeof(*p)]:
  82. NULL
  83. then naddr addresses (fixed length), and naliases aliases (asciiz).
  84. */
  85. *ret = *ph; /* copy whole structure (not its address!) */
  86. /* copy addresses */
  87. q = (char **)buf; /* pointer to pointers area (type: char **) */
  88. ret->h_addr_list = q; /* update pointer to address list */
  89. pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */
  90. for (p = ph->h_addr_list; *p != 0; p++) {
  91. memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
  92. *q++ = pbuf; /* the pointer is the one inside buf... */
  93. pbuf += ph->h_length; /* advance pbuf */
  94. }
  95. *q++ = NULL; /* address list terminator */
  96. /* copy aliases */
  97. ret->h_aliases = q; /* update pointer to aliases list */
  98. for (p = ph->h_aliases; *p != 0; p++) {
  99. strcpy(pbuf, *p); /* copy alias strings */
  100. *q++ = pbuf; /* the pointer is the one inside buf... */
  101. pbuf += strlen(*p); /* advance pbuf */
  102. *pbuf++ = 0; /* string terminator */
  103. }
  104. *q++ = NULL; /* terminator */
  105. strcpy(pbuf, ph->h_name); /* copy alias strings */
  106. ret->h_name = pbuf;
  107. pbuf += strlen(ph->h_name); /* advance pbuf */
  108. *pbuf++ = 0; /* string terminator */
  109. *result = ret; /* and let *result point to structure */
  110. }
  111. h_errno = hsave; /* restore h_errno */
  112. ast_mutex_unlock(&__mutex); /* end critical area */
  113. return (*result == NULL); /* return 0 on success, non-zero on error */
  114. }
  115. #endif
  116. /* Recursive thread safe version of gethostbyname that replaces the
  117. standard gethostbyname (which is not recursive)
  118. */
  119. struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
  120. {
  121. int res;
  122. int herrno;
  123. const char *s;
  124. struct hostent *result = NULL;
  125. /* Although it is perfectly legitimate to lookup a pure integer, for
  126. the sake of the sanity of people who like to name their peers as
  127. integers, we break with tradition and refuse to look up a
  128. pure integer */
  129. s = host;
  130. while(s && *s) {
  131. if (!isdigit(*s))
  132. break;
  133. s++;
  134. }
  135. if (!s || !*s)
  136. return NULL;
  137. res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
  138. if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
  139. return NULL;
  140. return &hp->hp;
  141. }
  142. /* This is a regression test for recursive mutexes.
  143. test_for_thread_safety() will return 0 if recursive mutex locks are
  144. working properly, and non-zero if they are not working properly. */
  145. AST_MUTEX_DEFINE_STATIC(test_lock);
  146. AST_MUTEX_DEFINE_STATIC(test_lock2);
  147. static pthread_t test_thread;
  148. static int lock_count = 0;
  149. static int test_errors = 0;
  150. static void *test_thread_body(void *data)
  151. {
  152. ast_mutex_lock(&test_lock);
  153. lock_count += 10;
  154. if (lock_count != 10)
  155. test_errors++;
  156. ast_mutex_lock(&test_lock);
  157. lock_count += 10;
  158. if (lock_count != 20)
  159. test_errors++;
  160. ast_mutex_lock(&test_lock2);
  161. ast_mutex_unlock(&test_lock);
  162. lock_count -= 10;
  163. if (lock_count != 10)
  164. test_errors++;
  165. ast_mutex_unlock(&test_lock);
  166. lock_count -= 10;
  167. ast_mutex_unlock(&test_lock2);
  168. if (lock_count != 0)
  169. test_errors++;
  170. return NULL;
  171. }
  172. int test_for_thread_safety(void)
  173. {
  174. ast_mutex_lock(&test_lock2);
  175. ast_mutex_lock(&test_lock);
  176. lock_count += 1;
  177. ast_mutex_lock(&test_lock);
  178. lock_count += 1;
  179. ast_pthread_create(&test_thread, NULL, test_thread_body, NULL);
  180. usleep(100);
  181. if (lock_count != 2)
  182. test_errors++;
  183. ast_mutex_unlock(&test_lock);
  184. lock_count -= 1;
  185. usleep(100);
  186. if (lock_count != 1)
  187. test_errors++;
  188. ast_mutex_unlock(&test_lock);
  189. lock_count -= 1;
  190. if (lock_count != 0)
  191. test_errors++;
  192. ast_mutex_unlock(&test_lock2);
  193. usleep(100);
  194. if (lock_count != 0)
  195. test_errors++;
  196. pthread_join(test_thread, NULL);
  197. return(test_errors); /* return 0 on success. */
  198. }
  199. int ast_base64decode(unsigned char *dst, char *src, int max)
  200. {
  201. int cnt = 0;
  202. unsigned int byte = 0;
  203. unsigned int bits = 0;
  204. int incnt = 0;
  205. #if 0
  206. unsigned char *odst = dst;
  207. #endif
  208. while(*src && (cnt < max)) {
  209. /* Shift in 6 bits of input */
  210. byte <<= 6;
  211. byte |= (b2a[(int)(*src)]) & 0x3f;
  212. bits += 6;
  213. #if 0
  214. printf("Add: %c %s\n", *src, binary(b2a[(int)(*src)] & 0x3f, 6));
  215. #endif
  216. src++;
  217. incnt++;
  218. /* If we have at least 8 bits left over, take that character
  219. off the top */
  220. if (bits >= 8) {
  221. bits -= 8;
  222. *dst = (byte >> bits) & 0xff;
  223. #if 0
  224. printf("Remove: %02x %s\n", *dst, binary(*dst, 8));
  225. #endif
  226. dst++;
  227. cnt++;
  228. }
  229. }
  230. #if 0
  231. dump(odst, cnt);
  232. #endif
  233. /* Dont worry about left over bits, they're extra anyway */
  234. return cnt;
  235. }
  236. int ast_base64encode(char *dst, unsigned char *src, int srclen, int max)
  237. {
  238. int cnt = 0;
  239. unsigned int byte = 0;
  240. int bits = 0;
  241. int index;
  242. int cntin = 0;
  243. #if 0
  244. char *odst = dst;
  245. dump(src, srclen);
  246. #endif
  247. /* Reserve one bit for end */
  248. max--;
  249. while((cntin < srclen) && (cnt < max)) {
  250. byte <<= 8;
  251. #if 0
  252. printf("Add: %02x %s\n", *src, binary(*src, 8));
  253. #endif
  254. byte |= *(src++);
  255. bits += 8;
  256. cntin++;
  257. while((bits >= 6) && (cnt < max)) {
  258. bits -= 6;
  259. /* We want only the top */
  260. index = (byte >> bits) & 0x3f;
  261. *dst = base64[index];
  262. #if 0
  263. printf("Remove: %c %s\n", *dst, binary(index, 6));
  264. #endif
  265. dst++;
  266. cnt++;
  267. }
  268. }
  269. if (bits && (cnt < max)) {
  270. /* Add one last character for the remaining bits,
  271. padding the rest with 0 */
  272. byte <<= (6 - bits);
  273. index = (byte) & 0x3f;
  274. *(dst++) = base64[index];
  275. cnt++;
  276. }
  277. *dst = '\0';
  278. return cnt;
  279. }
  280. static void base64_init(void)
  281. {
  282. int x;
  283. memset(b2a, -1, sizeof(b2a));
  284. /* Initialize base-64 Conversion table */
  285. for (x=0;x<26;x++) {
  286. /* A-Z */
  287. base64[x] = 'A' + x;
  288. b2a['A' + x] = x;
  289. /* a-z */
  290. base64[x + 26] = 'a' + x;
  291. b2a['a' + x] = x + 26;
  292. /* 0-9 */
  293. if (x < 10) {
  294. base64[x + 52] = '0' + x;
  295. b2a['0' + x] = x + 52;
  296. }
  297. }
  298. base64[62] = '+';
  299. base64[63] = '/';
  300. b2a[(int)'+'] = 62;
  301. b2a[(int)'/'] = 63;
  302. #if 0
  303. for (x=0;x<64;x++) {
  304. if (b2a[(int)base64[x]] != x) {
  305. fprintf(stderr, "!!! %d failed\n", x);
  306. } else
  307. fprintf(stderr, "--- %d passed\n", x);
  308. }
  309. #endif
  310. }
  311. /* Recursive thread safe replacement of inet_ntoa */
  312. const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia)
  313. {
  314. return inet_ntop(AF_INET, &ia, buf, bufsiz);
  315. }
  316. int ast_utils_init(void)
  317. {
  318. base64_init();
  319. return 0;
  320. }
  321. #ifndef LINUX
  322. #undef pthread_create /* For ast_pthread_create function only */
  323. int ast_pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data)
  324. {
  325. pthread_attr_t lattr;
  326. if (!attr) {
  327. pthread_attr_init(&lattr);
  328. attr = &lattr;
  329. }
  330. errno = pthread_attr_setstacksize(attr, PTHREAD_ATTR_STACKSIZE);
  331. if (errno)
  332. ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
  333. return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
  334. }
  335. #endif /* ! LINUX */
  336. static char *upper(const char *orig, char *buf, int bufsize)
  337. {
  338. int i;
  339. memset(buf, 0, bufsize);
  340. for (i=0; i<bufsize - 1; i++) {
  341. buf[i] = toupper(orig[i]);
  342. if (orig[i] == '\0') {
  343. break;
  344. }
  345. }
  346. return buf;
  347. }
  348. /* Case-insensitive substring matching */
  349. #ifndef LINUX
  350. char *ast_strcasestr(const char *haystack, const char *needle)
  351. {
  352. char *u1, *u2;
  353. int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
  354. u1 = alloca(u1len);
  355. u2 = alloca(u2len);
  356. if (u1 && u2) {
  357. char *offset;
  358. if (u2len > u1len) {
  359. /* Needle bigger than haystack */
  360. return NULL;
  361. }
  362. offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
  363. if (offset) {
  364. /* Return the offset into the original string */
  365. return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
  366. } else {
  367. return NULL;
  368. }
  369. } else {
  370. ast_log(LOG_ERROR, "Out of memory\n");
  371. return NULL;
  372. }
  373. }
  374. #endif