diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h index e0e5148a3f639442e77461c1ff55a9d77697f797..508a3ba7e959af10754373ae7fe42341ee3f5450 100755 --- a/include/asterisk/strings.h +++ b/include/asterisk/strings.h @@ -174,6 +174,20 @@ void ast_copy_string(char *dst, const char *src, size_t size), */ int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); +/*! + \brief Build a string in a buffer, designed to be called repeatedly + + This is a wrapper for snprintf, that properly handles the buffer pointer + and buffer space available. + + \return 0 on success, non-zero on failure. + \param buffer current position in buffer to place string into (will be updated on return) + \param space remaining space in buffer (will be updated on return) + \param fmt printf-style format string + \param ap varargs list of arguments for format +*/ +int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap); + /*! Make sure something is true */ /*! * Determine if a string containing a boolean value is "true". diff --git a/manager.c b/manager.c index 059c7298d46cdd9e2e58f690f229a1ca87a96a74..5e8cac8be0c93951f5d62f832d52c23a716ccaec 100755 --- a/manager.c +++ b/manager.c @@ -1473,13 +1473,16 @@ static int append_event(struct mansession *s, const char *str) int manager_event(int category, char *event, char *fmt, ...) { struct mansession *s; + char auth[80]; char tmp[4096]; - char auth[256]; + char *tmp_next = tmp; + size_t tmp_left = sizeof(tmp) - 2; va_list ap; - authority_to_str(category, auth, sizeof(auth)); + ast_build_string(&tmp_next, &tmp_left, "Event: %s\r\nPrivilege: %s\r\n", + event, authority_to_str(category, auth, sizeof(auth))); va_start(ap, fmt); - vsnprintf(tmp, sizeof(tmp) - 3, fmt, ap); + ast_build_string_va(&tmp_next, &tmp_left, fmt, ap); va_end(ap); strcat(tmp, "\r\n"); @@ -1492,11 +1495,9 @@ int manager_event(int category, char *event, char *fmt, ...) continue; ast_mutex_lock(&s->__lock); - ast_cli(s->fd, "Event: %s\r\n", event); - ast_cli(s->fd, "Privilege: %s\r\n", auth); if (s->busy) { append_event(s, tmp); - } else if (ast_carefulwrite(s->fd, tmp, strlen(tmp), 100) < 0) { + } else if (ast_carefulwrite(s->fd, tmp, sizeof(tmp) - tmp_left + 1, 100) < 0) { ast_log(LOG_WARNING, "Disconnecting slow (or gone) manager session!\n"); s->dead = 1; pthread_kill(s->t, SIGURG); diff --git a/utils.c b/utils.c index 79d73360543d1693e83aa4c84a75ec3914726f8c..fd99d581f369aaf36be084d450fa4194047b21a9 100755 --- a/utils.c +++ b/utils.c @@ -522,17 +522,14 @@ char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes) return s; } -int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) +int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap) { - va_list ap; int result; if (!buffer || !*buffer || !space || !*space) return -1; - va_start(ap, fmt); result = vsnprintf(*buffer, *space, fmt, ap); - va_end(ap); if (result < 0) return -1; @@ -544,6 +541,18 @@ int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) return 0; } +int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) +{ + va_list ap; + int result; + + va_start(ap, fmt); + result = ast_build_string_va(buffer, space, fmt, ap); + va_end(ap); + + return result; +} + int ast_true(const char *s) { if (!s || ast_strlen_zero(s))