Review Board 1.7.16


va_args cleanup in res_config_odbc, res_config_curl, utils, and also res_config_pgsql

Review Request #1848 - Created April 5, 2012 and submitted

Jonathan Rose
1.8
ASTERISK-19451
Reviewers
asterisk-dev
mjordan, mmichelson, wdoekes
Asterisk
A number of va_copy operations weren't matched with a corresponding va_end in res_config_odbc. Also, there was a potential for va_end to be invoked twice on the same va_arg in utils, which would mean invoking va_end on an undefined variable... which is bad.

va_end is removed from various functions in config_pgsql and config_curl since they aren't making their own copy.  The invokers of those functions are responsible for calling va_end on them.
None to speak of.  It compiles, but I'm really not sure how to check for va_arg leaks and such.  I'm not too worried about res_config_odbc and utils since those changes are pretty self-contained. The other changes should be fine too since the paramater ap in res_config_odbc isn't ended in any of the adapter functions there. I'm a little wary though that they should be copying to a new va_arg list instead like res_config_odbc does.

Diff revision 2 (Latest)

1 2
1 2

  1. /branches/1.8/main/utils.c: Loading...
  2. /branches/1.8/res/res_config_curl.c: Loading...
  3. /branches/1.8/res/res_config_odbc.c: Loading...
  4. /branches/1.8/res/res_config_pgsql.c: Loading...
/branches/1.8/main/utils.c
Revision 361291 New Change
1
/*
1
/*
2
 * Asterisk -- An open source telephony toolkit.
2
 * Asterisk -- An open source telephony toolkit.
3
 *
3
 *
4
 * Copyright (C) 1999 - 2006, Digium, Inc.
4
 * Copyright (C) 1999 - 2006, Digium, Inc.
5
 *
5
 *
6
 * See http://www.asterisk.org for more information about
6
 * See http://www.asterisk.org for more information about
7
 * the Asterisk project. Please do not directly contact
7
 * the Asterisk project. Please do not directly contact
8
 * any of the maintainers of this project for assistance;
8
 * any of the maintainers of this project for assistance;
9
 * the project provides a web site, mailing lists and IRC
9
 * the project provides a web site, mailing lists and IRC
10
 * channels for your use.
10
 * channels for your use.
11
 *
11
 *
12
 * This program is free software, distributed under the terms of
12
 * This program is free software, distributed under the terms of
13
 * the GNU General Public License Version 2. See the LICENSE file
13
 * the GNU General Public License Version 2. See the LICENSE file
14
 * at the top of the source tree.
14
 * at the top of the source tree.
15
 */
15
 */
16

    
   
16

   
17
/*! \file
17
/*! \file
18
 *
18
 *
19
 * \brief Utility functions
19
 * \brief Utility functions
20
 *
20
 *
21
 * \note These are important for portability and security,
21
 * \note These are important for portability and security,
22
 * so please use them in favour of other routines.
22
 * so please use them in favour of other routines.
23
 * Please consult the CODING GUIDELINES for more information.
23
 * Please consult the CODING GUIDELINES for more information.
24
 */
24
 */
25

    
   
25

   
26
#include "asterisk.h"
26
#include "asterisk.h"
27

    
   
27

   
28
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
28
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29

    
   
29

   
30
#include <ctype.h>
30
#include <ctype.h>
31
#include <sys/stat.h>
31
#include <sys/stat.h>
32
#include <sys/stat.h>
32
#include <sys/stat.h>
33

    
   
33

   
34
#ifdef HAVE_DEV_URANDOM
34
#ifdef HAVE_DEV_URANDOM
35
#include <fcntl.h>
35
#include <fcntl.h>
36
#endif
36
#endif
37

    
   
37

   
38
#include "asterisk/network.h"
38
#include "asterisk/network.h"
39

    
   
39

   
40
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in lock.h if required */
40
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in lock.h if required */
41
#include "asterisk/lock.h"
41
#include "asterisk/lock.h"
42
#include "asterisk/io.h"
42
#include "asterisk/io.h"
43
#include "asterisk/md5.h"
43
#include "asterisk/md5.h"
44
#include "asterisk/sha1.h"
44
#include "asterisk/sha1.h"
45
#include "asterisk/cli.h"
45
#include "asterisk/cli.h"
46
#include "asterisk/linkedlists.h"
46
#include "asterisk/linkedlists.h"
47

    
   
47

   
48
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
48
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
49
#include "asterisk/strings.h"
49
#include "asterisk/strings.h"
50

    
   
50

   
51
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
51
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
52
#include "asterisk/time.h"
52
#include "asterisk/time.h"
53

    
   
53

   
54
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
54
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
55
#include "asterisk/stringfields.h"
55
#include "asterisk/stringfields.h"
56

    
   
56

   
57
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
57
#define AST_API_MODULE		/* ensure that inlinable API functions will be built in this module if required */
58
#include "asterisk/utils.h"
58
#include "asterisk/utils.h"
59

    
   
59

   
60
#define AST_API_MODULE
60
#define AST_API_MODULE
61
#include "asterisk/threadstorage.h"
61
#include "asterisk/threadstorage.h"
62

    
   
62

   
63
#define AST_API_MODULE
63
#define AST_API_MODULE
64
#include "asterisk/config.h"
64
#include "asterisk/config.h"
65

    
   
65

   
66
static char base64[64];
66
static char base64[64];
67
static char b2a[256];
67
static char b2a[256];
68

    
   
68

   
69
AST_THREADSTORAGE(inet_ntoa_buf);
69
AST_THREADSTORAGE(inet_ntoa_buf);
70

    
   
70

   
71
#if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
71
#if !defined(HAVE_GETHOSTBYNAME_R_5) && !defined(HAVE_GETHOSTBYNAME_R_6)
72

    
   
72

   
73
#define ERANGE 34	/*!< duh? ERANGE value copied from web... */
73
#define ERANGE 34	/*!< duh? ERANGE value copied from web... */
74
#undef gethostbyname
74
#undef gethostbyname
75

    
   
75

   
76
AST_MUTEX_DEFINE_STATIC(__mutex);
76
AST_MUTEX_DEFINE_STATIC(__mutex);
77

    
   
77

   
78
/*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
78
/*! \brief Reentrant replacement for gethostbyname for BSD-based systems.
79
\note This
79
\note This
80
routine is derived from code originally written and placed in the public 
80
routine is derived from code originally written and placed in the public 
81
domain by Enzo Michelangeli <em@em.no-ip.com> */
81
domain by Enzo Michelangeli <em@em.no-ip.com> */
82

    
   
82

   
83
static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
83
static int gethostbyname_r (const char *name, struct hostent *ret, char *buf,
84
				size_t buflen, struct hostent **result, 
84
				size_t buflen, struct hostent **result, 
85
				int *h_errnop) 
85
				int *h_errnop) 
86
{
86
{
87
	int hsave;
87
	int hsave;
88
	struct hostent *ph;
88
	struct hostent *ph;
89
	ast_mutex_lock(&__mutex); /* begin critical area */
89
	ast_mutex_lock(&__mutex); /* begin critical area */
90
	hsave = h_errno;
90
	hsave = h_errno;
91

    
   
91

   
92
	ph = gethostbyname(name);
92
	ph = gethostbyname(name);
93
	*h_errnop = h_errno; /* copy h_errno to *h_herrnop */
93
	*h_errnop = h_errno; /* copy h_errno to *h_herrnop */
94
	if (ph == NULL) {
94
	if (ph == NULL) {
95
		*result = NULL;
95
		*result = NULL;
96
	} else {
96
	} else {
97
		char **p, **q;
97
		char **p, **q;
98
		char *pbuf;
98
		char *pbuf;
99
		int nbytes = 0;
99
		int nbytes = 0;
100
		int naddr = 0, naliases = 0;
100
		int naddr = 0, naliases = 0;
101
		/* determine if we have enough space in buf */
101
		/* determine if we have enough space in buf */
102

    
   
102

   
103
		/* count how many addresses */
103
		/* count how many addresses */
104
		for (p = ph->h_addr_list; *p != 0; p++) {
104
		for (p = ph->h_addr_list; *p != 0; p++) {
105
			nbytes += ph->h_length; /* addresses */
105
			nbytes += ph->h_length; /* addresses */
106
			nbytes += sizeof(*p); /* pointers */
106
			nbytes += sizeof(*p); /* pointers */
107
			naddr++;
107
			naddr++;
108
		}
108
		}
109
		nbytes += sizeof(*p); /* one more for the terminating NULL */
109
		nbytes += sizeof(*p); /* one more for the terminating NULL */
110

    
   
110

   
111
		/* count how many aliases, and total length of strings */
111
		/* count how many aliases, and total length of strings */
112
		for (p = ph->h_aliases; *p != 0; p++) {
112
		for (p = ph->h_aliases; *p != 0; p++) {
113
			nbytes += (strlen(*p)+1); /* aliases */
113
			nbytes += (strlen(*p)+1); /* aliases */
114
			nbytes += sizeof(*p);  /* pointers */
114
			nbytes += sizeof(*p);  /* pointers */
115
			naliases++;
115
			naliases++;
116
		}
116
		}
117
		nbytes += sizeof(*p); /* one more for the terminating NULL */
117
		nbytes += sizeof(*p); /* one more for the terminating NULL */
118

    
   
118

   
119
		/* here nbytes is the number of bytes required in buffer */
119
		/* here nbytes is the number of bytes required in buffer */
120
		/* as a terminator must be there, the minimum value is ph->h_length */
120
		/* as a terminator must be there, the minimum value is ph->h_length */
121
		if (nbytes > buflen) {
121
		if (nbytes > buflen) {
122
			*result = NULL;
122
			*result = NULL;
123
			ast_mutex_unlock(&__mutex); /* end critical area */
123
			ast_mutex_unlock(&__mutex); /* end critical area */
124
			return ERANGE; /* not enough space in buf!! */
124
			return ERANGE; /* not enough space in buf!! */
125
		}
125
		}
126

    
   
126

   
127
		/* There is enough space. Now we need to do a deep copy! */
127
		/* There is enough space. Now we need to do a deep copy! */
128
		/* Allocation in buffer:
128
		/* Allocation in buffer:
129
			from [0] to [(naddr-1) * sizeof(*p)]:
129
			from [0] to [(naddr-1) * sizeof(*p)]:
130
			pointers to addresses
130
			pointers to addresses
131
			at [naddr * sizeof(*p)]:
131
			at [naddr * sizeof(*p)]:
132
			NULL
132
			NULL
133
			from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
133
			from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
134
			pointers to aliases
134
			pointers to aliases
135
			at [(naddr+naliases+1) * sizeof(*p)]:
135
			at [(naddr+naliases+1) * sizeof(*p)]:
136
			NULL
136
			NULL
137
			then naddr addresses (fixed length), and naliases aliases (asciiz).
137
			then naddr addresses (fixed length), and naliases aliases (asciiz).
138
		*/
138
		*/
139

    
   
139

   
140
		*ret = *ph;   /* copy whole structure (not its address!) */
140
		*ret = *ph;   /* copy whole structure (not its address!) */
141

    
   
141

   
142
		/* copy addresses */
142
		/* copy addresses */
143
		q = (char **)buf; /* pointer to pointers area (type: char **) */
143
		q = (char **)buf; /* pointer to pointers area (type: char **) */
144
		ret->h_addr_list = q; /* update pointer to address list */
144
		ret->h_addr_list = q; /* update pointer to address list */
145
		pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
145
		pbuf = buf + ((naddr + naliases + 2) * sizeof(*p)); /* skip that area */
146
		for (p = ph->h_addr_list; *p != 0; p++) {
146
		for (p = ph->h_addr_list; *p != 0; p++) {
147
			memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
147
			memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
148
			*q++ = pbuf; /* the pointer is the one inside buf... */
148
			*q++ = pbuf; /* the pointer is the one inside buf... */
149
			pbuf += ph->h_length; /* advance pbuf */
149
			pbuf += ph->h_length; /* advance pbuf */
150
		}
150
		}
151
		*q++ = NULL; /* address list terminator */
151
		*q++ = NULL; /* address list terminator */
152

    
   
152

   
153
		/* copy aliases */
153
		/* copy aliases */
154
		ret->h_aliases = q; /* update pointer to aliases list */
154
		ret->h_aliases = q; /* update pointer to aliases list */
155
		for (p = ph->h_aliases; *p != 0; p++) {
155
		for (p = ph->h_aliases; *p != 0; p++) {
156
			strcpy(pbuf, *p); /* copy alias strings */
156
			strcpy(pbuf, *p); /* copy alias strings */
157
			*q++ = pbuf; /* the pointer is the one inside buf... */
157
			*q++ = pbuf; /* the pointer is the one inside buf... */
158
			pbuf += strlen(*p); /* advance pbuf */
158
			pbuf += strlen(*p); /* advance pbuf */
159
			*pbuf++ = 0; /* string terminator */
159
			*pbuf++ = 0; /* string terminator */
160
		}
160
		}
161
		*q++ = NULL; /* terminator */
161
		*q++ = NULL; /* terminator */
162

    
   
162

   
163
		strcpy(pbuf, ph->h_name); /* copy alias strings */
163
		strcpy(pbuf, ph->h_name); /* copy alias strings */
164
		ret->h_name = pbuf;
164
		ret->h_name = pbuf;
165
		pbuf += strlen(ph->h_name); /* advance pbuf */
165
		pbuf += strlen(ph->h_name); /* advance pbuf */
166
		*pbuf++ = 0; /* string terminator */
166
		*pbuf++ = 0; /* string terminator */
167

    
   
167

   
168
		*result = ret;  /* and let *result point to structure */
168
		*result = ret;  /* and let *result point to structure */
169

    
   
169

   
170
	}
170
	}
171
	h_errno = hsave;  /* restore h_errno */
171
	h_errno = hsave;  /* restore h_errno */
172
	ast_mutex_unlock(&__mutex); /* end critical area */
172
	ast_mutex_unlock(&__mutex); /* end critical area */
173

    
   
173

   
174
	return (*result == NULL); /* return 0 on success, non-zero on error */
174
	return (*result == NULL); /* return 0 on success, non-zero on error */
175
}
175
}
176

    
   
176

   
177

    
   
177

   
178
#endif
178
#endif
179

    
   
179

   
180
/*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
180
/*! \brief Re-entrant (thread safe) version of gethostbyname that replaces the 
181
   standard gethostbyname (which is not thread safe)
181
   standard gethostbyname (which is not thread safe)
182
*/
182
*/
183
struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
183
struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
184
{
184
{
185
	int res;
185
	int res;
186
	int herrno;
186
	int herrno;
187
	int dots = 0;
187
	int dots = 0;
188
	const char *s;
188
	const char *s;
189
	struct hostent *result = NULL;
189
	struct hostent *result = NULL;
190
	/* Although it is perfectly legitimate to lookup a pure integer, for
190
	/* Although it is perfectly legitimate to lookup a pure integer, for
191
	   the sake of the sanity of people who like to name their peers as
191
	   the sake of the sanity of people who like to name their peers as
192
	   integers, we break with tradition and refuse to look up a
192
	   integers, we break with tradition and refuse to look up a
193
	   pure integer */
193
	   pure integer */
194
	s = host;
194
	s = host;
195
	res = 0;
195
	res = 0;
196
	while (s && *s) {
196
	while (s && *s) {
197
		if (*s == '.')
197
		if (*s == '.')
198
			dots++;
198
			dots++;
199
		else if (!isdigit(*s))
199
		else if (!isdigit(*s))
200
			break;
200
			break;
201
		s++;
201
		s++;
202
	}
202
	}
203
	if (!s || !*s) {
203
	if (!s || !*s) {
204
		/* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
204
		/* Forge a reply for IP's to avoid octal IP's being interpreted as octal */
205
		if (dots != 3)
205
		if (dots != 3)
206
			return NULL;
206
			return NULL;
207
		memset(hp, 0, sizeof(struct ast_hostent));
207
		memset(hp, 0, sizeof(struct ast_hostent));
208
		hp->hp.h_addrtype = AF_INET;
208
		hp->hp.h_addrtype = AF_INET;
209
		hp->hp.h_addr_list = (void *) hp->buf;
209
		hp->hp.h_addr_list = (void *) hp->buf;
210
		hp->hp.h_addr = hp->buf + sizeof(void *);
210
		hp->hp.h_addr = hp->buf + sizeof(void *);
211
		/* For AF_INET, this will always be 4 */
211
		/* For AF_INET, this will always be 4 */
212
		hp->hp.h_length = 4;
212
		hp->hp.h_length = 4;
213
		if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
213
		if (inet_pton(AF_INET, host, hp->hp.h_addr) > 0)
214
			return &hp->hp;
214
			return &hp->hp;
215
		return NULL;
215
		return NULL;
216
		
216
		
217
	}
217
	}
218
#ifdef HAVE_GETHOSTBYNAME_R_5
218
#ifdef HAVE_GETHOSTBYNAME_R_5
219
	result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
219
	result = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &herrno);
220

    
   
220

   
221
	if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
221
	if (!result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
222
		return NULL;
222
		return NULL;
223
#else
223
#else
224
	res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
224
	res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
225

    
   
225

   
226
	if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
226
	if (res || !result || !hp->hp.h_addr_list || !hp->hp.h_addr_list[0])
227
		return NULL;
227
		return NULL;
228
#endif
228
#endif
229
	return &hp->hp;
229
	return &hp->hp;
230
}
230
}
231

    
   
