diff options
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/app.h | 5 | ||||
-rw-r--r-- | include/asterisk/cdr.h | 2 | ||||
-rw-r--r-- | include/asterisk/pbx.h | 12 | ||||
-rw-r--r-- | include/asterisk/strings.h | 244 | ||||
-rw-r--r-- | include/asterisk/tcptls.h | 2 | ||||
-rw-r--r-- | include/asterisk/threadstorage.h | 16 |
6 files changed, 264 insertions, 17 deletions
diff --git a/include/asterisk/app.h b/include/asterisk/app.h index 851ad9fa6..79af2313e 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -23,12 +23,17 @@ #ifndef _ASTERISK_APP_H #define _ASTERISK_APP_H +#include "asterisk/strings.h" +#include "asterisk/threadstorage.h" + struct ast_flags64; #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif +AST_THREADSTORAGE_EXTERNAL(global_app_buf); + /* IVR stuff */ /*! \brief Callback function for IVR diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h index 7ece62379..312c2546e 100644 --- a/include/asterisk/cdr.h +++ b/include/asterisk/cdr.h @@ -282,7 +282,7 @@ void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chan); * Changes the value of the last executed app * Returns nothing */ -void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data); +void ast_cdr_setapp(struct ast_cdr *cdr, const char *app, const char *data); /*! * \brief Convert a string to a detail record AMA flag diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index 3348bb8d7..2bb95930f 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -114,11 +114,11 @@ struct ast_switch { }; struct ast_timing { - int hastime; /*!< If time construct exists */ - unsigned int monthmask; /*!< Mask for month */ - unsigned int daymask; /*!< Mask for date */ - unsigned int dowmask; /*!< Mask for day of week (mon-sun) */ - unsigned int minmask[24]; /*!< Mask for minute */ + int hastime; /*!< If time construct exists */ + unsigned int monthmask; /*!< Mask for month */ + unsigned int daymask; /*!< Mask for date */ + unsigned int dowmask; /*!< Mask for day of week (sun-sat) */ + unsigned int minmask[48]; /*!< Mask for minute */ }; int ast_build_timing(struct ast_timing *i, const char *info); @@ -866,6 +866,8 @@ int pbx_builtin_raise_exception(struct ast_channel *chan, void *data); void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count); void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count); +void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used); +void ast_str_substitute_variables(struct ast_str **buf, size_t maxlen, struct ast_channel *chan, const char *templ); int ast_extension_patmatch(const char *pattern, const char *data); diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h index 43d5bfc41..84782a3ac 100644 --- a/include/asterisk/strings.h +++ b/include/asterisk/strings.h @@ -23,14 +23,17 @@ #ifndef _ASTERISK_STRINGS_H #define _ASTERISK_STRINGS_H +#define DEBUG_OPAQUE + #include <ctype.h> -#include "asterisk/inline_api.h" #include "asterisk/utils.h" #include "asterisk/threadstorage.h" /* You may see casts in this header that may seem useless but they ensure this file is C++ clean */ +#define AS_OR(a,b) ast_str_strlen(a) ? ast_str_buffer(a) : (b) + #ifdef AST_DEVMODE #define ast_strlen_zero(foo) _ast_strlen_zero(foo, __FILE__, __PRETTY_FUNCTION__, __LINE__) static force_inline int _ast_strlen_zero(const char *s, const char *file, const char *function, int line) @@ -202,7 +205,6 @@ void ast_copy_string(char *dst, const char *src, size_t size), } ) - /*! \brief Build a string in a buffer, designed to be called repeatedly @@ -338,13 +340,23 @@ int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default * struct ast_threadstorage pointer. */ struct ast_str { +#ifdef DEBUG_OPAQUE + size_t len2; + size_t used2; + struct ast_threadstorage *ts2; +#else size_t len; /*!< The current maximum length of the string */ size_t used; /*!< Amount of space used */ struct ast_threadstorage *ts; /*!< What kind of storage is this ? */ +#endif #define DS_MALLOC ((struct ast_threadstorage *)1) #define DS_ALLOCA ((struct ast_threadstorage *)2) #define DS_STATIC ((struct ast_threadstorage *)3) /* not supported yet */ +#ifdef DEBUG_OPAQUE + char str2[0]; +#else char str[0]; /*!< The string buffer */ +#endif }; /*! @@ -366,10 +378,16 @@ struct ast_str * attribute_malloc ast_str_create(size_t init_len), buf = (struct ast_str *)ast_calloc(1, sizeof(*buf) + init_len); if (buf == NULL) return NULL; - + +#ifdef DEBUG_OPAQUE + buf->len2 = init_len; + buf->used2 = 0; + buf->ts2 = DS_MALLOC; +#else buf->len = init_len; buf->used = 0; buf->ts = DS_MALLOC; +#endif return buf; } @@ -382,9 +400,15 @@ AST_INLINE_API( void ast_str_reset(struct ast_str *buf), { if (buf) { +#ifdef DEBUG_OPAQUE + buf->used2 = 0; + if (buf->len2) + buf->str2[0] = '\0'; +#else buf->used = 0; if (buf->len) buf->str[0] = '\0'; +#endif } } ) @@ -398,12 +422,83 @@ void ast_str_trim_blanks(struct ast_str *buf), if (!buf) { return; } +#ifdef DEBUG_OPAQUE + while (buf->used2 && buf->str2[buf->used2 - 1] < 33) { + buf->str2[--(buf->used2)] = '\0'; + } +#else while (buf->used && buf->str[buf->used - 1] < 33) { buf->str[--(buf->used)] = '\0'; } +#endif +} +) + +/*!\brief Returns the current length of the string stored within buf. + * \param A pointer to the ast_str string. + */ +AST_INLINE_API( +size_t ast_str_strlen(struct ast_str *buf), +{ +#ifdef DEBUG_OPAQUE + return buf->used2; +#else + return buf->used; +#endif +} +) + +/*!\brief Returns the current maximum length (without reallocation) of the current buffer. + * \param A pointer to the ast_str string. + */ +AST_INLINE_API( +size_t ast_str_size(struct ast_str *buf), +{ +#ifdef DEBUG_OPAQUE + return buf->len2; +#else + return buf->len; +#endif } ) +/*!\brief Returns the string buffer within the ast_str buf. + * \param A pointer to the ast_str string. + */ +AST_INLINE_API( +attribute_pure char *ast_str_buffer(struct ast_str *buf), +{ +#ifdef DEBUG_OPAQUE + return buf->str2; +#else + return buf->str; +#endif +} +) + +AST_INLINE_API( +char *ast_str_truncate(struct ast_str *buf, size_t len), +{ +#ifdef DEBUG_OPAQUE + if (len < 0) { + buf->used2 += len; + } else { + buf->used2 = len; + } + buf->str2[buf->used2] = '\0'; + return buf->str2; +#else + if (len < 0) { + buf->used += len; + } else { + buf->used = len; + } + buf->str[buf->used] = '\0'; + return buf->str; +#endif +} +) + /* * AST_INLINE_API() is a macro that takes a block of code as an argument. * Using preprocessor #directives in the argument is not supported by all @@ -427,6 +522,23 @@ int _ast_str_make_space(struct ast_str **buf, size_t new_len, const char *file, { struct ast_str *old_buf = *buf; +#ifdef DEBUG_OPAQUE + if (new_len <= (*buf)->len2) + return 0; /* success */ + if ((*buf)->ts2 == DS_ALLOCA || (*buf)->ts2 == DS_STATIC) + return -1; /* cannot extend */ + *buf = (struct ast_str *)__ast_realloc(*buf, new_len + sizeof(struct ast_str), file, lineno, function); + if (*buf == NULL) { + *buf = old_buf; + return -1; + } + if ((*buf)->ts2 != DS_MALLOC) { + pthread_setspecific((*buf)->ts2->key, *buf); + _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));) + } + + (*buf)->len2 = new_len; +#else if (new_len <= (*buf)->len) return 0; /* success */ if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC) @@ -442,6 +554,7 @@ int _ast_str_make_space(struct ast_str **buf, size_t new_len, const char *file, } (*buf)->len = new_len; +#endif return 0; } ) @@ -452,6 +565,23 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len), { struct ast_str *old_buf = *buf; +#ifdef DEBUG_OPAQUE + if (new_len <= (*buf)->len2) + return 0; /* success */ + if ((*buf)->ts2 == DS_ALLOCA || (*buf)->ts2 == DS_STATIC) + return -1; /* cannot extend */ + *buf = (struct ast_str *)ast_realloc(*buf, new_len + sizeof(struct ast_str)); + if (*buf == NULL) { + *buf = old_buf; + return -1; + } + if ((*buf)->ts2 != DS_MALLOC) { + pthread_setspecific((*buf)->ts2->key, *buf); + _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));) + } + + (*buf)->len2 = new_len; +#else if (new_len <= (*buf)->len) return 0; /* success */ if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC) @@ -467,11 +597,24 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len), } (*buf)->len = new_len; +#endif return 0; } ) #endif +#ifdef DEBUG_OPAQUE +#define ast_str_alloca(init_len) \ + ({ \ + struct ast_str *__ast_str_buf; \ + __ast_str_buf = alloca(sizeof(*__ast_str_buf) + init_len); \ + __ast_str_buf->len2 = init_len; \ + __ast_str_buf->used2 = 0; \ + __ast_str_buf->ts2 = DS_ALLOCA; \ + __ast_str_buf->str2[0] = '\0'; \ + (__ast_str_buf); \ + }) +#else #define ast_str_alloca(init_len) \ ({ \ struct ast_str *__ast_str_buf; \ @@ -482,6 +625,7 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len), __ast_str_buf->str[0] = '\0'; \ (__ast_str_buf); \ }) +#endif /*! * \brief Retrieve a thread locally stored dynamic string @@ -524,12 +668,20 @@ struct ast_str *ast_str_thread_get(struct ast_threadstorage *ts, buf = (struct ast_str *)ast_threadstorage_get(ts, sizeof(*buf) + init_len); if (buf == NULL) return NULL; - + +#ifdef DEBUG_OPAQUE + if (!buf->len2) { + buf->len2 = init_len; + buf->used2 = 0; + buf->ts2 = ts; + } +#else if (!buf->len) { buf->len = init_len; buf->used = 0; buf->ts = ts; } +#endif return buf; } @@ -544,12 +696,20 @@ struct ast_str *__ast_str_thread_get(struct ast_threadstorage *ts, buf = (struct ast_str *)__ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line); if (buf == NULL) return NULL; - + +#ifdef DEBUG_OPAQUE + if (!buf->len2) { + buf->len2 = init_len; + buf->used2 = 0; + buf->ts2 = ts; + } +#else if (!buf->len) { buf->len = init_len; buf->used = 0; buf->ts = ts; } +#endif return buf; } @@ -599,6 +759,8 @@ enum { */ int __attribute__((format(printf, 4, 0))) __ast_str_helper(struct ast_str **buf, size_t max_len, int append, const char *fmt, va_list ap); +char *__ast_str_helper2(struct ast_str **buf, size_t max_len, + const char *src, size_t maxsrc, int append, int escapecommas); /*! * \brief Set a dynamic string from a va_list @@ -655,6 +817,78 @@ AST_INLINE_API(int __attribute__((format(printf, 3, 0))) ast_str_append_va(struc } ) +/*!\brief Set a dynamic string to a non-NULL terminated substring. */ +AST_INLINE_API(char *ast_str_set_substr(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc), +{ + return __ast_str_helper2(buf, maxlen, src, maxsrc, 0, 0); +} +) + +/*!\brief Append a non-NULL terminated substring to the end of a dynamic string. */ +AST_INLINE_API(char *ast_str_append_substr(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc), +{ + return __ast_str_helper2(buf, maxlen, src, maxsrc, 1, 0); +} +) + +/*!\brief Set a dynamic string to a non-NULL terminated substring, with escaping of commas. */ +AST_INLINE_API(char *ast_str_set_escapecommas(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc), +{ + return __ast_str_helper2(buf, maxlen, src, maxsrc, 0, 1); +} +) + +/*!\brief Append a non-NULL terminated substring to the end of a dynamic string, with escaping of commas. */ +AST_INLINE_API(char *ast_str_append_escapecommas(struct ast_str **buf, size_t maxlen, const char *src, size_t maxsrc), +{ + return __ast_str_helper2(buf, maxlen, src, maxsrc, 1, 1); +} +) + +/*!\brief Wrapper for SQLGetData to use with dynamic strings + * \param buf Address of the pointer to the ast_str structure. + * \param maxlen The maximum size of the resulting string, or 0 for no limit. + * \param StatementHandle The statement handle from which to retrieve data. + * \param ColumnNumber Column number (1-based offset) for which to retrieve data. + * \param TargetType The SQL constant indicating what kind of data is to be retrieved (usually SQL_CHAR) + * \param StrLen_or_Ind A pointer to a length indicator, specifying the total length of data. + */ +#ifdef USE_ODBC +#include <sql.h> +#include <sqlext.h> +#include <sqltypes.h> + +AST_INLINE_API(SQLRETURN ast_str_SQLGetData(struct ast_str **buf, size_t maxlen, SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLLEN *StrLen_or_Ind), +{ + SQLRETURN res; + if (maxlen == 0) { +#ifdef DEBUG_OPAQUE + if (SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str2, 0, StrLen_or_Ind) == SQL_SUCCESS_WITH_INFO) { + ast_str_make_space(buf, *StrLen_or_Ind + 1); + } + maxlen = (*buf)->len2; + } else if (maxlen > 0) { + ast_str_make_space(buf, maxlen); + } + res = SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str2, maxlen, StrLen_or_Ind); + (*buf)->used2 = *StrLen_or_Ind; +#else + if (SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str, 0, StrLen_or_Ind) == SQL_SUCCESS_WITH_INFO) { + ast_str_make_space(buf, *StrLen_or_Ind + 1); + } + maxlen = (*buf)->len; + } else if (maxlen > 0) { + ast_str_make_space(buf, maxlen); + } + res = SQLGetData(StatementHandle, ColumnNumber, TargetType, (*buf)->str, maxlen, StrLen_or_Ind); + (*buf)->used = *StrLen_or_Ind; +#endif + return res; +} +) +#endif /* defined(USE_ODBC) */ + + /*! * \brief Set a dynamic string using variable arguments * diff --git a/include/asterisk/tcptls.h b/include/asterisk/tcptls.h index 6fb6d4b63..611709cbe 100644 --- a/include/asterisk/tcptls.h +++ b/include/asterisk/tcptls.h @@ -157,6 +157,6 @@ void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc); int ast_ssl_setup(struct ast_tls_config *cfg); HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *ser, void *buf, size_t count); -HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, void *buf, size_t count); +HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *ser, const void *buf, size_t count); #endif /* _ASTERISK_TCPTLS_H */ diff --git a/include/asterisk/threadstorage.h b/include/asterisk/threadstorage.h index cf6d47e32..ab586974f 100644 --- a/include/asterisk/threadstorage.h +++ b/include/asterisk/threadstorage.h @@ -85,7 +85,11 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len * \endcode */ #define AST_THREADSTORAGE(name) \ - AST_THREADSTORAGE_CUSTOM(name, NULL, ast_free_ptr) + AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr, static) +#define AST_THREADSTORAGE_PUBLIC(name) \ + AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr,) +#define AST_THREADSTORAGE_EXTERNAL(name) \ + extern struct ast_threadstorage name /*! * \brief Define a thread storage variable, with custom initialization and cleanup @@ -103,10 +107,12 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len * AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup); * \endcode */ +#define AST_THREADSTORAGE_CUSTOM(a,b,c) AST_THREADSTORAGE_CUSTOM_SCOPE(a,b,c,static) + #if !defined(DEBUG_THREADLOCALS) -#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \ +#define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \ static void __init_##name(void); \ -static struct ast_threadstorage name = { \ +scope struct ast_threadstorage name = { \ .once = THREADSTORAGE_ONCE_INIT, \ .key_init = __init_##name, \ .custom_init = c_init, \ @@ -116,9 +122,9 @@ static void __init_##name(void) \ pthread_key_create(&(name).key, c_cleanup); \ } #else /* defined(DEBUG_THREADLOCALS) */ -#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \ +#define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \ static void __init_##name(void); \ -static struct ast_threadstorage name = { \ +scope struct ast_threadstorage name = { \ .once = THREADSTORAGE_ONCE_INIT, \ .key_init = __init_##name, \ .custom_init = c_init, \ |