From a1c94fece82f2445e538de0c93345d34c4abdf17 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 28 Mar 2013 23:59:20 +0000 Subject: [PATCH] Add uuid wrapper API call ast_uuid_generate_str(). * Updated test_uuid.c to test the new API call. * Made system use the new API call to eliminate "10's of lines" where used. * Fixed untested ast_strdup() return in stasis_subscribe() by eliminating the need for it. struct stasis_subscription now contains the uniqueid[] string. * Fixed some issues in exchangecal_write_event(): Create uid with enough space for a UUID string to avoid a realloc. Fix off by one error if the calendar event provided a UUID string. There is no need to check for NULL before calling ast_free(). git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@384302 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/uuid.h | 15 ++++++- main/sorcery.c | 10 +---- main/stasis.c | 18 ++------ main/uuid.c | 37 +++++++++++++---- res/res_calendar_exchange.c | 83 +++++++++++++++---------------------- res/res_sorcery_config.c | 9 +--- tests/test_uuid.c | 20 ++++++++- 7 files changed, 101 insertions(+), 91 deletions(-) diff --git a/include/asterisk/uuid.h b/include/asterisk/uuid.h index c10268d8c2..223ad18c9c 100644 --- a/include/asterisk/uuid.h +++ b/include/asterisk/uuid.h @@ -24,7 +24,7 @@ #define _ASTERISK_UUID_H /* Size of an RFC 4122 UUID string plus terminating null byte */ -#define AST_UUID_STR_LEN 37 +#define AST_UUID_STR_LEN (36 + 1) struct ast_uuid; @@ -50,10 +50,21 @@ struct ast_uuid *ast_uuid_generate(void); * \param uuid The UUID to convert to a string * \param[out] buf The buffer where the UUID string will be stored * \param size The size of the buffer. Must be at least AST_UUID_STR_LEN. - * \returns The UUID string (a pointer to buf) + * \return The UUID string (a pointer to buf) */ char *ast_uuid_to_str(const struct ast_uuid *uuid, char *buf, size_t size); +/*! + * \brief Generate a UUID string. + * \since 12.0.0 + * + * \param buf The buffer where the UUID string will be stored + * \param size The size of the buffer. Must be at least AST_UUID_STR_LEN. + * + * \return The UUID string (a pointer to buf) + */ +char *ast_uuid_generate_str(char *buf, size_t size); + /*! * \brief Convert a string to a UUID * diff --git a/main/sorcery.c b/main/sorcery.c index f7731d9c88..d0f2e7d5cd 100644 --- a/main/sorcery.c +++ b/main/sorcery.c @@ -807,15 +807,7 @@ void *ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, con } if (ast_strlen_zero(id)) { - struct ast_uuid *uuid = ast_uuid_generate(); - - if (!uuid) { - ao2_ref(details, -1); - return NULL; - } - - ast_uuid_to_str(uuid, details->id, AST_UUID_STR_LEN); - ast_free(uuid); + ast_uuid_generate_str(details->id, sizeof(details->id)); } else { ast_copy_string(details->id, id, sizeof(details->id)); } diff --git a/main/stasis.c b/main/stasis.c index d1baa442bc..2bd432a0c6 100644 --- a/main/stasis.c +++ b/main/stasis.c @@ -106,7 +106,7 @@ const char *stasis_topic_name(const struct stasis_topic *topic) /*! \internal */ struct stasis_subscription { /*! Unique ID for this subscription */ - char *uniqueid; + char uniqueid[AST_UUID_STR_LEN]; /*! Topic subscribed to. */ struct stasis_topic *topic; /*! Mailbox for processing incoming messages. */ @@ -121,8 +121,6 @@ static void subscription_dtor(void *obj) { struct stasis_subscription *sub = obj; ast_assert(!stasis_subscription_is_subscribed(sub)); - ast_free(sub->uniqueid); - sub->uniqueid = NULL; ao2_cleanup(sub->topic); sub->topic = NULL; ast_taskprocessor_unreference(sub->mailbox); @@ -134,27 +132,19 @@ static void send_subscription_change_message(struct stasis_topic *topic, char *u struct stasis_subscription *stasis_subscribe(struct stasis_topic *topic, stasis_subscription_cb callback, void *data) { RAII_VAR(struct stasis_subscription *, sub, NULL, ao2_cleanup); - RAII_VAR(struct ast_uuid *, id, NULL, ast_free); - char uniqueid[AST_UUID_STR_LEN]; sub = ao2_alloc(sizeof(*sub), subscription_dtor); if (!sub) { return NULL; } - id = ast_uuid_generate(); - if (!id) { - ast_log(LOG_ERROR, "UUID generation failed\n"); - return NULL; - } - ast_uuid_to_str(id, uniqueid, sizeof(uniqueid)); + ast_uuid_generate_str(sub->uniqueid, sizeof(sub->uniqueid)); - sub->mailbox = ast_threadpool_serializer(uniqueid, pool); + sub->mailbox = ast_threadpool_serializer(sub->uniqueid, pool); if (!sub->mailbox) { return NULL; } - sub->uniqueid = ast_strdup(uniqueid); ao2_ref(topic, +1); sub->topic = topic; sub->callback = callback; @@ -163,7 +153,7 @@ struct stasis_subscription *stasis_subscribe(struct stasis_topic *topic, stasis_ if (topic_add_subscription(topic, sub) != 0) { return NULL; } - send_subscription_change_message(topic, uniqueid, "Subscribe"); + send_subscription_change_message(topic, sub->uniqueid, "Subscribe"); ao2_ref(sub, +1); return sub; diff --git a/main/uuid.c b/main/uuid.c index 46ac63d205..e95a4265ee 100644 --- a/main/uuid.c +++ b/main/uuid.c @@ -38,13 +38,17 @@ struct ast_uuid { uuid_t uu; }; -struct ast_uuid *ast_uuid_generate(void) +/*! + * \internal + * \brief Generate a UUID. + * \since 12.0.0 + * + * \param uuid Fill this with a generated UUID. + * + * \return Nothing + */ +static void generate_uuid(struct ast_uuid *uuid) { - struct ast_uuid *uuid = ast_malloc(sizeof(*uuid)); - - if (!uuid) { - return NULL; - } /* libuuid provides three methods of generating uuids, * uuid_generate(), uuid_generate_random(), and uuid_generate_time(). * @@ -114,6 +118,16 @@ struct ast_uuid *ast_uuid_generate(void) if (!has_dev_urandom) { ast_mutex_unlock(&uuid_lock); } +} + +struct ast_uuid *ast_uuid_generate(void) +{ + struct ast_uuid *uuid = ast_malloc(sizeof(*uuid)); + + if (!uuid) { + return NULL; + } + generate_uuid(uuid); return uuid; } @@ -124,10 +138,19 @@ char *ast_uuid_to_str(const struct ast_uuid *uuid, char *buf, size_t size) return buf; } +char *ast_uuid_generate_str(char *buf, size_t size) +{ + struct ast_uuid uuid; + + generate_uuid(&uuid); + return ast_uuid_to_str(&uuid, buf, size); +} + struct ast_uuid *ast_str_to_uuid(const char *str) { struct ast_uuid *uuid = ast_malloc(sizeof(*uuid)); int res; + if (!uuid) { return NULL; } @@ -143,6 +166,7 @@ struct ast_uuid *ast_str_to_uuid(const char *str) struct ast_uuid *ast_uuid_copy(const struct ast_uuid *src) { struct ast_uuid *dst = ast_malloc(sizeof(*dst)); + if (!dst) { return NULL; } @@ -202,5 +226,4 @@ void ast_uuid_init(void) uuid_generate_random(uu); ast_debug(1, "UUID system initiated\n"); - return; } diff --git a/res/res_calendar_exchange.c b/res/res_calendar_exchange.c index ff711c5413..acfdcee7c9 100644 --- a/res/res_calendar_exchange.c +++ b/res/res_calendar_exchange.c @@ -243,17 +243,9 @@ static void *unref_exchangecal(void *obj) static struct ast_str *generate_exchange_uuid(struct ast_str *uid) { char buffer[AST_UUID_STR_LEN]; - struct ast_uuid *uuid = ast_uuid_generate(); - - if (!uuid) { - ast_str_set(&uid, 0, "%s", ""); - return uid; - } - - ast_str_set(&uid, 0, "%s", ast_uuid_to_str(uuid, buffer, AST_UUID_STR_LEN)); - - ast_free(uuid); + ast_uuid_generate_str(buffer, sizeof(buffer)); + ast_str_set(&uid, 0, "%s", buffer); return uid; } @@ -414,9 +406,17 @@ static struct ast_str *exchangecal_request(struct exchangecal_pvt *pvt, const ch static int exchangecal_write_event(struct ast_calendar_event *event) { - struct ast_str *body = NULL, *response = NULL, *subdir = NULL; - struct ast_str *uid = NULL, *summary = NULL, *description = NULL, *organizer = NULL, - *location = NULL, *start = NULL, *end = NULL, *busystate = NULL; + struct ast_str *body = NULL; + struct ast_str *response = NULL; + struct ast_str *subdir = NULL; + struct ast_str *uid = NULL; + struct ast_str *summary = NULL; + struct ast_str *description = NULL; + struct ast_str *organizer = NULL; + struct ast_str *location = NULL; + struct ast_str *start = NULL; + struct ast_str *end = NULL; + struct ast_str *busystate = NULL; int ret = -1; if (!event) { @@ -434,7 +434,7 @@ static int exchangecal_write_event(struct ast_calendar_event *event) goto write_cleanup; } - if (!(uid = ast_str_create(32)) || + if (!(uid = ast_str_create(AST_UUID_STR_LEN)) || !(summary = ast_str_create(32)) || !(description = ast_str_create(32)) || !(organizer = ast_str_create(32)) || @@ -449,7 +449,7 @@ static int exchangecal_write_event(struct ast_calendar_event *event) if (ast_strlen_zero(event->uid)) { uid = generate_exchange_uuid(uid); } else { - ast_str_set(&uid, 36, "%s", event->uid); + ast_str_set(&uid, AST_UUID_STR_LEN, "%s", event->uid); } if (!is_valid_uuid(uid)) { @@ -496,7 +496,14 @@ static int exchangecal_write_event(struct ast_calendar_event *event) " \n" " \n" "\n", - ast_str_buffer(uid), ast_str_buffer(summary), ast_str_buffer(description), ast_str_buffer(organizer), ast_str_buffer(location), ast_str_buffer(start), ast_str_buffer(end), ast_str_buffer(busystate)); + ast_str_buffer(uid), + ast_str_buffer(summary), + ast_str_buffer(description), + ast_str_buffer(organizer), + ast_str_buffer(location), + ast_str_buffer(start), + ast_str_buffer(end), + ast_str_buffer(busystate)); ast_verb(0, "\n\n%s\n\n", ast_str_buffer(body)); ast_str_set(&subdir, 0, "/Calendar/%s.eml", ast_str_buffer(uid)); @@ -505,39 +512,17 @@ static int exchangecal_write_event(struct ast_calendar_event *event) } write_cleanup: - if (uid) { - ast_free(uid); - } - if (summary) { - ast_free(summary); - } - if (description) { - ast_free(description); - } - if (organizer) { - ast_free(organizer); - } - if (location) { - ast_free(location); - } - if (start) { - ast_free(start); - } - if (end) { - ast_free(end); - } - if (busystate) { - ast_free(busystate); - } - if (body) { - ast_free(body); - } - if (response) { - ast_free(response); - } - if (subdir) { - ast_free(subdir); - } + ast_free(uid); + ast_free(summary); + ast_free(description); + ast_free(organizer); + ast_free(location); + ast_free(start); + ast_free(end); + ast_free(busystate); + ast_free(body); + ast_free(response); + ast_free(subdir); return ret; } diff --git a/res/res_sorcery_config.c b/res/res_sorcery_config.c index 10347ea817..509538f5aa 100644 --- a/res/res_sorcery_config.c +++ b/res/res_sorcery_config.c @@ -305,19 +305,12 @@ static void *sorcery_config_open(const char *data) { char *tmp = ast_strdupa(data), *filename = strsep(&tmp, ","), *option; struct sorcery_config *config; - struct ast_uuid *uuid; if (ast_strlen_zero(filename) || !(config = ao2_alloc_options(sizeof(*config) + strlen(filename) + 1, sorcery_config_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK))) { return NULL; } - if (!(uuid = ast_uuid_generate())) { - ao2_ref(config, -1); - return NULL; - } - - ast_uuid_to_str(uuid, config->uuid, AST_UUID_STR_LEN); - ast_free(uuid); + ast_uuid_generate_str(config->uuid, sizeof(config->uuid)); ast_rwlock_init(&config->objects.lock); config->buckets = DEFAULT_OBJECT_BUCKETS; diff --git a/tests/test_uuid.c b/tests/test_uuid.c index a76ec8b393..70769ef953 100644 --- a/tests/test_uuid.c +++ b/tests/test_uuid.c @@ -50,7 +50,23 @@ AST_TEST_DEFINE(uuid) break; } - /* First, make sure that we can generate a UUID */ + /* Use method of generating UUID directly as a string. */ + ast_uuid_generate_str(uuid_str, sizeof(uuid_str)); + if (strlen(uuid_str) != (AST_UUID_STR_LEN - 1)) { + ast_test_status_update(test, "Failed to directly generate UUID string\n"); + goto end; + } + ast_test_status_update(test, "Generate UUID direct to string, got %s\n", uuid_str); + + /* Now convert the direct UUID string to a UUID */ + uuid1 = ast_str_to_uuid(uuid_str); + if (!uuid1) { + ast_test_status_update(test, "Unable to convert direct UUID string %s to UUID\n", uuid_str); + goto end; + } + ast_free(uuid1); + + /* Make sure that we can generate a UUID */ uuid1 = ast_uuid_generate(); if (!uuid1) { ast_test_status_update(test, "Unable to generate a UUID\n"); @@ -71,7 +87,7 @@ AST_TEST_DEFINE(uuid) goto end; } - ast_test_status_update(test, "Converted uuid to string, got %s\n", uuid_str); + ast_test_status_update(test, "Second generated UUID converted to string, got %s\n", uuid_str); /* Now convert the string back to a UUID */ uuid2 = ast_str_to_uuid(uuid_str);