231

   
232
/*! \brief Produce 32 char MD5 hash of value. */
232
/*! \brief Produce 32 char MD5 hash of value. */
233
void ast_md5_hash(char *output, const char *input)
233
void ast_md5_hash(char *output, const char *input)
234
{
234
{
235
	struct MD5Context md5;
235
	struct MD5Context md5;
236
	unsigned char digest[16];
236
	unsigned char digest[16];
237
	char *ptr;
237
	char *ptr;
238
	int x;
238
	int x;
239

    
   
239

   
240
	MD5Init(&md5);
240
	MD5Init(&md5);
241
	MD5Update(&md5, (const unsigned char *) input, strlen(input));
241
	MD5Update(&md5, (const unsigned char *) input, strlen(input));
242
	MD5Final(digest, &md5);
242
	MD5Final(digest, &md5);
243
	ptr = output;
243
	ptr = output;
244
	for (x = 0; x < 16; x++)
244
	for (x = 0; x < 16; x++)
245
		ptr += sprintf(ptr, "%2.2x", digest[x]);
245
		ptr += sprintf(ptr, "%2.2x", digest[x]);
246
}
246
}
247

    
   
247

   
248
/*! \brief Produce 40 char SHA1 hash of value. */
248
/*! \brief Produce 40 char SHA1 hash of value. */
249
void ast_sha1_hash(char *output, const char *input)
249
void ast_sha1_hash(char *output, const char *input)
250
{
250
{
251
	struct SHA1Context sha;
251
	struct SHA1Context sha;
252
	char *ptr;
252
	char *ptr;
253
	int x;
253
	int x;
254
	uint8_t Message_Digest[20];
254
	uint8_t Message_Digest[20];
255

    
   
255

   
256
	SHA1Reset(&sha);
256
	SHA1Reset(&sha);
257
	
257
	
258
	SHA1Input(&sha, (const unsigned char *) input, strlen(input));
258
	SHA1Input(&sha, (const unsigned char *) input, strlen(input));
259

    
   
259

   
260
	SHA1Result(&sha, Message_Digest);
260
	SHA1Result(&sha, Message_Digest);
261
	ptr = output;
261
	ptr = output;
262
	for (x = 0; x < 20; x++)
262
	for (x = 0; x < 20; x++)
263
		ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
263
		ptr += sprintf(ptr, "%2.2x", Message_Digest[x]);
264
}
264
}
265

    
   
265

   
266
/*! \brief decode BASE64 encoded text */
266
/*! \brief decode BASE64 encoded text */
267
int ast_base64decode(unsigned char *dst, const char *src, int max)
267
int ast_base64decode(unsigned char *dst, const char *src, int max)
268
{
268
{
269
	int cnt = 0;
269
	int cnt = 0;
270
	unsigned int byte = 0;
270
	unsigned int byte = 0;
271
	unsigned int bits = 0;
271
	unsigned int bits = 0;
272
	int incnt = 0;
272
	int incnt = 0;
273
	while(*src && *src != '=' && (cnt < max)) {
273
	while(*src && *src != '=' && (cnt < max)) {
274
		/* Shift in 6 bits of input */
274
		/* Shift in 6 bits of input */
275
		byte <<= 6;
275
		byte <<= 6;
276
		byte |= (b2a[(int)(*src)]) & 0x3f;
276
		byte |= (b2a[(int)(*src)]) & 0x3f;
277
		bits += 6;
277
		bits += 6;
278
		src++;
278
		src++;
279
		incnt++;
279
		incnt++;
280
		/* If we have at least 8 bits left over, take that character 
280
		/* If we have at least 8 bits left over, take that character 
281
		   off the top */
281
		   off the top */
282
		if (bits >= 8)  {
282
		if (bits >= 8)  {
283
			bits -= 8;
283
			bits -= 8;
284
			*dst = (byte >> bits) & 0xff;
284
			*dst = (byte >> bits) & 0xff;
285
			dst++;
285
			dst++;
286
			cnt++;
286
			cnt++;
287
		}
287
		}
288
	}
288
	}
289
	/* Don't worry about left over bits, they're extra anyway */
289
	/* Don't worry about left over bits, they're extra anyway */
290
	return cnt;
290
	return cnt;
291
}
291
}
292

    
   
292

   
293
/*! \brief encode text to BASE64 coding */
293
/*! \brief encode text to BASE64 coding */
294
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
294
int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks)
295
{
295
{
296
	int cnt = 0;
296
	int cnt = 0;
297
	int col = 0;
297
	int col = 0;
298
	unsigned int byte = 0;
298
	unsigned int byte = 0;
299
	int bits = 0;
299
	int bits = 0;
300
	int cntin = 0;
300
	int cntin = 0;
301
	/* Reserve space for null byte at end of string */
301
	/* Reserve space for null byte at end of string */
302
	max--;
302
	max--;
303
	while ((cntin < srclen) && (cnt < max)) {
303
	while ((cntin < srclen) && (cnt < max)) {
304
		byte <<= 8;
304
		byte <<= 8;
305
		byte |= *(src++);
305
		byte |= *(src++);
306
		bits += 8;
306
		bits += 8;
307
		cntin++;
307
		cntin++;
308
		if ((bits == 24) && (cnt + 4 <= max)) {
308
		if ((bits == 24) && (cnt + 4 <= max)) {
309
			*dst++ = base64[(byte >> 18) & 0x3f];
309
			*dst++ = base64[(byte >> 18) & 0x3f];
310
			*dst++ = base64[(byte >> 12) & 0x3f];
310
			*dst++ = base64[(byte >> 12) & 0x3f];
311
			*dst++ = base64[(byte >> 6) & 0x3f];
311
			*dst++ = base64[(byte >> 6) & 0x3f];
312
			*dst++ = base64[byte & 0x3f];
312
			*dst++ = base64[byte & 0x3f];
313
			cnt += 4;
313
			cnt += 4;
314
			col += 4;
314
			col += 4;
315
			bits = 0;
315
			bits = 0;
316
			byte = 0;
316
			byte = 0;
317
		}
317
		}
318
		if (linebreaks && (cnt < max) && (col == 64)) {
318
		if (linebreaks && (cnt < max) && (col == 64)) {
319
			*dst++ = '\n';
319
			*dst++ = '\n';
320
			cnt++;
320
			cnt++;
321
			col = 0;
321
			col = 0;
322
		}
322
		}
323
	}
323
	}
324
	if (bits && (cnt + 4 <= max)) {
324
	if (bits && (cnt + 4 <= max)) {
325
		/* Add one last character for the remaining bits, 
325
		/* Add one last character for the remaining bits, 
326
		   padding the rest with 0 */
326
		   padding the rest with 0 */
327
		byte <<= 24 - bits;
327
		byte <<= 24 - bits;
328
		*dst++ = base64[(byte >> 18) & 0x3f];
328
		*dst++ = base64[(byte >> 18) & 0x3f];
329
		*dst++ = base64[(byte >> 12) & 0x3f];
329
		*dst++ = base64[(byte >> 12) & 0x3f];
330
		if (bits == 16)
330
		if (bits == 16)
331
			*dst++ = base64[(byte >> 6) & 0x3f];
331
			*dst++ = base64[(byte >> 6) & 0x3f];
332
		else
332
		else
333
			*dst++ = '=';
333
			*dst++ = '=';
334
		*dst++ = '=';
334
		*dst++ = '=';
335
		cnt += 4;
335
		cnt += 4;
336
	}
336
	}
337
	if (linebreaks && (cnt < max)) {
337
	if (linebreaks && (cnt < max)) {
338
		*dst++ = '\n';
338
		*dst++ = '\n';
339
		cnt++;
339
		cnt++;
340
	}
340
	}
341
	*dst = '\0';
341
	*dst = '\0';
342
	return cnt;
342
	return cnt;
343
}
343
}
344

    
   
344

   
345
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
345
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
346
{
346
{
347
	return ast_base64encode_full(dst, src, srclen, max, 0);
347
	return ast_base64encode_full(dst, src, srclen, max, 0);
348
}
348
}
349

    
   
349

   
350
static void base64_init(void)
350
static void base64_init(void)
351
{
351
{
352
	int x;
352
	int x;
353
	memset(b2a, -1, sizeof(b2a));
353
	memset(b2a, -1, sizeof(b2a));
354
	/* Initialize base-64 Conversion table */
354
	/* Initialize base-64 Conversion table */
355
	for (x = 0; x < 26; x++) {
355
	for (x = 0; x < 26; x++) {
356
		/* A-Z */
356
		/* A-Z */
357
		base64[x] = 'A' + x;
357
		base64[x] = 'A' + x;
358
		b2a['A' + x] = x;
358
		b2a['A' + x] = x;
359
		/* a-z */
359
		/* a-z */
360
		base64[x + 26] = 'a' + x;
360
		base64[x + 26] = 'a' + x;
361
		b2a['a' + x] = x + 26;
361
		b2a['a' + x] = x + 26;
362
		/* 0-9 */
362
		/* 0-9 */
363
		if (x < 10) {
363
		if (x < 10) {
364
			base64[x + 52] = '0' + x;
364
			base64[x + 52] = '0' + x;
365
			b2a['0' + x] = x + 52;
365
			b2a['0' + x] = x + 52;
366
		}
366
		}
367
	}
367
	}
368
	base64[62] = '+';
368
	base64[62] = '+';
369
	base64[63] = '/';
369
	base64[63] = '/';
370
	b2a[(int)'+'] = 62;
370
	b2a[(int)'+'] = 62;
371
	b2a[(int)'/'] = 63;
371
	b2a[(int)'/'] = 63;
372
}
372
}
373

    
   
373

   
374
/*! \brief Turn text string to URI-encoded %XX version 
374
/*! \brief Turn text string to URI-encoded %XX version 
375
 *
375
 *
376
 * \note 
376
 * \note 
377
 *  At this point, this function is encoding agnostic; it does not
377
 *  At this point, this function is encoding agnostic; it does not
378
 *  check whether it is fed legal UTF-8. We escape control
378
 *  check whether it is fed legal UTF-8. We escape control
379
 *  characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
379
 *  characters (\x00-\x1F\x7F), '%', and all characters above 0x7F.
380
 *  If do_special_char == 1 we will convert all characters except alnum
380
 *  If do_special_char == 1 we will convert all characters except alnum
381
 *  and mark.
381
 *  and mark.
382
 *  Outbuf needs to have more memory allocated than the instring
382
 *  Outbuf needs to have more memory allocated than the instring
383
 *  to have room for the expansion. Every char that is converted
383
 *  to have room for the expansion. Every char that is converted
384
 *  is replaced by three ASCII characters.
384
 *  is replaced by three ASCII characters.
385
 */
385
 */
386
char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char)
386
char *ast_uri_encode(const char *string, char *outbuf, int buflen, int do_special_char)
387
{
387
{
388
	const char *ptr  = string;	/* Start with the string */
388
	const char *ptr  = string;	/* Start with the string */
389
	char *out = outbuf;
389
	char *out = outbuf;
390
	const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
390
	const char *mark = "-_.!~*'()"; /* no encode set, RFC 2396 section 2.3, RFC 3261 sec 25 */
391

    
   
391

   
392
	while (*ptr && out - outbuf < buflen - 1) {
392
	while (*ptr && out - outbuf < buflen - 1) {
393
		if ((const signed char) *ptr < 32 || *ptr == 0x7f || *ptr == '%' ||
393
		if ((const signed char) *ptr < 32 || *ptr == 0x7f || *ptr == '%' ||
394
				(do_special_char &&
394
				(do_special_char &&
395
				!(*ptr >= '0' && *ptr <= '9') &&      /* num */
395
				!(*ptr >= '0' && *ptr <= '9') &&      /* num */
396
				!(*ptr >= 'A' && *ptr <= 'Z') &&      /* ALPHA */
396
				!(*ptr >= 'A' && *ptr <= 'Z') &&      /* ALPHA */
397
				!(*ptr >= 'a' && *ptr <= 'z') &&      /* alpha */
397
				!(*ptr >= 'a' && *ptr <= 'z') &&      /* alpha */
398
				!strchr(mark, *ptr))) {               /* mark set */
398
				!strchr(mark, *ptr))) {               /* mark set */
399
			if (out - outbuf >= buflen - 3) {
399
			if (out - outbuf >= buflen - 3) {
400
				break;
400
				break;
401
			}
401
			}
402

    
   
402

   
403
			out += sprintf(out, "%%%02X", (unsigned char) *ptr);
403
			out += sprintf(out, "%%%02X", (unsigned char) *ptr);
404
		} else {
404
		} else {
405
			*out = *ptr;	/* Continue copying the string */
405
			*out = *ptr;	/* Continue copying the string */
406
			out++;
406
			out++;
407
		}
407
		}
408
		ptr++;
408
		ptr++;
409
	}
409
	}
410

    
   
410

   
411
	if (buflen) {
411
	if (buflen) {
412
		*out = '\0';
412
		*out = '\0';
413
	}
413
	}
414

    
   
414

   
415
	return outbuf;
415
	return outbuf;
416
}
416
}
417

    
   
417

   
418
/*! \brief escapes characters specified for quoted portions of sip messages */
418
/*! \brief escapes characters specified for quoted portions of sip messages */
419
char *ast_escape_quoted(const char *string, char *outbuf, int buflen)
419
char *ast_escape_quoted(const char *string, char *outbuf, int buflen)
420
{
420
{
421
	const char *ptr  = string;
421
	const char *ptr  = string;
422
	char *out = outbuf;
422
	char *out = outbuf;
423
	char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
423
	char *allow = "\t\v !"; /* allow LWS (minus \r and \n) and "!" */
424

    
   
424

   
425
	while (*ptr && out - outbuf < buflen - 1) {
425
	while (*ptr && out - outbuf < buflen - 1) {
426
		if (!(strchr(allow, *ptr))
426
		if (!(strchr(allow, *ptr))
427
			&& !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
427
			&& !(*ptr >= '#' && *ptr <= '[') /* %x23 - %x5b */
428
			&& !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
428
			&& !(*ptr >= ']' && *ptr <= '~') /* %x5d - %x7e */
429
			&& !((unsigned char) *ptr > 0x7f)) {             /* UTF8-nonascii */
429
			&& !((unsigned char) *ptr > 0x7f)) {             /* UTF8-nonascii */
430

    
   
430

   
431
			if (out - outbuf >= buflen - 2) {
431
			if (out - outbuf >= buflen - 2) {
432
				break;
432
				break;
433
			}
433
			}
434
			out += sprintf(out, "\\%c", (unsigned char) *ptr);
434
			out += sprintf(out, "\\%c", (unsigned char) *ptr);
435
		} else {
435
		} else {
436
			*out = *ptr;
436
			*out = *ptr;
437
			out++;
437
			out++;
438
		}
438
		}
439
		ptr++;
439
		ptr++;
440
	}
440
	}
441

    
   
441

   
442
	if (buflen) {
442
	if (buflen) {
443
		*out = '\0';
443
		*out = '\0';
444
	}
444
	}
445

    
   
445

   
446
	return outbuf;
446
	return outbuf;
447
}
447
}
448

    
   
448

   
449
/*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  */
449
/*! \brief  ast_uri_decode: Decode SIP URI, URN, URL (overwrite the string)  */
450
void ast_uri_decode(char *s) 
450
void ast_uri_decode(char *s) 
451
{
451
{
452
	char *o;
452
	char *o;
453
	unsigned int tmp;
453
	unsigned int tmp;
454

    
   
454

   
455
	for (o = s; *s; s++, o++) {
455
	for (o = s; *s; s++, o++) {
456
		if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
456
		if (*s == '%' && s[1] != '\0' && s[2] != '\0' && sscanf(s + 1, "%2x", &tmp) == 1) {
457
			/* have '%', two chars and correct parsing */
457
			/* have '%', two chars and correct parsing */
458
			*o = tmp;
458
			*o = tmp;
459
			s += 2;	/* Will be incremented once more when we break out */
459
			s += 2;	/* Will be incremented once more when we break out */
460
		} else /* all other cases, just copy */
460
		} else /* all other cases, just copy */
461
			*o = *s;
461
			*o = *s;
462
	}
462
	}
463
	*o = '\0';
463
	*o = '\0';
464
}
464
}
465

    
   
465

   
466
/*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
466
/*! \brief  ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */
467
const char *ast_inet_ntoa(struct in_addr ia)
467
const char *ast_inet_ntoa(struct in_addr ia)
468
{
468
{
469
	char *buf;
469
	char *buf;
470

    
   
470

   
471
	if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
471
	if (!(buf = ast_threadstorage_get(&inet_ntoa_buf, INET_ADDRSTRLEN)))
472
		return "";
472
		return "";
473

    
   
473

   
474
	return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
474
	return inet_ntop(AF_INET, &ia, buf, INET_ADDRSTRLEN);
475
}
475
}
476

    
   
476

   
477
#ifdef HAVE_DEV_URANDOM
477
#ifdef HAVE_DEV_URANDOM
478
static int dev_urandom_fd;
478
static int dev_urandom_fd;
479
#endif
479
#endif
480

    
   
480

   
481
#ifndef __linux__
481
#ifndef __linux__
482
#undef pthread_create /* For ast_pthread_create function only */
482
#undef pthread_create /* For ast_pthread_create function only */
483
#endif /* !__linux__ */
483
#endif /* !__linux__ */
484

    
   
484

   
485
#if !defined(LOW_MEMORY)
485
#if !defined(LOW_MEMORY)
486

    
   
486

   
487
#ifdef DEBUG_THREADS
487
#ifdef DEBUG_THREADS
488

    
   
488

   
489
/*! \brief A reasonable maximum number of locks a thread would be holding ... */
489
/*! \brief A reasonable maximum number of locks a thread would be holding ... */
490
#define AST_MAX_LOCKS 64
490
#define AST_MAX_LOCKS 64
491

    
   
491

   
492
/* Allow direct use of pthread_mutex_t and friends */
492
/* Allow direct use of pthread_mutex_t and friends */
493
#undef pthread_mutex_t
493
#undef pthread_mutex_t
494
#undef pthread_mutex_lock
494
#undef pthread_mutex_lock
495
#undef pthread_mutex_unlock
495
#undef pthread_mutex_unlock
496
#undef pthread_mutex_init
496
#undef pthread_mutex_init
497
#undef pthread_mutex_destroy
497
#undef pthread_mutex_destroy
498

    
   
498

   
499
/*! 
499
/*! 
500
 * \brief Keep track of which locks a thread holds 
500
 * \brief Keep track of which locks a thread holds 
501
 *
501
 *
502
 * There is an instance of this struct for every active thread
502
 * There is an instance of this struct for every active thread
503
 */
503
 */
504
struct thr_lock_info {
504
struct thr_lock_info {
505
	/*! The thread's ID */
505
	/*! The thread's ID */
506
	pthread_t thread_id;
506
	pthread_t thread_id;
507
	/*! The thread name which includes where the thread was started */
507
	/*! The thread name which includes where the thread was started */
508
	const char *thread_name;
508
	const char *thread_name;
509
	/*! This is the actual container of info for what locks this thread holds */
509
	/*! This is the actual container of info for what locks this thread holds */
510
	struct {
510
	struct {
511
		const char *file;
511
		const char *file;
512
		int line_num;
512
		int line_num;
513
		const char *func;
513
		const char *func;
514
		const char *lock_name;
514
		const char *lock_name;
515
		void *lock_addr;
515
		void *lock_addr;
516
		int times_locked;
516
		int times_locked;
517
		enum ast_lock_type type;
517
		enum ast_lock_type type;
518
		/*! This thread is waiting on this lock */
518
		/*! This thread is waiting on this lock */
519
		int pending:2;
519
		int pending:2;
520
#ifdef HAVE_BKTR
520
#ifdef HAVE_BKTR
521
		struct ast_bt *backtrace;
521
		struct ast_bt *backtrace;
522
#endif
522
#endif
523
	} locks[AST_MAX_LOCKS];
523
	} locks[AST_MAX_LOCKS];
524
	/*! This is the number of locks currently held by this thread.
524
	/*! This is the number of locks currently held by this thread.
525
	 *  The index (num_locks - 1) has the info on the last one in the
525
	 *  The index (num_locks - 1) has the info on the last one in the
526
	 *  locks member */
526
	 *  locks member */
527
	unsigned int num_locks;
527
	unsigned int num_locks;
528
	/*! Protects the contents of the locks member 
528
	/*! Protects the contents of the locks member 
529
	 * Intentionally not ast_mutex_t */
529
	 * Intentionally not ast_mutex_t */
530
	pthread_mutex_t lock;
530
	pthread_mutex_t lock;
531
	AST_LIST_ENTRY(thr_lock_info) entry;
531
	AST_LIST_ENTRY(thr_lock_info) entry;
532
};
532
};
533

    
   
533

   
534
/*! 
534
/*! 
535
 * \brief Locked when accessing the lock_infos list 
535
 * \brief Locked when accessing the lock_infos list 
536
 */
536
 */
537
AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
537
AST_MUTEX_DEFINE_STATIC(lock_infos_lock);
538
/*!
538
/*!
539
 * \brief A list of each thread's lock info 
539
 * \brief A list of each thread's lock info 
540
 */
540
 */
541
static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
541
static AST_LIST_HEAD_NOLOCK_STATIC(lock_infos, thr_lock_info);
542

    
   
542

   
543
/*!
543
/*!
544
 * \brief Destroy a thread's lock info
544
 * \brief Destroy a thread's lock info
545
 *
545
 *
546
 * This gets called automatically when the thread stops
546
 * This gets called automatically when the thread stops
547
 */
547
 */
548
static void lock_info_destroy(void *data)
548
static void lock_info_destroy(void *data)
549
{
549
{
550
	struct thr_lock_info *lock_info = data;
550
	struct thr_lock_info *lock_info = data;
551
	int i;
551
	int i;
552

    
   
552

   
553
	pthread_mutex_lock(&lock_infos_lock.mutex);
553
	pthread_mutex_lock(&lock_infos_lock.mutex);
554
	AST_LIST_REMOVE(&lock_infos, lock_info, entry);
554
	AST_LIST_REMOVE(&lock_infos, lock_info, entry);
555
	pthread_mutex_unlock(&lock_infos_lock.mutex);
555
	pthread_mutex_unlock(&lock_infos_lock.mutex);
556

    
   
556

   
557

    
   
557

   
558
	for (i = 0; i < lock_info->num_locks; i++) {
558
	for (i = 0; i < lock_info->num_locks; i++) {
559
		if (lock_info->locks[i].pending == -1) {
559
		if (lock_info->locks[i].pending == -1) {
560
			/* This just means that the last lock this thread went for was by
560
			/* This just means that the last lock this thread went for was by
561
			 * using trylock, and it failed.  This is fine. */
561
			 * using trylock, and it failed.  This is fine. */
562
			break;
562
			break;
563
		}
563
		}
564

    
   
564

   
565
		ast_log(LOG_ERROR, 
565
		ast_log(LOG_ERROR, 
566
			"Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n", 
566
			"Thread '%s' still has a lock! - '%s' (%p) from '%s' in %s:%d!\n", 
567
			lock_info->thread_name,
567
			lock_info->thread_name,
568
			lock_info->locks[i].lock_name,
568
			lock_info->locks[i].lock_name,
569
			lock_info->locks[i].lock_addr,
569
			lock_info->locks[i].lock_addr,
570
			lock_info->locks[i].func,
570
			lock_info->locks[i].func,
571
			lock_info->locks[i].file,
571
			lock_info->locks[i].file,
572
			lock_info->locks[i].line_num
572
			lock_info->locks[i].line_num
573
		);
573
		);
574
	}
574
	}
575

    
   
575

   
576
	pthread_mutex_destroy(&lock_info->lock);
576
	pthread_mutex_destroy(&lock_info->lock);
577
	if (lock_info->thread_name)
577
	if (lock_info->thread_name)
578
		free((void *) lock_info->thread_name);
578
		free((void *) lock_info->thread_name);
579
	free(lock_info);
579
	free(lock_info);
580
}
580
}
581

    
   
581

   
582
/*!
582
/*!
583
 * \brief The thread storage key for per-thread lock info
583
 * \brief The thread storage key for per-thread lock info
584
 */
584
 */
585
AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
585
AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
586
#ifdef HAVE_BKTR
586
#ifdef HAVE_BKTR
587
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
587
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
588
	int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
588
	int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
589
#else
589
#else
590
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
590
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
591
	int line_num, const char *func, const char *lock_name, void *lock_addr)
591
	int line_num, const char *func, const char *lock_name, void *lock_addr)
592
#endif
592
#endif
593
{
593
{
594
	struct thr_lock_info *lock_info;
594
	struct thr_lock_info *lock_info;
595
	int i;
595
	int i;
596

    
   
596

   
597
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
597
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
598
		return;
598
		return;
599

    
   
599

   
600
	pthread_mutex_lock(&lock_info->lock);
600
	pthread_mutex_lock(&lock_info->lock);
601

    
   
601

   
602
	for (i = 0; i < lock_info->num_locks; i++) {
602
	for (i = 0; i < lock_info->num_locks; i++) {
603
		if (lock_info->locks[i].lock_addr == lock_addr) {
603
		if (lock_info->locks[i].lock_addr == lock_addr) {
604
			lock_info->locks[i].times_locked++;
604
			lock_info->locks[i].times_locked++;
605
#ifdef HAVE_BKTR
605
#ifdef HAVE_BKTR
606
			lock_info->locks[i].backtrace = bt;
606
			lock_info->locks[i].backtrace = bt;
607
#endif
607
#endif
608
			pthread_mutex_unlock(&lock_info->lock);
608
			pthread_mutex_unlock(&lock_info->lock);
609
			return;
609
			return;
610
		}
610
		}
611
	}
611
	}
612

    
   
612

   
613
	if (lock_info->num_locks == AST_MAX_LOCKS) {
613
	if (lock_info->num_locks == AST_MAX_LOCKS) {
614
		/* Can't use ast_log here, because it will cause infinite recursion */
614
		/* Can't use ast_log here, because it will cause infinite recursion */
615
		fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
615
		fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
616
			"  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
616
			"  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
617
		pthread_mutex_unlock(&lock_info->lock);
617
		pthread_mutex_unlock(&lock_info->lock);
618
		return;
618
		return;
619
	}
619
	}
620

    
   
620

   
621
	if (i && lock_info->locks[i - 1].pending == -1) {
621
	if (i && lock_info->locks[i - 1].pending == -1) {
622
		/* The last lock on the list was one that this thread tried to lock but
622
		/* The last lock on the list was one that this thread tried to lock but
623
		 * failed at doing so.  It has now moved on to something else, so remove
623
		 * failed at doing so.  It has now moved on to something else, so remove
624
		 * the old lock from the list. */
624
		 * the old lock from the list. */
625
		i--;
625
		i--;
626
		lock_info->num_locks--;
626
		lock_info->num_locks--;
627
		memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
627
		memset(&lock_info->locks[i], 0, sizeof(lock_info->locks[0]));
628
	}
628
	}
629

    
   
629

   
630
	lock_info->locks[i].file = filename;
630
	lock_info->locks[i].file = filename;
631
	lock_info->locks[i].line_num = line_num;
631
	lock_info->locks[i].line_num = line_num;
632
	lock_info->locks[i].func = func;
632
	lock_info->locks[i].func = func;
633
	lock_info->locks[i].lock_name = lock_name;
633
	lock_info->locks[i].lock_name = lock_name;
634
	lock_info->locks[i].lock_addr = lock_addr;
634
	lock_info->locks[i].lock_addr = lock_addr;
635
	lock_info->locks[i].times_locked = 1;
635
	lock_info->locks[i].times_locked = 1;
636
	lock_info->locks[i].type = type;
636
	lock_info->locks[i].type = type;
637
	lock_info->locks[i].pending = 1;
637
	lock_info->locks[i].pending = 1;
638
#ifdef HAVE_BKTR
638
#ifdef HAVE_BKTR
639
	lock_info->locks[i].backtrace = bt;
639
	lock_info->locks[i].backtrace = bt;
640
#endif
640
#endif
641
	lock_info->num_locks++;
641
	lock_info->num_locks++;
642

    
   
642

   
643
	pthread_mutex_unlock(&lock_info->lock);
643
	pthread_mutex_unlock(&lock_info->lock);
644
}
644
}
645

    
   
645

   
646
void ast_mark_lock_acquired(void *lock_addr)
646
void ast_mark_lock_acquired(void *lock_addr)
647
{
647
{
648
	struct thr_lock_info *lock_info;
648
	struct thr_lock_info *lock_info;
649

    
   
649

   
650
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
650
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
651
		return;
651
		return;
652

    
   
652

   
653
	pthread_mutex_lock(&lock_info->lock);
653
	pthread_mutex_lock(&lock_info->lock);
654
	if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
654
	if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
655
		lock_info->locks[lock_info->num_locks - 1].pending = 0;
655
		lock_info->locks[lock_info->num_locks - 1].pending = 0;
656
	}
656
	}
657
	pthread_mutex_unlock(&lock_info->lock);
657
	pthread_mutex_unlock(&lock_info->lock);
658
}
658
}
659

    
   
659

   
660
void ast_mark_lock_failed(void *lock_addr)
660
void ast_mark_lock_failed(void *lock_addr)
661
{
661
{
662
	struct thr_lock_info *lock_info;
662
	struct thr_lock_info *lock_info;
663

    
   
663

   
664
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
664
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
665
		return;
665
		return;
666

    
   
666

   
667
	pthread_mutex_lock(&lock_info->lock);
667
	pthread_mutex_lock(&lock_info->lock);
668
	if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
668
	if (lock_info->locks[lock_info->num_locks - 1].lock_addr == lock_addr) {
669
		lock_info->locks[lock_info->num_locks - 1].pending = -1;
669
		lock_info->locks[lock_info->num_locks - 1].pending = -1;
670
		lock_info->locks[lock_info->num_locks - 1].times_locked--;
670
		lock_info->locks[lock_info->num_locks - 1].times_locked--;
671
	}
671
	}
672
	pthread_mutex_unlock(&lock_info->lock);
672
	pthread_mutex_unlock(&lock_info->lock);
673
}
673
}
674

    
   
674

   
675
int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size)
675
int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size)
676
{
676
{
677
	struct thr_lock_info *lock_info;
677
	struct thr_lock_info *lock_info;
678
	int i = 0;
678
	int i = 0;
679

    
   
679

   
680
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
680
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
681
		return -1;
681
		return -1;
682

    
   
682

   
683
	pthread_mutex_lock(&lock_info->lock);
683
	pthread_mutex_lock(&lock_info->lock);
684

    
   
684

   
685
	for (i = lock_info->num_locks - 1; i >= 0; i--) {
685
	for (i = lock_info->num_locks - 1; i >= 0; i--) {
686
		if (lock_info->locks[i].lock_addr == lock_addr)
686
		if (lock_info->locks[i].lock_addr == lock_addr)
687
			break;
687
			break;
688
	}
688
	}
689

    
   
689

   
690
	if (i == -1) {
690
	if (i == -1) {
691
		/* Lock not found :( */
691
		/* Lock not found :( */
692
		pthread_mutex_unlock(&lock_info->lock);
692
		pthread_mutex_unlock(&lock_info->lock);
693
		return -1;
693
		return -1;
694
	}
694
	}
695

    
   
695

   
696
	ast_copy_string(filename, lock_info->locks[i].file, filename_size);
696
	ast_copy_string(filename, lock_info->locks[i].file, filename_size);
697
	*lineno = lock_info->locks[i].line_num;
697
	*lineno = lock_info->locks[i].line_num;
698
	ast_copy_string(func, lock_info->locks[i].func, func_size);
698
	ast_copy_string(func, lock_info->locks[i].func, func_size);
699
	ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
699
	ast_copy_string(mutex_name, lock_info->locks[i].lock_name, mutex_name_size);
700

    
   
700

   
701
	pthread_mutex_unlock(&lock_info->lock);
701
	pthread_mutex_unlock(&lock_info->lock);
702

    
   
702

   
703
	return 0;
703
	return 0;
704
}
704
}
705

    
   
705

   
706
#ifdef HAVE_BKTR
706
#ifdef HAVE_BKTR
707
void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
707
void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
708
#else
708
#else
709
void ast_remove_lock_info(void *lock_addr)
709
void ast_remove_lock_info(void *lock_addr)
710
#endif
710
#endif
711
{
711
{
712
	struct thr_lock_info *lock_info;
712
	struct thr_lock_info *lock_info;
713
	int i = 0;
713
	int i = 0;
714

    
   
714

   
715
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
715
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
716
		return;
716
		return;
717

    
   
717

   
718
	pthread_mutex_lock(&lock_info->lock);
718
	pthread_mutex_lock(&lock_info->lock);
719

    
   
719

   
720
	for (i = lock_info->num_locks - 1; i >= 0; i--) {
720
	for (i = lock_info->num_locks - 1; i >= 0; i--) {
721
		if (lock_info->locks[i].lock_addr == lock_addr)
721
		if (lock_info->locks[i].lock_addr == lock_addr)
722
			break;
722
			break;
723
	}
723
	}
724

    
   
724

   
725
	if (i == -1) {
725
	if (i == -1) {
726
		/* Lock not found :( */
726
		/* Lock not found :( */
727
		pthread_mutex_unlock(&lock_info->lock);
727
		pthread_mutex_unlock(&lock_info->lock);
728
		return;
728
		return;
729
	}
729
	}
730

    
   
730

   
731
	if (lock_info->locks[i].times_locked > 1) {
731
	if (lock_info->locks[i].times_locked > 1) {
732
		lock_info->locks[i].times_locked--;
732
		lock_info->locks[i].times_locked--;
733
#ifdef HAVE_BKTR
733
#ifdef HAVE_BKTR
734
		lock_info->locks[i].backtrace = bt;
734
		lock_info->locks[i].backtrace = bt;
735
#endif
735
#endif
736
		pthread_mutex_unlock(&lock_info->lock);
736
		pthread_mutex_unlock(&lock_info->lock);
737
		return;
737
		return;
738
	}
738
	}
739

    
   
739

   
740
	if (i < lock_info->num_locks - 1) {
740
	if (i < lock_info->num_locks - 1) {
741
		/* Not the last one ... *should* be rare! */
741
		/* Not the last one ... *should* be rare! */
742
		memmove(&lock_info->locks[i], &lock_info->locks[i + 1], 
742
		memmove(&lock_info->locks[i], &lock_info->locks[i + 1], 
743
			(lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
743
			(lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
744
	}
744
	}
745

    
   
745

   
746
	lock_info->num_locks--;
746
	lock_info->num_locks--;
747

    
   
747

   
748
	pthread_mutex_unlock(&lock_info->lock);
748
	pthread_mutex_unlock(&lock_info->lock);
749
}
749
}
750

    
   
750

   
751
static const char *locktype2str(enum ast_lock_type type)
751
static const char *locktype2str(enum ast_lock_type type)
752
{
752
{
753
	switch (type) {
753
	switch (type) {
754
	case AST_MUTEX:
754
	case AST_MUTEX:
755
		return "MUTEX";
755
		return "MUTEX";
756
	case AST_RDLOCK:
756
	case AST_RDLOCK:
757
		return "RDLOCK";
757
		return "RDLOCK";
758
	case AST_WRLOCK:
758
	case AST_WRLOCK:
759
		return "WRLOCK";
759
		return "WRLOCK";
760
	}
760
	}
761

    
   
761

   
762
	return "UNKNOWN";
762
	return "UNKNOWN";
763
}
763
}
764

    
   
764

   
765
#ifdef HAVE_BKTR
765
#ifdef HAVE_BKTR
766
static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
766
static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
767
{
767
{
768
	char **symbols;
768
	char **symbols;
769

    
   
769

   
770
	if (!bt) {
770
	if (!bt) {
771
		ast_str_append(str, 0, "\tNo backtrace to print\n");
771
		ast_str_append(str, 0, "\tNo backtrace to print\n");
772
		return;
772
		return;
773
	}
773
	}
774

    
   
774

   
775
	if ((symbols = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
775
	if ((symbols = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
776
		int frame_iterator;
776
		int frame_iterator;
777
		
777
		
778
		for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) {
778
		for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) {
779
			ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
779
			ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
780
		}
780
		}
781

    
   
781

   
782
		free(symbols);
782
		free(symbols);
783
	} else {
783
	} else {
784
		ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
784
		ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
785
	}
785
	}
786
}
786
}
787
#endif
787
#endif
788

    
   
788

   
789
static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
789
static void append_lock_information(struct ast_str **str, struct thr_lock_info *lock_info, int i)
790
{
790
{
791
	int j;
791
	int j;
792
	ast_mutex_t *lock;
792
	ast_mutex_t *lock;
793
	struct ast_lock_track *lt;
793
	struct ast_lock_track *lt;
794
	
794
	
795
	ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", 
795
	ast_str_append(str, 0, "=== ---> %sLock #%d (%s): %s %d %s %s %p (%d)\n", 
796
				   lock_info->locks[i].pending > 0 ? "Waiting for " : 
796
				   lock_info->locks[i].pending > 0 ? "Waiting for " : 
797
				   lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
797
				   lock_info->locks[i].pending < 0 ? "Tried and failed to get " : "", i,
798
				   lock_info->locks[i].file, 
798
				   lock_info->locks[i].file, 
799
				   locktype2str(lock_info->locks[i].type),
799
				   locktype2str(lock_info->locks[i].type),
800
				   lock_info->locks[i].line_num,
800
				   lock_info->locks[i].line_num,
801
				   lock_info->locks[i].func, lock_info->locks[i].lock_name,
801
				   lock_info->locks[i].func, lock_info->locks[i].lock_name,
802
				   lock_info->locks[i].lock_addr, 
802
				   lock_info->locks[i].lock_addr, 
803
				   lock_info->locks[i].times_locked);
803
				   lock_info->locks[i].times_locked);
804
#ifdef HAVE_BKTR
804
#ifdef HAVE_BKTR
805
	append_backtrace_information(str, lock_info->locks[i].backtrace);
805
	append_backtrace_information(str, lock_info->locks[i].backtrace);
806
#endif
806
#endif
807
	
807
	
808
	if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
808
	if (!lock_info->locks[i].pending || lock_info->locks[i].pending == -1)
809
		return;
809
		return;
810
	
810
	
811
	/* We only have further details for mutexes right now */
811
	/* We only have further details for mutexes right now */
812
	if (lock_info->locks[i].type != AST_MUTEX)
812
	if (lock_info->locks[i].type != AST_MUTEX)
813
		return;
813
		return;
814
	
814
	
815
	lock = lock_info->locks[i].lock_addr;
815
	lock = lock_info->locks[i].lock_addr;
816
	lt = lock->track;
816
	lt = lock->track;
817
	ast_reentrancy_lock(lt);
817
	ast_reentrancy_lock(lt);
818
	for (j = 0; *str && j < lt->reentrancy; j++) {
818
	for (j = 0; *str && j < lt->reentrancy; j++) {
819
		ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
819
		ast_str_append(str, 0, "=== --- ---> Locked Here: %s line %d (%s)\n",
820
					   lt->file[j], lt->lineno[j], lt->func[j]);
820
					   lt->file[j], lt->lineno[j], lt->func[j]);
821
	}
821
	}
822
	ast_reentrancy_unlock(lt);	
822
	ast_reentrancy_unlock(lt);	
823
}
823
}
824

    
   
824

   
825

    
   
825

   
826
/*! This function can help you find highly temporal locks; locks that happen for a 
826
/*! This function can help you find highly temporal locks; locks that happen for a 
827
    short time, but at unexpected times, usually at times that create a deadlock,
827
    short time, but at unexpected times, usually at times that create a deadlock,
828
	Why is this thing locked right then? Who is locking it? Who am I fighting
828
	Why is this thing locked right then? Who is locking it? Who am I fighting
829
    with for this lock? 
829
    with for this lock? 
830

    
   
830

   
831
	To answer such questions, just call this routine before you would normally try
831
	To answer such questions, just call this routine before you would normally try
832
	to aquire a lock. It doesn't do anything if the lock is not acquired. If the
832
	to aquire a lock. It doesn't do anything if the lock is not acquired. If the
833
	lock is taken, it will publish a line or two to the console via ast_log().
833
	lock is taken, it will publish a line or two to the console via ast_log().
834

    
   
834

   
835
	Sometimes, the lock message is pretty uninformative. For instance, you might
835
	Sometimes, the lock message is pretty uninformative. For instance, you might
836
	find that the lock is being aquired deep within the astobj2 code; this tells
836
	find that the lock is being aquired deep within the astobj2 code; this tells
837
	you little about higher level routines that call the astobj2 routines.
837
	you little about higher level routines that call the astobj2 routines.
838
	But, using gdb, you can set a break at the ast_log below, and for that
838
	But, using gdb, you can set a break at the ast_log below, and for that
839
	breakpoint, you can set the commands:
839
	breakpoint, you can set the commands:
840
	  where
840
	  where
841
	  cont
841
	  cont
842
	which will give a stack trace and continue. -- that aught to do the job!
842
	which will give a stack trace and continue. -- that aught to do the job!
843

    
   
843

   
844
*/
844
*/
845
void log_show_lock(void *this_lock_addr)
845
void log_show_lock(void *this_lock_addr)
846
{
846
{
847
	struct thr_lock_info *lock_info;
847
	struct thr_lock_info *lock_info;
848
	struct ast_str *str;
848
	struct ast_str *str;
849

    
   
849

   
850
	if (!(str = ast_str_create(4096))) {
850
	if (!(str = ast_str_create(4096))) {
851
		ast_log(LOG_NOTICE,"Could not create str\n");
851
		ast_log(LOG_NOTICE,"Could not create str\n");
852
		return;
852
		return;
853
	}
853
	}
854
	
854
	
855

    
   
855

   
856
	pthread_mutex_lock(&lock_infos_lock.mutex);
856
	pthread_mutex_lock(&lock_infos_lock.mutex);
857
	AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
857
	AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
858
		int i;
858
		int i;
859
		pthread_mutex_lock(&lock_info->lock);
859
		pthread_mutex_lock(&lock_info->lock);
860
		for (i = 0; str && i < lock_info->num_locks; i++) {
860
		for (i = 0; str && i < lock_info->num_locks; i++) {
861
			/* ONLY show info about this particular lock, if
861
			/* ONLY show info about this particular lock, if
862
			   it's acquired... */
862
			   it's acquired... */
863
			if (lock_info->locks[i].lock_addr == this_lock_addr) {
863
			if (lock_info->locks[i].lock_addr == this_lock_addr) {
864
				append_lock_information(&str, lock_info, i);
864
				append_lock_information(&str, lock_info, i);
865
				ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
865
				ast_log(LOG_NOTICE, "%s", ast_str_buffer(str));
866
				break;
866
				break;
867
			}
867
			}
868
		}
868
		}
869
		pthread_mutex_unlock(&lock_info->lock);
869
		pthread_mutex_unlock(&lock_info->lock);
870
	}
870
	}
871
	pthread_mutex_unlock(&lock_infos_lock.mutex);
871
	pthread_mutex_unlock(&lock_infos_lock.mutex);
872
	ast_free(str);
872
	ast_free(str);
873
}
873
}
874

    
   
874

   
875

    
   
875

   
876
static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
876
static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
877
{
877
{
878
	struct thr_lock_info *lock_info;
878
	struct thr_lock_info *lock_info;
879
	struct ast_str *str;
879
	struct ast_str *str;
880

    
   
880

   
881
	if (!(str = ast_str_create(4096)))
881
	if (!(str = ast_str_create(4096)))
882
		return CLI_FAILURE;
882
		return CLI_FAILURE;
883

    
   
883

   
884
	switch (cmd) {
884
	switch (cmd) {
885
	case CLI_INIT:
885
	case CLI_INIT:
886
		e->command = "core show locks";
886
		e->command = "core show locks";
887
		e->usage =
887
		e->usage =
888
			"Usage: core show locks\n"
888
			"Usage: core show locks\n"
889
			"       This command is for lock debugging.  It prints out which locks\n"
889
			"       This command is for lock debugging.  It prints out which locks\n"
890
			"are owned by each active thread.\n";
890
			"are owned by each active thread.\n";
891
		return NULL;
891
		return NULL;
892

    
   
892

   
893
	case CLI_GENERATE:
893
	case CLI_GENERATE:
894
		return NULL;
894
		return NULL;
895
	}
895
	}
896

    
   
896

   
897
	ast_str_append(&str, 0, "\n" 
897
	ast_str_append(&str, 0, "\n" 
898
	               "=======================================================================\n"
898
	               "=======================================================================\n"
899
	               "=== Currently Held Locks ==============================================\n"
899
	               "=== Currently Held Locks ==============================================\n"
900
	               "=======================================================================\n"
900
	               "=======================================================================\n"
901
	               "===\n"
901
	               "===\n"
902
	               "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
902
	               "=== <pending> <lock#> (<file>): <lock type> <line num> <function> <lock name> <lock addr> (times locked)\n"
903
	               "===\n");
903
	               "===\n");
904

    
   
904

   
905
	if (!str)
905
	if (!str)
906
		return CLI_FAILURE;
906
		return CLI_FAILURE;
907

    
   
907

   
908
	pthread_mutex_lock(&lock_infos_lock.mutex);
908
	pthread_mutex_lock(&lock_infos_lock.mutex);
909
	AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
909
	AST_LIST_TRAVERSE(&lock_infos, lock_info, entry) {
910
		int i;
910
		int i;
911
		if (lock_info->num_locks) {
911
		if (lock_info->num_locks) {
912
			ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id,
912
			ast_str_append(&str, 0, "=== Thread ID: 0x%lx (%s)\n", (long) lock_info->thread_id,
913
				lock_info->thread_name);
913
				lock_info->thread_name);
914
			pthread_mutex_lock(&lock_info->lock);
914
			pthread_mutex_lock(&lock_info->lock);
915
			for (i = 0; str && i < lock_info->num_locks; i++) {
915
			for (i = 0; str && i < lock_info->num_locks; i++) {
916
				append_lock_information(&str, lock_info, i);
916
				append_lock_information(&str, lock_info, i);
917
			}
917
			}
918
			pthread_mutex_unlock(&lock_info->lock);
918
			pthread_mutex_unlock(&lock_info->lock);
919
			if (!str)
919
			if (!str)
920
				break;
920
				break;
921
			ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
921
			ast_str_append(&str, 0, "=== -------------------------------------------------------------------\n"
922
			               "===\n");
922
			               "===\n");
923
			if (!str)
923
			if (!str)
924
				break;
924
				break;
925
		}
925
		}
926
	}
926
	}
927
	pthread_mutex_unlock(&lock_infos_lock.mutex);
927
	pthread_mutex_unlock(&lock_infos_lock.mutex);
928

    
   
928

   
929
	if (!str)
929
	if (!str)
930
		return CLI_FAILURE;
930
		return CLI_FAILURE;
931

    
   
931

   
932
	ast_str_append(&str, 0, "=======================================================================\n"
932
	ast_str_append(&str, 0, "=======================================================================\n"
933
	               "\n");
933
	               "\n");
934

    
   
934

   
935
	if (!str)
935
	if (!str)
936
		return CLI_FAILURE;
936
		return CLI_FAILURE;
937

    
   
937

   
938
	ast_cli(a->fd, "%s", ast_str_buffer(str));
938
	ast_cli(a->fd, "%s", ast_str_buffer(str));
939

    
   
939

   
940
	ast_free(str);
940
	ast_free(str);
941

    
   
941

   
942
	return CLI_SUCCESS;
942
	return CLI_SUCCESS;
943
}
943
}
944

    
   
944

   
945
static struct ast_cli_entry utils_cli[] = {
945
static struct ast_cli_entry utils_cli[] = {
946
	AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
946
	AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
947
};
947
};
948

    
   
948

   
949
#endif /* DEBUG_THREADS */
949
#endif /* DEBUG_THREADS */
950

    
   
950

   
951
/*
951
/*
952
 * support for 'show threads'. The start routine is wrapped by
952
 * support for 'show threads'. The start routine is wrapped by
953
 * dummy_start(), so that ast_register_thread() and
953
 * dummy_start(), so that ast_register_thread() and
954
 * ast_unregister_thread() know the thread identifier.
954
 * ast_unregister_thread() know the thread identifier.
955
 */
955
 */
956
struct thr_arg {
956
struct thr_arg {
957
	void *(*start_routine)(void *);
957
	void *(*start_routine)(void *);
958
	void *data;
958
	void *data;
959
	char *name;
959
	char *name;
960
};
960
};
961

    
   
961

   
962
/*
962
/*
963
 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
963
 * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
964
 * are odd macros which start and end a block, so they _must_ be
964
 * are odd macros which start and end a block, so they _must_ be
965
 * used in pairs (the latter with a '1' argument to call the
965
 * used in pairs (the latter with a '1' argument to call the
966
 * handler on exit.
966
 * handler on exit.
967
 * On BSD we don't need this, but we keep it for compatibility.
967
 * On BSD we don't need this, but we keep it for compatibility.
968
 */
968
 */
969
static void *dummy_start(void *data)
969
static void *dummy_start(void *data)
970
{
970
{
971
	void *ret;
971
	void *ret;
972
	struct thr_arg a = *((struct thr_arg *) data);	/* make a local copy */
972
	struct thr_arg a = *((struct thr_arg *) data);	/* make a local copy */
973
#ifdef DEBUG_THREADS
973
#ifdef DEBUG_THREADS
974
	struct thr_lock_info *lock_info;
974
	struct thr_lock_info *lock_info;
975
	pthread_mutexattr_t mutex_attr;
975
	pthread_mutexattr_t mutex_attr;
976
#endif
976
#endif
977

    
   
977

   
978
	/* note that even though data->name is a pointer to allocated memory,
978
	/* note that even though data->name is a pointer to allocated memory,
979
	   we are not freeing it here because ast_register_thread is going to
979
	   we are not freeing it here because ast_register_thread is going to
980
	   keep a copy of the pointer and then ast_unregister_thread will
980
	   keep a copy of the pointer and then ast_unregister_thread will
981
	   free the memory
981
	   free the memory
982
	*/
982
	*/
983
	ast_free(data);
983
	ast_free(data);
984
	ast_register_thread(a.name);
984
	ast_register_thread(a.name);
985
	pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
985
	pthread_cleanup_push(ast_unregister_thread, (void *) pthread_self());
986

    
   
986

   
987
#ifdef DEBUG_THREADS
987
#ifdef DEBUG_THREADS
988
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
988
	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
989
		return NULL;
989
		return NULL;
990

    
   
990

   
991
	lock_info->thread_id = pthread_self();
991
	lock_info->thread_id = pthread_self();
992
	lock_info->thread_name = strdup(a.name);
992
	lock_info->thread_name = strdup(a.name);
993

    
   
993

   
994
	pthread_mutexattr_init(&mutex_attr);
994
	pthread_mutexattr_init(&mutex_attr);
995
	pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
995
	pthread_mutexattr_settype(&mutex_attr, AST_MUTEX_KIND);
996
	pthread_mutex_init(&lock_info->lock, &mutex_attr);
996
	pthread_mutex_init(&lock_info->lock, &mutex_attr);
997
	pthread_mutexattr_destroy(&mutex_attr);
997
	pthread_mutexattr_destroy(&mutex_attr);
998

    
   
998

   
999
	pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
999
	pthread_mutex_lock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1000
	AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
1000
	AST_LIST_INSERT_TAIL(&lock_infos, lock_info, entry);
1001
	pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1001
	pthread_mutex_unlock(&lock_infos_lock.mutex); /* Intentionally not the wrapper */
1002
#endif /* DEBUG_THREADS */
1002
#endif /* DEBUG_THREADS */
1003

    
   
1003

   
1004
	ret = a.start_routine(a.data);
1004
	ret = a.start_routine(a.data);
1005

    
   
1005

   
1006
	pthread_cleanup_pop(1);
1006
	pthread_cleanup_pop(1);
1007

    
   
1007

   
1008
	return ret;
1008
	return ret;
1009
}
1009
}
1010

    
   
1010

   
1011
#endif /* !LOW_MEMORY */
1011
#endif /* !LOW_MEMORY */
1012

    
   
1012

   
1013
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1013
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1014
			     void *data, size_t stacksize, const char *file, const char *caller,
1014
			     void *data, size_t stacksize, const char *file, const char *caller,
1015
			     int line, const char *start_fn)
1015
			     int line, const char *start_fn)
1016
{
1016
{
1017
#if !defined(LOW_MEMORY)
1017
#if !defined(LOW_MEMORY)
1018
	struct thr_arg *a;
1018
	struct thr_arg *a;
1019
#endif
1019
#endif
1020

    
   
1020

   
1021
	if (!attr) {
1021
	if (!attr) {
1022
		attr = alloca(sizeof(*attr));
1022
		attr = alloca(sizeof(*attr));
1023
		pthread_attr_init(attr);
1023
		pthread_attr_init(attr);
1024
	}
1024
	}
1025

    
   
1025

   
1026
#ifdef __linux__
1026
#ifdef __linux__
1027
	/* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
1027
	/* On Linux, pthread_attr_init() defaults to PTHREAD_EXPLICIT_SCHED,
1028
	   which is kind of useless. Change this here to
1028
	   which is kind of useless. Change this here to
1029
	   PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
1029
	   PTHREAD_INHERIT_SCHED; that way the -p option to set realtime
1030
	   priority will propagate down to new threads by default.
1030
	   priority will propagate down to new threads by default.
1031
	   This does mean that callers cannot set a different priority using
1031
	   This does mean that callers cannot set a different priority using
1032
	   PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
1032
	   PTHREAD_EXPLICIT_SCHED in the attr argument; instead they must set
1033
	   the priority afterwards with pthread_setschedparam(). */
1033
	   the priority afterwards with pthread_setschedparam(). */
1034
	if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1034
	if ((errno = pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED)))
1035
		ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
1035
		ast_log(LOG_WARNING, "pthread_attr_setinheritsched: %s\n", strerror(errno));
1036
#endif
1036
#endif
1037

    
   
1037

   
1038
	if (!stacksize)
1038
	if (!stacksize)
1039
		stacksize = AST_STACKSIZE;
1039
		stacksize = AST_STACKSIZE;
1040

    
   
1040

   
1041
	if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
1041
	if ((errno = pthread_attr_setstacksize(attr, stacksize ? stacksize : AST_STACKSIZE)))
1042
		ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
1042
		ast_log(LOG_WARNING, "pthread_attr_setstacksize: %s\n", strerror(errno));
1043

    
   
1043

   
1044
#if !defined(LOW_MEMORY)
1044
#if !defined(LOW_MEMORY)
1045
	if ((a = ast_malloc(sizeof(*a)))) {
1045
	if ((a = ast_malloc(sizeof(*a)))) {
1046
		a->start_routine = start_routine;
1046
		a->start_routine = start_routine;
1047
		a->data = data;
1047
		a->data = data;
1048
		start_routine = dummy_start;
1048
		start_routine = dummy_start;
1049
		if (asprintf(&a->name, "%-20s started at [%5d] %s %s()",
1049
		if (asprintf(&a->name, "%-20s started at [%5d] %s %s()",
1050
			     start_fn, line, file, caller) < 0) {
1050
			     start_fn, line, file, caller) < 0) {
1051
			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
1051
			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
1052
			a->name = NULL;
1052
			a->name = NULL;
1053
		}
1053
		}
1054
		data = a;
1054
		data = a;
1055
	}
1055
	}
1056
#endif /* !LOW_MEMORY */
1056
#endif /* !LOW_MEMORY */
1057

    
   
1057

   
1058
	return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
1058
	return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
1059
}
1059
}
1060

    
   
1060

   
1061

    
   
1061

   
1062
int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1062
int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
1063
			     void *data, size_t stacksize, const char *file, const char *caller,
1063
			     void *data, size_t stacksize, const char *file, const char *caller,
1064
			     int line, const char *start_fn)
1064
			     int line, const char *start_fn)
1065
{
1065
{
1066
	unsigned char attr_destroy = 0;
1066
	unsigned char attr_destroy = 0;
1067
	int res;
1067
	int res;
1068

    
   
1068

   
1069
	if (!attr) {
1069
	if (!attr) {
1070
		attr = alloca(sizeof(*attr));
1070
		attr = alloca(sizeof(*attr));
1071
		pthread_attr_init(attr);
1071
		pthread_attr_init(attr);
1072
		attr_destroy = 1;
1072
		attr_destroy = 1;
1073
	}
1073
	}
1074

    
   
1074

   
1075
	if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1075
	if ((errno = pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED)))
1076
		ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
1076
		ast_log(LOG_WARNING, "pthread_attr_setdetachstate: %s\n", strerror(errno));
1077

    
   
1077

   
1078
	res = ast_pthread_create_stack(thread, attr, start_routine, data, 
1078
	res = ast_pthread_create_stack(thread, attr, start_routine, data, 
1079
	                               stacksize, file, caller, line, start_fn);
1079
	                               stacksize, file, caller, line, start_fn);
1080

    
   
1080

   
1081
	if (attr_destroy)
1081
	if (attr_destroy)
1082
		pthread_attr_destroy(attr);
1082
		pthread_attr_destroy(attr);
1083

    
   
1083

   
1084
	return res;
1084
	return res;
1085
}
1085
}
1086

    
   
1086

   
1087
int ast_wait_for_input(int fd, int ms)
1087
int ast_wait_for_input(int fd, int ms)
1088
{
1088
{
1089
	struct pollfd pfd[1];
1089
	struct pollfd pfd[1];
1090
	memset(pfd, 0, sizeof(pfd));
1090
	memset(pfd, 0, sizeof(pfd));
1091
	pfd[0].fd = fd;
1091
	pfd[0].fd = fd;
1092
	pfd[0].events = POLLIN|POLLPRI;
1092
	pfd[0].events = POLLIN|POLLPRI;
1093
	return ast_poll(pfd, 1, ms);
1093
	return ast_poll(pfd, 1, ms);
1094
}
1094
}
1095

    
   
1095

   
1096
static int ast_wait_for_output(int fd, int timeoutms)
1096
static int ast_wait_for_output(int fd, int timeoutms)
1097
{
1097
{
1098
	struct pollfd pfd = {
1098
	struct pollfd pfd = {
1099
		.fd = fd,
1099
		.fd = fd,
1100
		.events = POLLOUT,
1100
		.events = POLLOUT,
1101
	};
1101
	};
1102
	int res;
1102
	int res;
1103
	struct timeval start = ast_tvnow();
1103
	struct timeval start = ast_tvnow();
1104
	int elapsed = 0;
1104
	int elapsed = 0;
1105

    
   
1105

   
1106
	/* poll() until the fd is writable without blocking */
1106
	/* poll() until the fd is writable without blocking */
1107
	while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1107
	while ((res = ast_poll(&pfd, 1, timeoutms - elapsed)) <= 0) {
1108
		if (res == 0) {
1108
		if (res == 0) {
1109
			/* timed out. */
1109
			/* timed out. */
1110
#ifndef STANDALONE
1110
#ifndef STANDALONE
1111
			ast_debug(1, "Timed out trying to write\n");
1111
			ast_debug(1, "Timed out trying to write\n");
1112
#endif
1112
#endif
1113
			return -1;
1113
			return -1;
1114
		} else if (res == -1) {
1114
		} else if (res == -1) {
1115
			/* poll() returned an error, check to see if it was fatal */
1115
			/* poll() returned an error, check to see if it was fatal */
1116

    
   
1116

   
1117
			if (errno == EINTR || errno == EAGAIN) {
1117
			if (errno == EINTR || errno == EAGAIN) {
1118
				elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1118
				elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1119
				if (elapsed >= timeoutms) {
1119
				if (elapsed >= timeoutms) {
1120
					return -1;
1120
					return -1;
1121
				}
1121
				}
1122
				/* This was an acceptable error, go back into poll() */
1122
				/* This was an acceptable error, go back into poll() */
1123
				continue;
1123
				continue;
1124
			}
1124
			}
1125

    
   
1125

   
1126
			/* Fatal error, bail. */
1126
			/* Fatal error, bail. */
1127
			ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
1127
			ast_log(LOG_ERROR, "poll returned error: %s\n", strerror(errno));
1128

    
   
1128

   
1129
			return -1;
1129
			return -1;
1130
		}
1130
		}
1131
		elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1131
		elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1132
		if (elapsed >= timeoutms) {
1132
		if (elapsed >= timeoutms) {
1133
			return -1;
1133
			return -1;
1134
		}
1134
		}
1135
	}
1135
	}
1136

    
   
1136

   
1137
	return 0;
1137
	return 0;
1138
}
1138
}
1139

    
   
1139

   
1140
/*!
1140
/*!
1141
 * Try to write string, but wait no more than ms milliseconds before timing out.
1141
 * Try to write string, but wait no more than ms milliseconds before timing out.
1142
 *
1142
 *
1143
 * \note The code assumes that the file descriptor has NONBLOCK set,
1143
 * \note The code assumes that the file descriptor has NONBLOCK set,
1144
 * so there is only one system call made to do a write, unless we actually
1144
 * so there is only one system call made to do a write, unless we actually
1145
 * have a need to wait.  This way, we get better performance.
1145
 * have a need to wait.  This way, we get better performance.
1146
 * If the descriptor is blocking, all assumptions on the guaranteed
1146
 * If the descriptor is blocking, all assumptions on the guaranteed
1147
 * detail do not apply anymore.
1147
 * detail do not apply anymore.
1148
 */
1148
 */
1149
int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
1149
int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
1150
{
1150
{
1151
	struct timeval start = ast_tvnow();
1151
	struct timeval start = ast_tvnow();
1152
	int res = 0;
1152
	int res = 0;
1153
	int elapsed = 0;
1153
	int elapsed = 0;
1154

    
   
1154

   
1155
	while (len) {
1155
	while (len) {
1156
		if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1156
		if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1157
			return -1;
1157
			return -1;
1158
		}
1158
		}
1159

    
   
1159

   
1160
		res = write(fd, s, len);
1160
		res = write(fd, s, len);
1161

    
   
1161

   
1162
		if (res < 0 && errno != EAGAIN && errno != EINTR) {
1162
		if (res < 0 && errno != EAGAIN && errno != EINTR) {
1163
			/* fatal error from write() */
1163
			/* fatal error from write() */
1164
			ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1164
			ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
1165
			return -1;
1165
			return -1;
1166
		}
1166
		}
1167

    
   
1167

   
1168
		if (res < 0) {
1168
		if (res < 0) {
1169
			/* It was an acceptable error */
1169
			/* It was an acceptable error */
1170
			res = 0;
1170
			res = 0;
1171
		}
1171
		}
1172

    
   
1172

   
1173
		/* Update how much data we have left to write */
1173
		/* Update how much data we have left to write */
1174
		len -= res;
1174
		len -= res;
1175
		s += res;
1175
		s += res;
1176
		res = 0;
1176
		res = 0;
1177

    
   
1177

   
1178
		elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1178
		elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1179
		if (elapsed >= timeoutms) {
1179
		if (elapsed >= timeoutms) {
1180
			/* We've taken too long to write 
1180
			/* We've taken too long to write 
1181
			 * This is only an error condition if we haven't finished writing. */
1181
			 * This is only an error condition if we haven't finished writing. */
1182
			res = len ? -1 : 0;
1182
			res = len ? -1 : 0;
1183
			break;
1183
			break;
1184
		}
1184
		}
1185
	}
1185
	}
1186

    
   
1186

   
1187
	return res;
1187
	return res;
1188
}
1188
}
1189

    
   
1189

   
1190
int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
1190
int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeoutms)
1191
{
1191
{
1192
	struct timeval start = ast_tvnow();
1192
	struct timeval start = ast_tvnow();
1193
	int n = 0;
1193
	int n = 0;
1194
	int elapsed = 0;
1194
	int elapsed = 0;
1195

    
   
1195

   
1196
	while (len) {
1196
	while (len) {
1197
		if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1197
		if (ast_wait_for_output(fd, timeoutms - elapsed)) {
1198
			/* poll returned a fatal error, so bail out immediately. */
1198
			/* poll returned a fatal error, so bail out immediately. */
1199
			return -1;
1199
			return -1;
1200
		}
1200
		}
1201

    
   
1201

   
1202
		/* Clear any errors from a previous write */
1202
		/* Clear any errors from a previous write */
1203
		clearerr(f);
1203
		clearerr(f);
1204

    
   
1204

   
1205
		n = fwrite(src, 1, len, f);
1205
		n = fwrite(src, 1, len, f);
1206

    
   
1206

   
1207
		if (ferror(f) && errno != EINTR && errno != EAGAIN) {
1207
		if (ferror(f) && errno != EINTR && errno != EAGAIN) {
1208
			/* fatal error from fwrite() */
1208
			/* fatal error from fwrite() */
1209
			if (!feof(f)) {
1209
			if (!feof(f)) {
1210
				/* Don't spam the logs if it was just that the connection is closed. */
1210
				/* Don't spam the logs if it was just that the connection is closed. */
1211
				ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
1211
				ast_log(LOG_ERROR, "fwrite() returned error: %s\n", strerror(errno));
1212
			}
1212
			}
1213
			n = -1;
1213
			n = -1;
1214
			break;
1214
			break;
1215
		}
1215
		}
1216

    
   
1216

   
1217
		/* Update for data already written to the socket */
1217
		/* Update for data already written to the socket */
1218
		len -= n;
1218
		len -= n;
1219
		src += n;
1219
		src += n;
1220

    
   
1220

   
1221
		elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1221
		elapsed = ast_tvdiff_ms(ast_tvnow(), start);
1222
		if (elapsed >= timeoutms) {
1222
		if (elapsed >= timeoutms) {
1223
			/* We've taken too long to write 
1223
			/* We've taken too long to write 
1224
			 * This is only an error condition if we haven't finished writing. */
1224
			 * This is only an error condition if we haven't finished writing. */
1225
			n = len ? -1 : 0;
1225
			n = len ? -1 : 0;
1226
			break;
1226
			break;
1227
		}
1227
		}
1228
	}
1228
	}
1229

    
   
1229

   
1230
	while (fflush(f)) {
1230
	while (fflush(f)) {
1231
		if (errno == EAGAIN || errno == EINTR) {
1231
		if (errno == EAGAIN || errno == EINTR) {
1232
			continue;
1232
			continue;
1233
		}
1233
		}
1234
		if (!feof(f)) {
1234
		if (!feof(f)) {
1235
			/* Don't spam the logs if it was just that the connection is closed. */
1235
			/* Don't spam the logs if it was just that the connection is closed. */
1236
			ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
1236
			ast_log(LOG_ERROR, "fflush() returned error: %s\n", strerror(errno));
1237
		}
1237
		}
1238
		n = -1;
1238
		n = -1;
1239
		break;
1239
		break;
1240
	}
1240
	}
1241

    
   
1241

   
1242
	return n < 0 ? -1 : 0;
1242
	return n < 0 ? -1 : 0;
1243
}
1243
}
1244

    
   
1244

   
1245
char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
1245
char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
1246
{
1246
{
1247
	char *e;
1247
	char *e;
1248
	char *q;
1248
	char *q;
1249

    
   
1249

   
1250
	s = ast_strip(s);
1250
	s = ast_strip(s);
1251
	if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1251
	if ((q = strchr(beg_quotes, *s)) && *q != '\0') {
1252
		e = s + strlen(s) - 1;
1252
		e = s + strlen(s) - 1;
1253
		if (*e == *(end_quotes + (q - beg_quotes))) {
1253
		if (*e == *(end_quotes + (q - beg_quotes))) {
1254
			s++;
1254
			s++;
1255
			*e = '\0';
1255
			*e = '\0';
1256
		}
1256
		}
1257
	}
1257
	}
1258

    
   
1258

   
1259
	return s;
1259
	return s;
1260
}
1260
}
1261

    
   
1261

   
1262
char *ast_unescape_semicolon(char *s)
1262
char *ast_unescape_semicolon(char *s)
1263
{
1263
{
1264
	char *e;
1264
	char *e;
1265
	char *work = s;
1265
	char *work = s;
1266

    
   
1266

   
1267
	while ((e = strchr(work, ';'))) {
1267
	while ((e = strchr(work, ';'))) {
1268
		if ((e > work) && (*(e-1) == '\\')) {
1268
		if ((e > work) && (*(e-1) == '\\')) {
1269
			memmove(e - 1, e, strlen(e) + 1);
1269
			memmove(e - 1, e, strlen(e) + 1);
1270
			work = e;
1270
			work = e;
1271
		} else {
1271
		} else {
1272
			work = e + 1;
1272
			work = e + 1;
1273
		}
1273
		}
1274
	}
1274
	}
1275

    
   
1275

   
1276
	return s;
1276
	return s;
1277
}
1277
}
1278

    
   
1278

   
1279
/* !\brief unescape some C sequences in place, return pointer to the original string.
1279
/* !\brief unescape some C sequences in place, return pointer to the original string.
1280
 */
1280
 */
1281
char *ast_unescape_c(char *src)
1281
char *ast_unescape_c(char *src)
1282
{
1282
{
1283
	char c, *ret, *dst;
1283
	char c, *ret, *dst;
1284

    
   
1284

   
1285
	if (src == NULL)
1285
	if (src == NULL)
1286
		return NULL;
1286
		return NULL;
1287
	for (ret = dst = src; (c = *src++); *dst++ = c ) {
1287
	for (ret = dst = src; (c = *src++); *dst++ = c ) {
1288
		if (c != '\\')
1288
		if (c != '\\')
1289
			continue;	/* copy char at the end of the loop */
1289
			continue;	/* copy char at the end of the loop */
1290
		switch ((c = *src++)) {
1290
		switch ((c = *src++)) {
1291
		case '\0':	/* special, trailing '\' */
1291
		case '\0':	/* special, trailing '\' */
1292
			c = '\\';
1292
			c = '\\';
1293
			break;
1293
			break;
1294
		case 'b':	/* backspace */
1294
		case 'b':	/* backspace */
1295
			c = '\b';
1295
			c = '\b';
1296
			break;
1296
			break;
1297
		case 'f':	/* form feed */
1297
		case 'f':	/* form feed */
1298
			c = '\f';
1298
			c = '\f';
1299
			break;
1299
			break;
1300
		case 'n':
1300
		case 'n':
1301
			c = '\n';
1301
			c = '\n';
1302
			break;
1302
			break;
1303
		case 'r':
1303
		case 'r':
1304
			c = '\r';
1304
			c = '\r';
1305
			break;
1305
			break;
1306
		case 't':
1306
		case 't':
1307
			c = '\t';
1307
			c = '\t';
1308
			break;
1308
			break;
1309
		}
1309
		}
1310
		/* default, use the char literally */
1310
		/* default, use the char literally */
1311
	}
1311
	}
1312
	*dst = '\0';
1312
	*dst = '\0';
1313
	return ret;
1313
	return ret;
1314
}
1314
}
1315

    
   
1315

   
1316
int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
1316
int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
1317
{
1317
{
1318
	int result;
1318
	int result;
1319

    
   
1319

   
1320
	if (!buffer || !*buffer || !space || !*space)
1320
	if (!buffer || !*buffer || !space || !*space)
1321
		return -1;
1321
		return -1;
1322

    
   
1322

   
1323
	result = vsnprintf(*buffer, *space, fmt, ap);
1323
	result = vsnprintf(*buffer, *space, fmt, ap);
1324

    
   
1324

   
1325
	if (result < 0)
1325
	if (result < 0)
1326
		return -1;
1326
		return -1;
1327
	else if (result > *space)
1327
	else if (result > *space)
1328
		result = *space;
1328
		result = *space;
1329

    
   
1329

   
1330
	*buffer += result;
1330
	*buffer += result;
1331
	*space -= result;
1331
	*space -= result;
1332
	return 0;
1332
	return 0;
1333
}
1333
}
1334

    
   
1334

   
1335
int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
1335
int ast_build_string(char **buffer, size_t *space, const char *fmt, ...)
1336
{
1336
{
1337
	va_list ap;
1337
	va_list ap;
1338
	int result;
1338
	int result;
1339

    
   
1339

   
1340
	va_start(ap, fmt);
1340
	va_start(ap, fmt);
1341
	result = ast_build_string_va(buffer, space, fmt, ap);
1341
	result = ast_build_string_va(buffer, space, fmt, ap);
1342
	va_end(ap);
1342
	va_end(ap);
1343

    
   
1343

   
1344
	return result;
1344
	return result;
1345
}
1345
}
1346

    
   
1346

   
1347
int ast_true(const char *s)
1347
int ast_true(const char *s)
1348
{
1348
{
1349
	if (ast_strlen_zero(s))
1349
	if (ast_strlen_zero(s))
1350
		return 0;
1350
		return 0;
1351

    
   
1351

   
1352
	/* Determine if this is a true value */
1352
	/* Determine if this is a true value */
1353
	if (!strcasecmp(s, "yes") ||
1353
	if (!strcasecmp(s, "yes") ||
1354
	    !strcasecmp(s, "true") ||
1354
	    !strcasecmp(s, "true") ||
1355
	    !strcasecmp(s, "y") ||
1355
	    !strcasecmp(s, "y") ||
1356
	    !strcasecmp(s, "t") ||
1356
	    !strcasecmp(s, "t") ||
1357
	    !strcasecmp(s, "1") ||
1357
	    !strcasecmp(s, "1") ||
1358
	    !strcasecmp(s, "on"))
1358
	    !strcasecmp(s, "on"))
1359
		return -1;
1359
		return -1;
1360

    
   
1360

   
1361
	return 0;
1361
	return 0;
1362
}
1362
}
1363

    
   
1363

   
1364
int ast_false(const char *s)
1364
int ast_false(const char *s)
1365
{
1365
{
1366
	if (ast_strlen_zero(s))
1366
	if (ast_strlen_zero(s))
1367
		return 0;
1367
		return 0;
1368

    
   
1368

   
1369
	/* Determine if this is a false value */
1369
	/* Determine if this is a false value */
1370
	if (!strcasecmp(s, "no") ||
1370
	if (!strcasecmp(s, "no") ||
1371
	    !strcasecmp(s, "false") ||
1371
	    !strcasecmp(s, "false") ||
1372
	    !strcasecmp(s, "n") ||
1372
	    !strcasecmp(s, "n") ||
1373
	    !strcasecmp(s, "f") ||
1373
	    !strcasecmp(s, "f") ||
1374
	    !strcasecmp(s, "0") ||
1374
	    !strcasecmp(s, "0") ||
1375
	    !strcasecmp(s, "off"))
1375
	    !strcasecmp(s, "off"))
1376
		return -1;
1376
		return -1;
1377

    
   
1377

   
1378
	return 0;
1378
	return 0;
1379
}
1379
}
1380

    
   
1380

   
1381
#define ONE_MILLION	1000000
1381
#define ONE_MILLION	1000000
1382
/*
1382
/*
1383
 * put timeval in a valid range. usec is 0..999999
1383
 * put timeval in a valid range. usec is 0..999999
1384
 * negative values are not allowed and truncated.
1384
 * negative values are not allowed and truncated.
1385
 */
1385
 */
1386
static struct timeval tvfix(struct timeval a)
1386
static struct timeval tvfix(struct timeval a)
1387
{
1387
{
1388
	if (a.tv_usec >= ONE_MILLION) {
1388
	if (a.tv_usec >= ONE_MILLION) {
1389
		ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1389
		ast_log(LOG_WARNING, "warning too large timestamp %ld.%ld\n",
1390
			(long)a.tv_sec, (long int) a.tv_usec);
1390
			(long)a.tv_sec, (long int) a.tv_usec);
1391
		a.tv_sec += a.tv_usec / ONE_MILLION;
1391
		a.tv_sec += a.tv_usec / ONE_MILLION;
1392
		a.tv_usec %= ONE_MILLION;
1392
		a.tv_usec %= ONE_MILLION;
1393
	} else if (a.tv_usec < 0) {
1393
	} else if (a.tv_usec < 0) {
1394
		ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1394
		ast_log(LOG_WARNING, "warning negative timestamp %ld.%ld\n",
1395
			(long)a.tv_sec, (long int) a.tv_usec);
1395
			(long)a.tv_sec, (long int) a.tv_usec);
1396
		a.tv_usec = 0;
1396
		a.tv_usec = 0;
1397
	}
1397
	}
1398
	return a;
1398
	return a;
1399
}
1399
}
1400

    
   
1400

   
1401
struct timeval ast_tvadd(struct timeval a, struct timeval b)
1401
struct timeval ast_tvadd(struct timeval a, struct timeval b)
1402
{
1402
{
1403
	/* consistency checks to guarantee usec in 0..999999 */
1403
	/* consistency checks to guarantee usec in 0..999999 */
1404
	a = tvfix(a);
1404
	a = tvfix(a);
1405
	b = tvfix(b);
1405
	b = tvfix(b);
1406
	a.tv_sec += b.tv_sec;
1406
	a.tv_sec += b.tv_sec;
1407
	a.tv_usec += b.tv_usec;
1407
	a.tv_usec += b.tv_usec;
1408
	if (a.tv_usec >= ONE_MILLION) {
1408
	if (a.tv_usec >= ONE_MILLION) {
1409
		a.tv_sec++;
1409
		a.tv_sec++;
1410
		a.tv_usec -= ONE_MILLION;
1410
		a.tv_usec -= ONE_MILLION;
1411
	}
1411
	}
1412
	return a;
1412
	return a;
1413
}
1413
}
1414

    
   
1414

   
1415
struct timeval ast_tvsub(struct timeval a, struct timeval b)
1415
struct timeval ast_tvsub(struct timeval a, struct timeval b)
1416
{
1416
{
1417
	/* consistency checks to guarantee usec in 0..999999 */
1417
	/* consistency checks to guarantee usec in 0..999999 */
1418
	a = tvfix(a);
1418
	a = tvfix(a);
1419
	b = tvfix(b);
1419
	b = tvfix(b);
1420
	a.tv_sec -= b.tv_sec;
1420
	a.tv_sec -= b.tv_sec;
1421
	a.tv_usec -= b.tv_usec;
1421
	a.tv_usec -= b.tv_usec;
1422
	if (a.tv_usec < 0) {
1422
	if (a.tv_usec < 0) {
1423
		a.tv_sec-- ;
1423
		a.tv_sec-- ;
1424
		a.tv_usec += ONE_MILLION;
1424
		a.tv_usec += ONE_MILLION;
1425
	}
1425
	}
1426
	return a;
1426
	return a;
1427
}
1427
}
1428
#undef ONE_MILLION
1428
#undef ONE_MILLION
1429

    
   
1429

   
1430
/*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1430
/*! \brief glibc puts a lock inside random(3), so that the results are thread-safe.
1431
 * BSD libc (and others) do not. */
1431
 * BSD libc (and others) do not. */
1432

    
   
1432

   
1433
#ifndef linux
1433
#ifndef linux
1434
AST_MUTEX_DEFINE_STATIC(randomlock);
1434
AST_MUTEX_DEFINE_STATIC(randomlock);
1435
#endif
1435
#endif
1436

    
   
1436

   
1437
long int ast_random(void)
1437
long int ast_random(void)
1438
{
1438
{
1439
	long int res;
1439
	long int res;
1440
#ifdef HAVE_DEV_URANDOM
1440
#ifdef HAVE_DEV_URANDOM
1441
	if (dev_urandom_fd >= 0) {
1441
	if (dev_urandom_fd >= 0) {
1442
		int read_res = read(dev_urandom_fd, &res, sizeof(res));
1442
		int read_res = read(dev_urandom_fd, &res, sizeof(res));
1443
		if (read_res > 0) {
1443
		if (read_res > 0) {
1444
			long int rm = RAND_MAX;
1444
			long int rm = RAND_MAX;
1445
			res = res < 0 ? ~res : res;
1445
			res = res < 0 ? ~res : res;
1446
			rm++;
1446
			rm++;
1447
			return res % rm;
1447
			return res % rm;
1448
		}
1448
		}
1449
	}
1449
	}
1450
#endif
1450
#endif
1451
#ifdef linux
1451
#ifdef linux
1452
	res = random();
1452
	res = random();
1453
#else
1453
#else
1454
	ast_mutex_lock(&randomlock);
1454
	ast_mutex_lock(&randomlock);
1455
	res = random();
1455
	res = random();
1456
	ast_mutex_unlock(&randomlock);
1456
	ast_mutex_unlock(&randomlock);
1457
#endif
1457
#endif
1458
	return res;
1458
	return res;
1459
}
1459
}
1460

    
   
1460

   
1461
char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1461
char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
1462
{
1462
{
1463
 	char *dataPut = start;
1463
 	char *dataPut = start;
1464
	int inEscape = 0;
1464
	int inEscape = 0;
1465
	int inQuotes = 0;
1465
	int inQuotes = 0;
1466

    
   
1466

   
1467
	for (; *start; start++) {
1467
	for (; *start; start++) {
1468
		if (inEscape) {
1468
		if (inEscape) {
1469
			*dataPut++ = *start;       /* Always goes verbatim */
1469
			*dataPut++ = *start;       /* Always goes verbatim */
1470
			inEscape = 0;
1470
			inEscape = 0;
1471
		} else {
1471
		} else {
1472
			if (*start == '\\') {
1472
			if (*start == '\\') {
1473
				inEscape = 1;      /* Do not copy \ into the data */
1473
				inEscape = 1;      /* Do not copy \ into the data */
1474
			} else if (*start == '\'') {
1474
			} else if (*start == '\'') {
1475
				inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
1475
				inQuotes = 1 - inQuotes;   /* Do not copy ' into the data */
1476
			} else {
1476
			} else {
1477
				/* Replace , with |, unless in quotes */
1477
				/* Replace , with |, unless in quotes */
1478
				*dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1478
				*dataPut++ = inQuotes ? *start : ((*start == find) ? replace_with : *start);
1479
			}
1479
			}
1480
		}
1480
		}
1481
	}
1481
	}
1482
	if (start != dataPut)
1482
	if (start != dataPut)
1483
		*dataPut = 0;
1483
		*dataPut = 0;
1484
	return dataPut;
1484
	return dataPut;
1485
}
1485
}
1486

    
   
1486

   
1487
void ast_join(char *s, size_t len, const char * const w[])
1487
void ast_join(char *s, size_t len, const char * const w[])
1488
{
1488
{
1489
	int x, ofs = 0;
1489
	int x, ofs = 0;
1490
	const char *src;
1490
	const char *src;
1491

    
   
1491

   
1492
	/* Join words into a string */
1492
	/* Join words into a string */
1493
	if (!s)
1493
	if (!s)
1494
		return;
1494
		return;
1495
	for (x = 0; ofs < len && w[x]; x++) {
1495
	for (x = 0; ofs < len && w[x]; x++) {
1496
		if (x > 0)
1496
		if (x > 0)
1497
			s[ofs++] = ' ';
1497
			s[ofs++] = ' ';
1498
		for (src = w[x]; *src && ofs < len; src++)
1498
		for (src = w[x]; *src && ofs < len; src++)
1499
			s[ofs++] = *src;
1499
			s[ofs++] = *src;
1500
	}
1500
	}
1501
	if (ofs == len)
1501
	if (ofs == len)
1502
		ofs--;
1502
		ofs--;
1503
	s[ofs] = '\0';
1503
	s[ofs] = '\0';
1504
}
1504
}
1505

    
   
1505

   
1506
/*
1506
/*
1507
 * stringfields support routines.
1507
 * stringfields support routines.
1508
 */
1508
 */
1509

    
   
1509

   
1510
/* this is a little complex... string fields are stored with their
1510
/* this is a little complex... string fields are stored with their
1511
   allocated size in the bytes preceding the string; even the
1511
   allocated size in the bytes preceding the string; even the
1512
   constant 'empty' string has to be this way, so the code that
1512
   constant 'empty' string has to be this way, so the code that
1513
   checks to see if there is enough room for a new string doesn't
1513
   checks to see if there is enough room for a new string doesn't
1514
   have to have any special case checks
1514
   have to have any special case checks
1515
*/
1515
*/
1516

    
   
1516

   
1517
static const struct {
1517
static const struct {
1518
	ast_string_field_allocation allocation;
1518
	ast_string_field_allocation allocation;
1519
	char string[1];
1519
	char string[1];
1520
} __ast_string_field_empty_buffer;
1520
} __ast_string_field_empty_buffer;
1521

    
   
1521

   
1522
ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
1522
ast_string_field __ast_string_field_empty = __ast_string_field_empty_buffer.string;
1523

    
   
1523

   
1524
#define ALLOCATOR_OVERHEAD 48
1524
#define ALLOCATOR_OVERHEAD 48
1525

    
   
1525

   
1526
static size_t optimal_alloc_size(size_t size)
1526
static size_t optimal_alloc_size(size_t size)
1527
{
1527
{
1528
	unsigned int count;
1528
	unsigned int count;
1529

    
   
1529

   
1530
	size += ALLOCATOR_OVERHEAD;
1530
	size += ALLOCATOR_OVERHEAD;
1531

    
   
1531

   
1532
	for (count = 1; size; size >>= 1, count++);
1532
	for (count = 1; size; size >>= 1, count++);
1533

    
   
1533

   
1534
	return (1 << count) - ALLOCATOR_OVERHEAD;
1534
	return (1 << count) - ALLOCATOR_OVERHEAD;
1535
}
1535
}
1536

    
   
1536

   
1537
/*! \brief add a new block to the pool.
1537
/*! \brief add a new block to the pool.
1538
 * We can only allocate from the topmost pool, so the
1538
 * We can only allocate from the topmost pool, so the
1539
 * fields in *mgr reflect the size of that only.
1539
 * fields in *mgr reflect the size of that only.
1540
 */
1540
 */
1541
static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1541
static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1542
			   size_t size, const char *file, int lineno, const char *func)
1542
			   size_t size, const char *file, int lineno, const char *func)
1543
{
1543
{
1544
	struct ast_string_field_pool *pool;
1544
	struct ast_string_field_pool *pool;
1545
	size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
1545
	size_t alloc_size = optimal_alloc_size(sizeof(*pool) + size);
1546

    
   
1546

   
1547
#if defined(__AST_DEBUG_MALLOC)
1547
#if defined(__AST_DEBUG_MALLOC)
1548
	if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
1548
	if (!(pool = __ast_calloc(1, alloc_size, file, lineno, func))) {
1549
		return -1;
1549
		return -1;
1550
	}
1550
	}
1551
#else
1551
#else
1552
	if (!(pool = ast_calloc(1, alloc_size))) {
1552
	if (!(pool = ast_calloc(1, alloc_size))) {
1553
		return -1;
1553
		return -1;
1554
	}
1554
	}
1555
#endif
1555
#endif
1556

    
   
1556

   
1557
	pool->prev = *pool_head;
1557
	pool->prev = *pool_head;
1558
	pool->size = alloc_size - sizeof(*pool);
1558
	pool->size = alloc_size - sizeof(*pool);
1559
	*pool_head = pool;
1559
	*pool_head = pool;
1560
	mgr->last_alloc = NULL;
1560
	mgr->last_alloc = NULL;
1561

    
   
1561

   
1562
	return 0;
1562
	return 0;
1563
}
1563
}
1564

    
   
1564

   
1565
/*
1565
/*
1566
 * This is an internal API, code should not use it directly.
1566
 * This is an internal API, code should not use it directly.
1567
 * It initializes all fields as empty, then uses 'size' for 3 functions:
1567
 * It initializes all fields as empty, then uses 'size' for 3 functions:
1568
 * size > 0 means initialize the pool list with a pool of given size.
1568
 * size > 0 means initialize the pool list with a pool of given size.
1569
 *	This must be called right after allocating the object.
1569
 *	This must be called right after allocating the object.
1570
 * size = 0 means release all pools except the most recent one.
1570
 * size = 0 means release all pools except the most recent one.
1571
 *      If the first pool was allocated via embedding in another
1571
 *      If the first pool was allocated via embedding in another
1572
 *      object, that pool will be preserved instead.
1572
 *      object, that pool will be preserved instead.
1573
 *	This is useful to e.g. reset an object to the initial value.
1573
 *	This is useful to e.g. reset an object to the initial value.
1574
 * size < 0 means release all pools.
1574
 * size < 0 means release all pools.
1575
 *	This must be done before destroying the object.
1575
 *	This must be done before destroying the object.
1576
 */
1576
 */
1577
int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1577
int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
1578
			    int needed, const char *file, int lineno, const char *func)
1578
			    int needed, const char *file, int lineno, const char *func)
1579
{
1579
{
1580
	const char **p = (const char **) pool_head + 1;
1580
	const char **p = (const char **) pool_head + 1;
1581
	struct ast_string_field_pool *cur = NULL;
1581
	struct ast_string_field_pool *cur = NULL;
1582
	struct ast_string_field_pool *preserve = NULL;
1582
	struct ast_string_field_pool *preserve = NULL;
1583

    
   
1583

   
1584
	/* clear fields - this is always necessary */
1584
	/* clear fields - this is always necessary */
1585
	while ((struct ast_string_field_mgr *) p != mgr) {
1585
	while ((struct ast_string_field_mgr *) p != mgr) {
1586
		*p++ = __ast_string_field_empty;
1586
		*p++ = __ast_string_field_empty;
1587
	}
1587
	}
1588

    
   
1588

   
1589
	mgr->last_alloc = NULL;
1589
	mgr->last_alloc = NULL;
1590
#if defined(__AST_DEBUG_MALLOC)
1590
#if defined(__AST_DEBUG_MALLOC)
1591
	mgr->owner_file = file;
1591
	mgr->owner_file = file;
1592
	mgr->owner_func = func;
1592
	mgr->owner_func = func;
1593
	mgr->owner_line = lineno;
1593
	mgr->owner_line = lineno;
1594
#endif
1594
#endif
1595
	if (needed > 0) {		/* allocate the initial pool */
1595
	if (needed > 0) {		/* allocate the initial pool */
1596
		*pool_head = NULL;
1596
		*pool_head = NULL;
1597
		mgr->embedded_pool = NULL;
1597
		mgr->embedded_pool = NULL;
1598
		return add_string_pool(mgr, pool_head, needed, file, lineno, func);
1598
		return add_string_pool(mgr, pool_head, needed, file, lineno, func);
1599
	}
1599
	}
1600

    
   
1600

   
1601
	/* if there is an embedded pool, we can't actually release *all*
1601
	/* if there is an embedded pool, we can't actually release *all*
1602
	 * pools, we must keep the embedded one. if the caller is about
1602
	 * pools, we must keep the embedded one. if the caller is about
1603
	 * to free the structure that contains the stringfield manager
1603
	 * to free the structure that contains the stringfield manager
1604
	 * and embedded pool anyway, it will be freed as part of that
1604
	 * and embedded pool anyway, it will be freed as part of that
1605
	 * operation.
1605
	 * operation.
1606
	 */
1606
	 */
1607
	if ((needed < 0) && mgr->embedded_pool) {
1607
	if ((needed < 0) && mgr->embedded_pool) {
1608
		needed = 0;
1608
		needed = 0;
1609
	}
1609
	}
1610

    
   
1610

   
1611
	if (needed < 0) {		/* reset all pools */
1611
	if (needed < 0) {		/* reset all pools */
1612
		cur = *pool_head;
1612
		cur = *pool_head;
1613
	} else if (mgr->embedded_pool) { /* preserve the embedded pool */
1613
	} else if (mgr->embedded_pool) { /* preserve the embedded pool */
1614
		preserve = mgr->embedded_pool;
1614
		preserve = mgr->embedded_pool;
1615
		cur = *pool_head;
1615
		cur = *pool_head;
1616
	} else {			/* preserve the last pool */
1616
	} else {			/* preserve the last pool */
1617
		if (*pool_head == NULL) {
1617
		if (*pool_head == NULL) {
1618
			ast_log(LOG_WARNING, "trying to reset empty pool\n");
1618
			ast_log(LOG_WARNING, "trying to reset empty pool\n");
1619
			return -1;
1619
			return -1;
1620
		}
1620
		}
1621
		preserve = *pool_head;
1621
		preserve = *pool_head;
1622
		cur = preserve->prev;
1622
		cur = preserve->prev;
1623
	}
1623
	}
1624

    
   
1624

   
1625
	if (preserve) {
1625
	if (preserve) {
1626
		preserve->prev = NULL;
1626
		preserve->prev = NULL;
1627
		preserve->used = preserve->active = 0;
1627
		preserve->used = preserve->active = 0;
1628
	}
1628
	}
1629

    
   
1629

   
1630
	while (cur) {
1630
	while (cur) {
1631
		struct ast_string_field_pool *prev = cur->prev;
1631
		struct ast_string_field_pool *prev = cur->prev;
1632

    
   
1632

   
1633
		if (cur != preserve) {
1633
		if (cur != preserve) {
1634
			ast_free(cur);
1634
			ast_free(cur);
1635
		}
1635
		}
1636
		cur = prev;
1636
		cur = prev;
1637
	}
1637
	}
1638

    
   
1638

   
1639
	*pool_head = preserve;
1639
	*pool_head = preserve;
1640

    
   
1640

   
1641
	return 0;
1641
	return 0;
1642
}
1642
}
1643

    
   
1643

   
1644
ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
1644
ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
1645
						struct ast_string_field_pool **pool_head, size_t needed)
1645
						struct ast_string_field_pool **pool_head, size_t needed)
1646
{
1646
{
1647
	char *result = NULL;
1647
	char *result = NULL;
1648
	size_t space = (*pool_head)->size - (*pool_head)->used;
1648
	size_t space = (*pool_head)->size - (*pool_head)->used;
1649
	size_t to_alloc;
1649
	size_t to_alloc;
1650

    
   
1650

   
1651
	/* Make room for ast_string_field_allocation and make it a multiple of that. */
1651
	/* Make room for ast_string_field_allocation and make it a multiple of that. */
1652
	to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
1652
	to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
1653
	ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
1653
	ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
1654

    
   
1654

   
1655
	if (__builtin_expect(to_alloc > space, 0)) {
1655
	if (__builtin_expect(to_alloc > space, 0)) {
1656
		size_t new_size = (*pool_head)->size;
1656
		size_t new_size = (*pool_head)->size;
1657

    
   
1657

   
1658
		while (new_size < to_alloc) {
1658
		while (new_size < to_alloc) {
1659
			new_size *= 2;
1659
			new_size *= 2;
1660
		}
1660
		}
1661

    
   
1661

   
1662
#if defined(__AST_DEBUG_MALLOC)
1662
#if defined(__AST_DEBUG_MALLOC)
1663
		if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
1663
		if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
1664
			return NULL;
1664
			return NULL;
1665
#else
1665
#else
1666
		if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
1666
		if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
1667
			return NULL;
1667
			return NULL;
1668
#endif
1668
#endif
1669
	}
1669
	}
1670

    
   
1670

   
1671
	/* pool->base is always aligned (gcc aligned attribute). We ensure that
1671
	/* pool->base is always aligned (gcc aligned attribute). We ensure that
1672
	 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
1672
	 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
1673
	 * causing result to always be aligned as well; which in turn fixes that
1673
	 * causing result to always be aligned as well; which in turn fixes that
1674
	 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
1674
	 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
1675
	result = (*pool_head)->base + (*pool_head)->used;
1675
	result = (*pool_head)->base + (*pool_head)->used;
1676
	(*pool_head)->used += to_alloc;
1676
	(*pool_head)->used += to_alloc;
1677
	(*pool_head)->active += needed;
1677
	(*pool_head)->active += needed;
1678
	result += ast_alignof(ast_string_field_allocation);
1678
	result += ast_alignof(ast_string_field_allocation);
1679
	AST_STRING_FIELD_ALLOCATION(result) = needed;
1679
	AST_STRING_FIELD_ALLOCATION(result) = needed;
1680
	mgr->last_alloc = result;
1680
	mgr->last_alloc = result;
1681

    
   
1681

   
1682
	return result;
1682
	return result;
1683
}
1683
}
1684

    
   
1684

   
1685
int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
1685
int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
1686
				struct ast_string_field_pool **pool_head, size_t needed,
1686
				struct ast_string_field_pool **pool_head, size_t needed,
1687
				const ast_string_field *ptr)
1687
				const ast_string_field *ptr)
1688
{
1688
{
1689
	ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
1689
	ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
1690
	size_t space = (*pool_head)->size - (*pool_head)->used;
1690
	size_t space = (*pool_head)->size - (*pool_head)->used;
1691

    
   
1691

   
1692
	if (*ptr != mgr->last_alloc) {
1692
	if (*ptr != mgr->last_alloc) {
1693
		return 1;
1693
		return 1;
1694
	}
1694
	}
1695

    
   
1695

   
1696
	if (space < grow) {
1696
	if (space < grow) {
1697
		return 1;
1697
		return 1;
1698
	}
1698
	}
1699

    
   
1699

   
1700
	(*pool_head)->used += grow;
1700
	(*pool_head)->used += grow;
1701
	(*pool_head)->active += grow;
1701
	(*pool_head)->active += grow;
1702
	AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1702
	AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1703

    
   
1703

   
1704
	return 0;
1704
	return 0;
1705
}
1705
}
1706

    
   
1706

   
1707
void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
1707
void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
1708
				       const ast_string_field ptr)
1708
				       const ast_string_field ptr)
1709
{
1709
{
1710
	struct ast_string_field_pool *pool, *prev;
1710
	struct ast_string_field_pool *pool, *prev;
1711

    
   
1711

   
1712
	if (ptr == __ast_string_field_empty) {
1712
	if (ptr == __ast_string_field_empty) {
1713
		return;
1713
		return;
1714
	}
1714
	}
1715

    
   
1715

   
1716
	for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
1716
	for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
1717
		if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
1717
		if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
1718
			pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
1718
			pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
1719
			if ((pool->active == 0) && prev) {
1719
			if ((pool->active == 0) && prev) {
1720
				prev->prev = pool->prev;
1720
				prev->prev = pool->prev;
1721
				ast_free(pool);
1721
				ast_free(pool);
1722
			}
1722
			}
1723
			break;
1723
			break;
1724
		}
1724
		}
1725
	}
1725
	}
1726
}
1726
}
1727

    
   
1727

   
1728
void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
1728
void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
1729
				     struct ast_string_field_pool **pool_head,
1729
				     struct ast_string_field_pool **pool_head,
1730
				     ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
1730
				     ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
1731
{
1731
{
1732
	size_t needed;
1732
	size_t needed;
1733
	size_t available;
1733
	size_t available;
1734
	size_t space = (*pool_head)->size - (*pool_head)->used;
1734
	size_t space = (*pool_head)->size - (*pool_head)->used;
1735
	ssize_t grow;
1735
	ssize_t grow;
1736
	char *target;
1736
	char *target;
1737

    
   
1737

   
1738
	/* if the field already has space allocated, try to reuse it;
1738
	/* if the field already has space allocated, try to reuse it;
1739
	   otherwise, try to use the empty space at the end of the current
1739
	   otherwise, try to use the empty space at the end of the current
1740
	   pool
1740
	   pool
1741
	*/
1741
	*/
1742
	if (*ptr != __ast_string_field_empty) {
1742
	if (*ptr != __ast_string_field_empty) {
1743
		target = (char *) *ptr;
1743
		target = (char *) *ptr;
1744
		available = AST_STRING_FIELD_ALLOCATION(*ptr);
1744
		available = AST_STRING_FIELD_ALLOCATION(*ptr);
1745
		if (*ptr == mgr->last_alloc) {
1745
		if (*ptr == mgr->last_alloc) {
1746
			available += space;
1746
			available += space;
1747
		}
1747
		}
1748
	} else {
1748
	} else {
1749
		/* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
1749
		/* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
1750
		 * so we don't need to re-align anything here.
1750
		 * so we don't need to re-align anything here.
1751
		 */
1751
		 */
1752
		target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
1752
		target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
1753
		available = space - ast_alignof(ast_string_field_allocation);
1753
		available = space - ast_alignof(ast_string_field_allocation);
1754
	}
1754
	}
1755

    
   
1755

   
1756
	needed = vsnprintf(target, available, format, ap1) + 1;
1756
	needed = vsnprintf(target, available, format, ap1) + 1;
1757

    
   
1757

   
1758
	va_end(ap1);

   
1759

    
   

   
1760
	if (needed > available) {
1758
	if (needed > available) {
1761
		/* the allocation could not be satisfied using the field's current allocation
1759
		/* the allocation could not be satisfied using the field's current allocation
1762
		   (if it has one), or the space available in the pool (if it does not). allocate
1760
		   (if it has one), or the space available in the pool (if it does not). allocate
1763
		   space for it, adding a new string pool if necessary.
1761
		   space for it, adding a new string pool if necessary.
1764
		*/
1762
		*/
1765
		if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
1763
		if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
1766
			return;
1764
			return;
1767
		}
1765
		}
1768
		vsprintf(target, format, ap2);
1766
		vsprintf(target, format, ap2);
1769
		__ast_string_field_release_active(*pool_head, *ptr);
1767
		__ast_string_field_release_active(*pool_head, *ptr);
1770
		*ptr = target;
1768
		*ptr = target;
1771
	} else if (*ptr != target) {
1769
	} else if (*ptr != target) {
1772
		/* the allocation was satisfied using available space in the pool, but not
1770
		/* the allocation was satisfied using available space in the pool, but not
1773
		   using the space already allocated to the field
1771
		   using the space already allocated to the field
1774
		*/
1772
		*/
1775
		__ast_string_field_release_active(*pool_head, *ptr);
1773
		__ast_string_field_release_active(*pool_head, *ptr);
1776
		mgr->last_alloc = *ptr = target;
1774
		mgr->last_alloc = *ptr = target;
1777
		AST_STRING_FIELD_ALLOCATION(target) = needed;
1775
		AST_STRING_FIELD_ALLOCATION(target) = needed;
1778
		(*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
1776
		(*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
1779
		(*pool_head)->active += needed;
1777
		(*pool_head)->active += needed;
1780
	} else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
1778
	} else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
1781
		/* the allocation was satisfied by using available space in the pool *and*
1779
		/* the allocation was satisfied by using available space in the pool *and*
1782
		   the field was the last allocated field from the pool, so it grew
1780
		   the field was the last allocated field from the pool, so it grew
1783
		*/
1781
		*/
1784
		AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1782
		AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1785
		(*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
1783
		(*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
1786
		(*pool_head)->active += grow;
1784
		(*pool_head)->active += grow;
1787
	}
1785
	}
1788
}
1786
}
1789

    
   
1787

   
1790
void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
1788
void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
1791
				  struct ast_string_field_pool **pool_head,
1789
				  struct ast_string_field_pool **pool_head,
1792
				  ast_string_field *ptr, const char *format, ...)
1790
				  ast_string_field *ptr, const char *format, ...)
1793
{
1791
{
1794
	va_list ap1, ap2;
1792
	va_list ap1, ap2;
1795

    
   
1793

   
1796
	va_start(ap1, format);
1794
	va_start(ap1, format);
1797
	va_start(ap2, format);		/* va_copy does not exist on FreeBSD */
1795
	va_start(ap2, format);		/* va_copy does not exist on FreeBSD */
1798

    
   
1796

   
1799
	__ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
1797
	__ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
1800

    
   
1798

   
1801
	va_end(ap1);
1799
	va_end(ap1);
1802
	va_end(ap2);
1800
	va_end(ap2);
1803
}
1801
}
1804

    
   
1802

   
1805
void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
1803
void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
1806
				     size_t field_mgr_pool_offset, size_t pool_size, const char *file,
1804
				     size_t field_mgr_pool_offset, size_t pool_size, const char *file,
1807
				     int lineno, const char *func)
1805
				     int lineno, const char *func)
1808
{
1806
{
1809
	struct ast_string_field_mgr *mgr;
1807
	struct ast_string_field_mgr *mgr;
1810
	struct ast_string_field_pool *pool;
1808
	struct ast_string_field_pool *pool;
1811
	struct ast_string_field_pool **pool_head;
1809
	struct ast_string_field_pool **pool_head;
1812
	size_t pool_size_needed = sizeof(*pool) + pool_size;
1810
	size_t pool_size_needed = sizeof(*pool) + pool_size;
1813
	size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
1811
	size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
1814
	void *allocation;
1812
	void *allocation;
1815
	unsigned int x;
1813
	unsigned int x;
1816

    
   
1814

   
1817
#if defined(__AST_DEBUG_MALLOC)	
1815
#if defined(__AST_DEBUG_MALLOC)	
1818
	if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
1816
	if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
1819
		return NULL;
1817
		return NULL;
1820
	}
1818
	}
1821
#else
1819
#else
1822
	if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
1820
	if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
1823
		return NULL;
1821
		return NULL;
1824
	}
1822
	}
1825
#endif
1823
#endif
1826

    
   
1824

   
1827
	for (x = 0; x < num_structs; x++) {
1825
	for (x = 0; x < num_structs; x++) {
1828
		void *base = allocation + (size_to_alloc * x);
1826
		void *base = allocation + (size_to_alloc * x);
1829
		const char **p;
1827
		const char **p;
1830

    
   
1828

   
1831
		mgr = base + field_mgr_offset;
1829
		mgr = base + field_mgr_offset;
1832
		pool_head = base + field_mgr_pool_offset;
1830
		pool_head = base + field_mgr_pool_offset;
1833
		pool = base + struct_size;
1831
		pool = base + struct_size;
1834

    
   
1832

   
1835
		p = (const char **) pool_head + 1;
1833
		p = (const char **) pool_head + 1;
1836
		while ((struct ast_string_field_mgr *) p != mgr) {
1834
		while ((struct ast_string_field_mgr *) p != mgr) {
1837
			*p++ = __ast_string_field_empty;
1835
			*p++ = __ast_string_field_empty;
1838
		}
1836
		}
1839

    
   
1837

   
1840
		mgr->embedded_pool = pool;
1838
		mgr->embedded_pool = pool;
1841
		*pool_head = pool;
1839
		*pool_head = pool;
1842
		pool->size = size_to_alloc - struct_size - sizeof(*pool);
1840
		pool->size = size_to_alloc - struct_size - sizeof(*pool);
1843
#if defined(__AST_DEBUG_MALLOC)
1841
#if defined(__AST_DEBUG_MALLOC)
1844
		mgr->owner_file = file;
1842
		mgr->owner_file = file;
1845
		mgr->owner_func = func;
1843
		mgr->owner_func = func;
1846
		mgr->owner_line = lineno;
1844
		mgr->owner_line = lineno;
1847
#endif
1845
#endif
1848
	}
1846
	}
1849

    
   
1847

   
1850
	return allocation;
1848
	return allocation;
1851
}
1849
}
1852

    
   
1850

   
1853
/* end of stringfields support */
1851
/* end of stringfields support */
1854

    
   
1852

   
1855
AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1853
AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
1856

    
   
1854

   
1857
int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1855
int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
1858
{
1856
{
1859
	int ret;
1857
	int ret;
1860
	ast_mutex_lock(&fetchadd_m);
1858
	ast_mutex_lock(&fetchadd_m);
1861
	ret = *p;
1859
	ret = *p;
1862
	*p += v;
1860
	*p += v;
1863
	ast_mutex_unlock(&fetchadd_m);
1861
	ast_mutex_unlock(&fetchadd_m);
1864
	return ret;
1862
	return ret;
1865
}
1863
}
1866

    
   
1864

   
1867
/*! \brief
1865
/*! \brief
1868
 * get values from config variables.
1866
 * get values from config variables.
1869
 */
1867
 */
1870
int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
1868
int ast_get_timeval(const char *src, struct timeval *dst, struct timeval _default, int *consumed)
1871
{
1869
{
1872
	long double dtv = 0.0;
1870
	long double dtv = 0.0;
1873
	int scanned;
1871
	int scanned;
1874

    
   
1872

   
1875
	if (dst == NULL)
1873
	if (dst == NULL)
1876
		return -1;
1874
		return -1;
1877

    
   
1875

   
1878
	*dst = _default;
1876
	*dst = _default;
1879

    
   
1877

   
1880
	if (ast_strlen_zero(src))
1878
	if (ast_strlen_zero(src))
1881
		return -1;
1879
		return -1;
1882

    
   
1880

   
1883
	/* only integer at the moment, but one day we could accept more formats */
1881
	/* only integer at the moment, but one day we could accept more formats */
1884
	if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
1882
	if (sscanf(src, "%30Lf%n", &dtv, &scanned) > 0) {
1885
		dst->tv_sec = dtv;
1883
		dst->tv_sec = dtv;
1886
		dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
1884
		dst->tv_usec = (dtv - dst->tv_sec) * 1000000.0;
1887
		if (consumed)
1885
		if (consumed)
1888
			*consumed = scanned;
1886
			*consumed = scanned;
1889
		return 0;
1887
		return 0;
1890
	} else
1888
	} else
1891
		return -1;
1889
		return -1;
1892
}
1890
}
1893

    
   
1891

   
1894
/*! \brief
1892
/*! \brief
1895
 * get values from config variables.
1893
 * get values from config variables.
1896
 */
1894
 */
1897
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1895
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
1898
{
1896
{
1899
	long t;
1897
	long t;
1900
	int scanned;
1898
	int scanned;
1901

    
   
1899

   
1902
	if (dst == NULL)
1900
	if (dst == NULL)
1903
		return -1;
1901
		return -1;
1904

    
   
1902

   
1905
	*dst = _default;
1903
	*dst = _default;
1906

    
   
1904

   
1907
	if (ast_strlen_zero(src))
1905
	if (ast_strlen_zero(src))
1908
		return -1;
1906
		return -1;
1909

    
   
1907

   
1910
	/* only integer at the moment, but one day we could accept more formats */
1908
	/* only integer at the moment, but one day we could accept more formats */
1911
	if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
1909
	if (sscanf(src, "%30ld%n", &t, &scanned) == 1) {
1912
		*dst = t;
1910
		*dst = t;
1913
		if (consumed)
1911
		if (consumed)
1914
			*consumed = scanned;
1912
			*consumed = scanned;
1915
		return 0;
1913
		return 0;
1916
	} else
1914
	} else
1917
		return -1;
1915
		return -1;
1918
}
1916
}
1919

    
   
1917

   
1920
void ast_enable_packet_fragmentation(int sock)
1918
void ast_enable_packet_fragmentation(int sock)
1921
{
1919
{
1922
#if defined(HAVE_IP_MTU_DISCOVER)
1920
#if defined(HAVE_IP_MTU_DISCOVER)
1923
	int val = IP_PMTUDISC_DONT;
1921
	int val = IP_PMTUDISC_DONT;
1924
	
1922
	
1925
	if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
1923
	if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
1926
		ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
1924
		ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
1927
#endif /* HAVE_IP_MTU_DISCOVER */
1925
#endif /* HAVE_IP_MTU_DISCOVER */
1928
}
1926
}
1929

    
   
1927

   
1930
int ast_mkdir(const char *path, int mode)
1928
int ast_mkdir(const char *path, int mode)
1931
{
1929
{
1932
	char *ptr;
1930
	char *ptr;
1933
	int len = strlen(path), count = 0, x, piececount = 0;
1931
	int len = strlen(path), count = 0, x, piececount = 0;
1934
	char *tmp = ast_strdupa(path);
1932
	char *tmp = ast_strdupa(path);
1935
	char **pieces;
1933
	char **pieces;
1936
	char *fullpath = alloca(len + 1);
1934
	char *fullpath = alloca(len + 1);
1937
	int res = 0;
1935
	int res = 0;
1938

    
   
1936

   
1939
	for (ptr = tmp; *ptr; ptr++) {
1937
	for (ptr = tmp; *ptr; ptr++) {
1940
		if (*ptr == '/')
1938
		if (*ptr == '/')
1941
			count++;
1939
			count++;
1942
	}
1940
	}
1943

    
   
1941

   
1944
	/* Count the components to the directory path */
1942
	/* Count the components to the directory path */
1945
	pieces = alloca(count * sizeof(*pieces));
1943
	pieces = alloca(count * sizeof(*pieces));
1946
	for (ptr = tmp; *ptr; ptr++) {
1944
	for (ptr = tmp; *ptr; ptr++) {
1947
		if (*ptr == '/') {
1945
		if (*ptr == '/') {
1948
			*ptr = '\0';
1946
			*ptr = '\0';
1949
			pieces[piececount++] = ptr + 1;
1947
			pieces[piececount++] = ptr + 1;
1950
		}
1948
		}
1951
	}
1949
	}
1952

    
   
1950

   
1953
	*fullpath = '\0';
1951
	*fullpath = '\0';
1954
	for (x = 0; x < piececount; x++) {
1952
	for (x = 0; x < piececount; x++) {
1955
		/* This looks funky, but the buffer is always ideally-sized, so it's fine. */
1953
		/* This looks funky, but the buffer is always ideally-sized, so it's fine. */
1956
		strcat(fullpath, "/");
1954
		strcat(fullpath, "/");
1957
		strcat(fullpath, pieces[x]);
1955
		strcat(fullpath, pieces[x]);
1958
		res = mkdir(fullpath, mode);
1956
		res = mkdir(fullpath, mode);
1959
		if (res && errno != EEXIST)
1957
		if (res && errno != EEXIST)
1960
			return errno;
1958
			return errno;
1961
	}
1959
	}
1962
	return 0;
1960
	return 0;
1963
}
1961
}
1964

    
   
1962

   
1965
int ast_utils_init(void)
1963
int ast_utils_init(void)
1966
{
1964
{
1967
#ifdef HAVE_DEV_URANDOM
1965
#ifdef HAVE_DEV_URANDOM
1968
	dev_urandom_fd = open("/dev/urandom", O_RDONLY);
1966
	dev_urandom_fd = open("/dev/urandom", O_RDONLY);
1969
#endif
1967
#endif
1970
	base64_init();
1968
	base64_init();
1971
#ifdef DEBUG_THREADS
1969
#ifdef DEBUG_THREADS
1972
#if !defined(LOW_MEMORY)
1970
#if !defined(LOW_MEMORY)
1973
	ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
1971
	ast_cli_register_multiple(utils_cli, ARRAY_LEN(utils_cli));
1974
#endif
1972
#endif
1975
#endif
1973
#endif
1976
	return 0;
1974
	return 0;
1977
}
1975
}
1978

    
   
1976

   
1979

    
   
1977

   
1980
/*!
1978
/*!
1981
 *\brief Parse digest authorization header.
1979
 *\brief Parse digest authorization header.
1982
 *\return Returns -1 if we have no auth or something wrong with digest.
1980
 *\return Returns -1 if we have no auth or something wrong with digest.
1983
 *\note	This function may be used for Digest request and responce header.
1981
 *\note	This function may be used for Digest request and responce header.
1984
 * request arg is set to nonzero, if we parse Digest Request.
1982
 * request arg is set to nonzero, if we parse Digest Request.
1985
 * pedantic arg can be set to nonzero if we need to do addition Digest check.
1983
 * pedantic arg can be set to nonzero if we need to do addition Digest check.
1986
 */
1984
 */
1987
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
1985
int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic) {
1988
	char *c;
1986
	char *c;
1989
	struct ast_str *str = ast_str_create(16);
1987
	struct ast_str *str = ast_str_create(16);
1990

    
   
1988

   
1991
	/* table of recognised keywords, and places where they should be copied */
1989
	/* table of recognised keywords, and places where they should be copied */
1992
	const struct x {
1990
	const struct x {
1993
		const char *key;
1991
		const char *key;
1994
		const ast_string_field *field;
1992
		const ast_string_field *field;
1995
	} *i, keys[] = {
1993
	} *i, keys[] = {
1996
		{ "username=", &d->username },
1994
		{ "username=", &d->username },
1997
		{ "realm=", &d->realm },
1995
		{ "realm=", &d->realm },
1998
		{ "nonce=", &d->nonce },
1996
		{ "nonce=", &d->nonce },
1999
		{ "uri=", &d->uri },
1997
		{ "uri=", &d->uri },
2000
		{ "domain=", &d->domain },
1998
		{ "domain=", &d->domain },
2001
		{ "response=", &d->response },
1999
		{ "response=", &d->response },
2002
		{ "cnonce=", &d->cnonce },
2000
		{ "cnonce=", &d->cnonce },
2003
		{ "opaque=", &d->opaque },
2001
		{ "opaque=", &d->opaque },
2004
		/* Special cases that cannot be directly copied */
2002
		/* Special cases that cannot be directly copied */
2005
		{ "algorithm=", NULL },
2003
		{ "algorithm=", NULL },
2006
		{ "qop=", NULL },
2004
		{ "qop=", NULL },
2007
		{ "nc=", NULL },
2005
		{ "nc=", NULL },
2008
		{ NULL, 0 },
2006
		{ NULL, 0 },
2009
	};
2007
	};
2010

    
   
2008

   
2011
	if (ast_strlen_zero(digest) || !d || !str) {
2009
	if (ast_strlen_zero(digest) || !d || !str) {
2012
		ast_free(str);
2010
		ast_free(str);
2013
		return -1;
2011
		return -1;
2014
	}
2012
	}
2015

    
   
2013

   
2016
	ast_str_set(&str, 0, "%s", digest);
2014
	ast_str_set(&str, 0, "%s", digest);
2017

    
   
2015

   
2018
	c = ast_skip_blanks(ast_str_buffer(str));
2016
	c = ast_skip_blanks(ast_str_buffer(str));
2019

    
   
2017

   
2020
	if (strncasecmp(c, "Digest ", strlen("Digest "))) {
2018
	if (strncasecmp(c, "Digest ", strlen("Digest "))) {
2021
		ast_log(LOG_WARNING, "Missing Digest.\n");
2019
		ast_log(LOG_WARNING, "Missing Digest.\n");
2022
		ast_free(str);
2020
		ast_free(str);
2023
		return -1;
2021
		return -1;
2024
	}
2022
	}
2025
	c += strlen("Digest ");
2023
	c += strlen("Digest ");
2026

    
   
2024

   
2027
	/* lookup for keys/value pair */
2025
	/* lookup for keys/value pair */
2028
	while (c && *c && *(c = ast_skip_blanks(c))) {
2026
	while (c && *c && *(c = ast_skip_blanks(c))) {
2029
		/* find key */
2027
		/* find key */
2030
		for (i = keys; i->key != NULL; i++) {
2028
		for (i = keys; i->key != NULL; i++) {
2031
			char *src, *separator;
2029
			char *src, *separator;
2032
			int unescape = 0;
2030
			int unescape = 0;
2033
			if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2031
			if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
2034
				continue;
2032
				continue;
2035
			}
2033
			}
2036

    
   
2034

   
2037
			/* Found. Skip keyword, take text in quotes or up to the separator. */
2035
			/* Found. Skip keyword, take text in quotes or up to the separator. */
2038
			c += strlen(i->key);
2036
			c += strlen(i->key);
2039
			if (*c == '"') {
2037
			if (*c == '"') {
2040
				src = ++c;
2038
				src = ++c;
2041
				separator = "\"";
2039
				separator = "\"";
2042
				unescape = 1;
2040
				unescape = 1;
2043
			} else {
2041
			} else {
2044
				src = c;
2042
				src = c;
2045
				separator = ",";
2043
				separator = ",";
2046
			}
2044
			}
2047
			strsep(&c, separator); /* clear separator and move ptr */
2045
			strsep(&c, separator); /* clear separator and move ptr */
2048
			if (unescape) {
2046
			if (unescape) {
2049
				ast_unescape_c(src);
2047
				ast_unescape_c(src);
2050
			}
2048
			}
2051
			if (i->field) {
2049
			if (i->field) {
2052
				ast_string_field_ptr_set(d, i->field, src);
2050
				ast_string_field_ptr_set(d, i->field, src);
2053
			} else {
2051
			} else {
2054
				/* Special cases that require additional procesing */
2052
				/* Special cases that require additional procesing */
2055
				if (!strcasecmp(i->key, "algorithm=")) {
2053
				if (!strcasecmp(i->key, "algorithm=")) {
2056
					if (strcasecmp(src, "MD5")) {
2054
					if (strcasecmp(src, "MD5")) {
2057
						ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
2055
						ast_log(LOG_WARNING, "Digest algorithm: \"%s\" not supported.\n", src);
2058
						ast_free(str);
2056
						ast_free(str);
2059
						return -1;
2057
						return -1;
2060
					}
2058
					}
2061
				} else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
2059
				} else if (!strcasecmp(i->key, "qop=") && !strcasecmp(src, "auth")) {
2062
					d->qop = 1;
2060
					d->qop = 1;
2063
				} else if (!strcasecmp(i->key, "nc=")) {
2061
				} else if (!strcasecmp(i->key, "nc=")) {
2064
					unsigned long u;
2062
					unsigned long u;
2065
					if (sscanf(src, "%30lx", &u) != 1) {
2063
					if (sscanf(src, "%30lx", &u) != 1) {
2066
						ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
2064
						ast_log(LOG_WARNING, "Incorrect Digest nc value: \"%s\".\n", src);
2067
						ast_free(str);
2065
						ast_free(str);
2068
						return -1;
2066
						return -1;
2069
					}
2067
					}
2070
					ast_string_field_set(d, nc, src);
2068
					ast_string_field_set(d, nc, src);
2071
				}
2069
				}
2072
			}
2070
			}
2073
			break;
2071
			break;
2074
		}
2072
		}
2075
		if (i->key == NULL) { /* not found, try ',' */
2073
		if (i->key == NULL) { /* not found, try ',' */
2076
			strsep(&c, ",");
2074
			strsep(&c, ",");
2077
		}
2075
		}
2078
	}
2076
	}
2079
	ast_free(str);
2077
	ast_free(str);
2080

    
   
2078

   
2081
	/* Digest checkout */
2079
	/* Digest checkout */
2082
	if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2080
	if (ast_strlen_zero(d->realm) || ast_strlen_zero(d->nonce)) {
2083
		/* "realm" and "nonce" MUST be always exist */
2081
		/* "realm" and "nonce" MUST be always exist */
2084
		return -1;
2082
		return -1;
2085
	}
2083
	}
2086

    
   
2084

   
2087
	if (!request) {
2085
	if (!request) {
2088
		/* Additional check for Digest response */
2086
		/* Additional check for Digest response */
2089
		if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
2087
		if (ast_strlen_zero(d->username) || ast_strlen_zero(d->uri) || ast_strlen_zero(d->response)) {
2090
			return -1;
2088
			return -1;
2091
		}
2089
		}
2092

    
   
2090

   
2093
		if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2091
		if (pedantic && d->qop && (ast_strlen_zero(d->cnonce) || ast_strlen_zero(d->nc))) {
2094
			return -1;
2092
			return -1;
2095
		}
2093
		}
2096
	}
2094
	}
2097

    
   
2095

   
2098
	return 0;
2096
	return 0;
2099
}
2097
}
2100

    
   
2098

   
2101
#ifndef __AST_DEBUG_MALLOC
2099
#ifndef __AST_DEBUG_MALLOC
2102
int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
2100
int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...)
2103
{
2101
{
2104
	int res;
2102
	int res;
2105
	va_list ap;
2103
	va_list ap;
2106

    
   
2104

   
2107
	va_start(ap, fmt);
2105
	va_start(ap, fmt);
2108
	if ((res = vasprintf(ret, fmt, ap)) == -1) {
2106
	if ((res = vasprintf(ret, fmt, ap)) == -1) {
2109
		MALLOC_FAILURE_MSG;
2107
		MALLOC_FAILURE_MSG;
2110
	}
2108
	}
2111
	va_end(ap);
2109
	va_end(ap);
2112

    
   
2110

   
2113
	return res;
2111
	return res;
2114
}
2112
}
2115
#endif
2113
#endif
2116

    
   
2114

   
2117
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
2115
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
2118
{
2116
{
2119
	const char *envPATH = getenv("PATH");
2117
	const char *envPATH = getenv("PATH");
2120
	char *tpath, *path;
2118
	char *tpath, *path;
2121
	struct stat unused;
2119
	struct stat unused;
2122
	if (!envPATH) {
2120
	if (!envPATH) {
2123
		return NULL;
2121
		return NULL;
2124
	}
2122
	}
2125
	tpath = ast_strdupa(envPATH);
2123
	tpath = ast_strdupa(envPATH);
2126
	while ((path = strsep(&tpath, ":"))) {
2124
	while ((path = strsep(&tpath, ":"))) {
2127
		snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
2125
		snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
2128
		if (!stat(fullpath, &unused)) {
2126
		if (!stat(fullpath, &unused)) {
2129
			return fullpath;
2127
			return fullpath;
2130
		}
2128
		}
2131
	}
2129
	}
2132
	return NULL;
2130
	return NULL;
2133
}
2131
}
2134

    
   
2132

   
/branches/1.8/res/res_config_curl.c
Revision 361291 New Change
 
/branches/1.8/res/res_config_odbc.c
Revision 361291 New Change
 
/branches/1.8/res/res_config_pgsql.c
Revision 361291 New Change
 
  1. /branches/1.8/main/utils.c: Loading...
  2. /branches/1.8/res/res_config_curl.c: Loading...
  3. /branches/1.8/res/res_config_odbc.c: Loading...
  4. /branches/1.8/res/res_config_pgsql.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.