<p>Sean Bright has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/5948">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_voicemail: Cleanup ODBC connection handling<br><br>The primary focus of this patch is adding a missing call to<br>ast_odbc_release_obj(), but is also a general cleanup of the ODBC<br>related code in app_voicemail.<br><br>ASTERISK-27093 #close<br><br>Change-Id: I8e285142eaeb3146b4287a928276b70db76c902b<br>---<br>M apps/app_voicemail.c<br>1 file changed, 379 insertions(+), 390 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/48/5948/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c<br>index fe5657d..e5591e5 100644<br>--- a/apps/app_voicemail.c<br>+++ b/apps/app_voicemail.c<br>@@ -3781,12 +3781,12 @@<br> SQLHSTMT stmt;<br> <br> res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>+ if (!SQL_SUCCEEDED(res)) {<br> ast_log(AST_LOG_WARNING, "SQL Alloc Handle failed!\n");<br> return NULL;<br> }<br> res = SQLPrepare(stmt, (unsigned char *) gps->sql, SQL_NTS);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>+ if (!SQL_SUCCEEDED(res)) {<br> ast_log(AST_LOG_WARNING, "SQL Prepare failed![%s]\n", gps->sql);<br> SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br> return NULL;<br>@@ -3828,14 +3828,14 @@<br> * \brief Retrieves a file from an ODBC data store.<br> * \param dir the path to the file to be retrieved.<br> * \param msgnum the message number, such as within a mailbox folder.<br>- * <br>+ *<br> * This method is used by the RETRIEVE macro when mailboxes are stored in an ODBC back end.<br> * The purpose is to get the message from the database store to the local file system, so that the message may be played, or the information file may be read.<br> *<br> * The file is looked up by invoking a SQL on the odbc_table (default 'voicemessages') using the dir and msgnum input parameters.<br> * The output is the message information file with the name msgnum and the extension .txt<br> * and the message file with the extension of its format, in the directory with base file name of the msgnum.<br>- * <br>+ *<br> * \return 0 on success, -1 on error.<br> */<br> static int retrieve_file(char *dir, int msgnum)<br>@@ -3848,7 +3848,7 @@<br> SQLSMALLINT colcount = 0;<br> SQLHSTMT stmt;<br> char sql[PATH_MAX];<br>- char fmt[80]="";<br>+ char fmt[80] = "";<br> char *c;<br> char coltitle[256];<br> SQLSMALLINT collen;<br>@@ -3864,144 +3864,139 @@<br> char msgnums[80];<br> char *argv[] = { dir, msgnums };<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };<br>-<br> struct odbc_obj *obj;<br>- obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- ast_copy_string(fmt, vmfmts, sizeof(fmt));<br>- c = strchr(fmt, '|');<br>- if (c)<br>- *c = '\0';<br>- if (!strcasecmp(fmt, "wav49"))<br>- strcpy(fmt, "WAV");<br>- snprintf(msgnums, sizeof(msgnums), "%d", msgnum);<br>- if (msgnum > -1)<br>- make_file(fn, sizeof(fn), dir, msgnum);<br>- else<br>- ast_copy_string(fn, dir, sizeof(fn));<br> <br>- /* Create the information file */<br>- snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);<br>- <br>- if (!(f = fopen(full_fn, "w+"))) {<br>- ast_log(AST_LOG_WARNING, "Failed to open/create '%s'\n", full_fn);<br>- goto yuck;<br>- }<br>- <br>- snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);<br>- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?", odbc_table);<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLFetch(stmt);<br>- if (res == SQL_NO_DATA) {<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- } else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- fd = open(full_fn, O_RDWR | O_CREAT | O_TRUNC, VOICEMAIL_FILE_MODE);<br>- if (fd < 0) {<br>- ast_log(AST_LOG_WARNING, "Failed to write '%s': %s\n", full_fn, strerror(errno));<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLNumResultCols(stmt, &colcount);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { <br>- ast_log(AST_LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- if (f) <br>- fprintf(f, "[message]\n");<br>- for (x = 0; x < colcount; x++) {<br>- rowdata[0] = '\0';<br>- colsize = 0;<br>- collen = sizeof(coltitle);<br>- res = SQLDescribeCol(stmt, x + 1, (unsigned char *) coltitle, sizeof(coltitle), &collen, <br>- &datatype, &colsize, &decimaldigits, &nullable);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- if (!strcasecmp(coltitle, "recording")) {<br>- off_t offset;<br>- res = SQLGetData(stmt, x + 1, SQL_BINARY, rowdata, 0, &colsize2);<br>- fdlen = colsize2;<br>- if (fd > -1) {<br>- char tmp[1]="";<br>- lseek(fd, fdlen - 1, SEEK_SET);<br>- if (write(fd, tmp, 1) != 1) {<br>- close(fd);<br>- fd = -1;<br>- continue;<br>- }<br>- /* Read out in small chunks */<br>- for (offset = 0; offset < colsize2; offset += CHUNKSIZE) {<br>- if ((fdm = mmap(NULL, CHUNKSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) {<br>- ast_log(AST_LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);<br>- SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- } else {<br>- res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE, NULL);<br>- munmap(fdm, CHUNKSIZE);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- unlink(full_fn);<br>- SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- }<br>- }<br>- if (truncate(full_fn, fdlen) < 0) {<br>- ast_log(LOG_WARNING, "Unable to truncate '%s': %s\n", full_fn, strerror(errno));<br>- }<br>- }<br>- } else {<br>- res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res == SQL_NULL_DATA) && (!strcasecmp(coltitle, "msg_id"))) {<br>- char msg_id[MSG_ID_LEN];<br>- generate_msg_id(msg_id);<br>- snprintf(rowdata, sizeof(rowdata), "%s", msg_id);<br>- odbc_update_msg_id(dir, msgnum, msg_id);<br>- } else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error! coltitle=%s\n[%s]\n\n", coltitle, sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- if (strcasecmp(coltitle, "msgnum") && strcasecmp(coltitle, "dir") && f)<br>- fprintf(f, "%s=%s\n", coltitle, rowdata);<br>- }<br>- }<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- } else<br>+ obj = ast_odbc_request_obj(odbc_database, 0);<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>-yuck:<br>+ return -1;<br>+ }<br>+<br>+ ast_copy_string(fmt, vmfmts, sizeof(fmt));<br>+ c = strchr(fmt, '|');<br>+ if (c)<br>+ *c = '\0';<br>+ if (!strcasecmp(fmt, "wav49"))<br>+ strcpy(fmt, "WAV");<br>+<br>+ snprintf(msgnums, sizeof(msgnums), "%d", msgnum);<br>+ if (msgnum > -1)<br>+ make_file(fn, sizeof(fn), dir, msgnum);<br>+ else<br>+ ast_copy_string(fn, dir, sizeof(fn));<br>+<br>+ /* Create the information file */<br>+ snprintf(full_fn, sizeof(full_fn), "%s.txt", fn);<br>+<br>+ if (!(f = fopen(full_fn, "w+"))) {<br>+ ast_log(AST_LOG_WARNING, "Failed to open/create '%s'\n", full_fn);<br>+ goto bail;<br>+ }<br>+<br>+ snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);<br>+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?", odbc_table);<br>+<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt) {<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ goto bail;<br>+ }<br>+<br>+ res = SQLFetch(stmt);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ if (res != SQL_NO_DATA) {<br>+ ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>+ }<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ fd = open(full_fn, O_RDWR | O_CREAT | O_TRUNC, VOICEMAIL_FILE_MODE);<br>+ if (fd < 0) {<br>+ ast_log(AST_LOG_WARNING, "Failed to write '%s': %s\n", full_fn, strerror(errno));<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ res = SQLNumResultCols(stmt, &colcount);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ fprintf(f, "[message]\n");<br>+ for (x = 0; x < colcount; x++) {<br>+ rowdata[0] = '\0';<br>+ colsize = 0;<br>+ collen = sizeof(coltitle);<br>+ res = SQLDescribeCol(stmt, x + 1, (unsigned char *) coltitle, sizeof(coltitle), &collen,<br>+ &datatype, &colsize, &decimaldigits, &nullable);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+ if (!strcasecmp(coltitle, "recording")) {<br>+ off_t offset;<br>+ res = SQLGetData(stmt, x + 1, SQL_BINARY, rowdata, 0, &colsize2);<br>+ fdlen = colsize2;<br>+ if (fd > -1) {<br>+ char tmp[1] = "";<br>+ lseek(fd, fdlen - 1, SEEK_SET);<br>+ if (write(fd, tmp, 1) != 1) {<br>+ close(fd);<br>+ fd = -1;<br>+ continue;<br>+ }<br>+ /* Read out in small chunks */<br>+ for (offset = 0; offset < colsize2; offset += CHUNKSIZE) {<br>+ if ((fdm = mmap(NULL, CHUNKSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) {<br>+ ast_log(AST_LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);<br>+ goto bail_with_handle;<br>+ }<br>+ res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE, NULL);<br>+ munmap(fdm, CHUNKSIZE);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>+ unlink(full_fn);<br>+ goto bail_with_handle;<br>+ }<br>+ }<br>+ if (truncate(full_fn, fdlen) < 0) {<br>+ ast_log(LOG_WARNING, "Unable to truncate '%s': %s\n", full_fn, strerror(errno));<br>+ }<br>+ }<br>+ } else {<br>+ res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>+ if (res == SQL_NULL_DATA && !strcasecmp(coltitle, "msg_id")) {<br>+ char msg_id[MSG_ID_LEN];<br>+ generate_msg_id(msg_id);<br>+ snprintf(rowdata, sizeof(rowdata), "%s", msg_id);<br>+ odbc_update_msg_id(dir, msgnum, msg_id);<br>+ } else if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Get Data error! coltitle=%s\n[%s]\n\n", coltitle, sql);<br>+ goto bail_with_handle;<br>+ }<br>+ if (strcasecmp(coltitle, "msgnum") && strcasecmp(coltitle, "dir")) {<br>+ fprintf(f, "%s=%s\n", coltitle, rowdata);<br>+ }<br>+ }<br>+ }<br>+<br>+bail_with_handle:<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+<br>+bail:<br> if (f)<br> fclose(f);<br> if (fd > -1)<br> close(fd);<br>+<br>+ ast_odbc_release_obj(obj);<br>+<br> return x - 1;<br> }<br> <br> /*!<br> * \brief Determines the highest message number in use for a given user and mailbox folder.<br>- * \param vmu <br>+ * \param vmu<br> * \param dir the folder the mailbox folder to look for messages. Used to construct the SQL where clause.<br> *<br> * This method is used when mailboxes are stored in an ODBC back end.<br>@@ -4012,58 +4007,61 @@<br> */<br> static int last_message_index(struct ast_vm_user *vmu, char *dir)<br> {<br>- int x = 0;<br>+ int x = -1;<br> int res;<br> SQLHSTMT stmt;<br> char sql[PATH_MAX];<br> char rowdata[20];<br> char *argv[] = { dir };<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };<br>-<br> struct odbc_obj *obj;<br>+<br> obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- snprintf(sql, sizeof(sql), "SELECT msgnum FROM %s WHERE dir=? order by msgnum desc", odbc_table);<br>-<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- if (res == SQL_NO_DATA) {<br>- ast_log(AST_LOG_DEBUG, "Directory '%s' has no messages and therefore no index was retrieved.\n", dir);<br>- } else {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- }<br>-<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- if (sscanf(rowdata, "%30d", &x) != 1)<br>- ast_log(AST_LOG_WARNING, "Failed to read message index!\n");<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- return x;<br>- } else<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>-yuck:<br>- return x - 1;<br>+ return -1;<br>+ }<br>+<br>+ snprintf(sql, sizeof(sql), "SELECT msgnum FROM %s WHERE dir=? order by msgnum desc", odbc_table);<br>+<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt) {<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ goto bail;<br>+ }<br>+<br>+ res = SQLFetch(stmt);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ if (res == SQL_NO_DATA) {<br>+ ast_log(AST_LOG_DEBUG, "Directory '%s' has no messages and therefore no index was retrieved.\n", dir);<br>+ } else {<br>+ ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>+ }<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ if (sscanf(rowdata, "%30d", &x) != 1) {<br>+ ast_log(AST_LOG_WARNING, "Failed to read message index!\n");<br>+ }<br>+<br>+bail_with_handle:<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+<br>+bail:<br>+ ast_odbc_release_obj(obj);<br>+<br>+ return x;<br> }<br> <br> /*!<br> * \brief Determines if the specified message exists.<br>- * \param dir the folder the mailbox folder to look for messages. <br>+ * \param dir the folder the mailbox folder to look for messages.<br> * \param msgnum the message index to query for.<br> *<br> * This method is used when mailboxes are stored in an ODBC back end.<br>@@ -4080,39 +4078,43 @@<br> char msgnums[20];<br> char *argv[] = { dir, msgnums };<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };<br>-<br> struct odbc_obj *obj;<br>+<br> obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- snprintf(msgnums, sizeof(msgnums), "%d", msgnum);<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?", odbc_table);<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- if (sscanf(rowdata, "%30d", &x) != 1)<br>- ast_log(AST_LOG_WARNING, "Failed to read message count!\n");<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- } else<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>-yuck:<br>+ return 0;<br>+ }<br>+<br>+ snprintf(msgnums, sizeof(msgnums), "%d", msgnum);<br>+ snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?", odbc_table);<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt) {<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ goto bail;<br>+ }<br>+<br>+ res = SQLFetch(stmt);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ if (sscanf(rowdata, "%30d", &x) != 1) {<br>+ ast_log(AST_LOG_WARNING, "Failed to read message count!\n");<br>+ }<br>+<br>+bail_with_handle:<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+<br>+bail:<br>+ ast_odbc_release_obj(obj);<br> return x;<br> }<br> <br>@@ -4127,48 +4129,50 @@<br> */<br> static int count_messages(struct ast_vm_user *vmu, char *dir)<br> {<br>- int x = 0;<br>+ int x = -1;<br> int res;<br> SQLHSTMT stmt;<br> char sql[PATH_MAX];<br> char rowdata[20];<br> char *argv[] = { dir };<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };<br>-<br> struct odbc_obj *obj;<br>- obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?", odbc_table);<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- goto yuck;<br>- }<br>- if (sscanf(rowdata, "%30d", &x) != 1)<br>- ast_log(AST_LOG_WARNING, "Failed to read message count!\n");<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- return x;<br>- } else<br>- ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>-yuck:<br>- return x - 1;<br> <br>+ obj = ast_odbc_request_obj(odbc_database, 0);<br>+ if (!obj) {<br>+ ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>+ return -1;<br>+ }<br>+<br>+ snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?", odbc_table);<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt) {<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ goto bail;<br>+ }<br>+<br>+ res = SQLFetch(stmt);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+<br>+ if (sscanf(rowdata, "%30d", &x) != 1) {<br>+ ast_log(AST_LOG_WARNING, "Failed to read message count!\n");<br>+ }<br>+<br>+bail_with_handle:<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+<br>+bail:<br>+ ast_odbc_release_obj(obj);<br>+ return x;<br> }<br> <br> /*!<br>@@ -4178,7 +4182,7 @@<br> *<br> * This method is used when mailboxes are stored in an ODBC back end.<br> * The specified message is directly deleted from the database 'voicemessages' table.<br>- * <br>+ *<br> * \return the value greater than zero on success to indicate the number of messages, less than zero on error.<br> */<br> static void delete_file(const char *sdir, int smsg)<br>@@ -4190,21 +4194,25 @@<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };<br> struct odbc_obj *obj;<br> <br>+ obj = ast_odbc_request_obj(odbc_database, 0);<br>+ if (!obj) {<br>+ ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>+ return;<br>+ }<br>+<br> argv[0] = ast_strdupa(sdir);<br> <br>- obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- snprintf(msgnums, sizeof(msgnums), "%d", smsg);<br>- snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?", odbc_table);<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt)<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- else<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- } else<br>- ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>- return; <br>+ snprintf(msgnums, sizeof(msgnums), "%d", smsg);<br>+ snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?", odbc_table);<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt) {<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ } else {<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+ }<br>+ ast_odbc_release_obj(obj);<br>+<br>+ return;<br> }<br> <br> /*!<br>@@ -4232,19 +4240,22 @@<br> generate_msg_id(msg_id);<br> delete_file(ddir, dmsg);<br> obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- snprintf(msgnums, sizeof(msgnums), "%d", smsg);<br>- snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);<br>- snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, msg_id, context, macrocontext, callerid, origtime, duration, recording, flag, mailboxuser, mailboxcontext) SELECT ?,?,?,context,macrocontext,callerid,origtime,duration,recording,flag,?,? FROM %s WHERE dir=? AND msgnum=?", odbc_table, odbc_table);<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt)<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);<br>- else<br>- SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- } else<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>- return; <br>+ return;<br>+ }<br>+<br>+ snprintf(msgnums, sizeof(msgnums), "%d", smsg);<br>+ snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);<br>+ snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, msg_id, context, macrocontext, callerid, origtime, duration, recording, flag, mailboxuser, mailboxcontext) SELECT ?,?,?,context,macrocontext,callerid,origtime,duration,recording,flag,?,? FROM %s WHERE dir=? AND msgnum=?", odbc_table, odbc_table);<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt)<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);<br>+ else<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+ ast_odbc_release_obj(obj);<br>+<br>+ return;<br> }<br> <br> struct insert_data {<br>@@ -4273,9 +4284,8 @@<br> SQLHSTMT stmt;<br> <br> res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>+ if (!SQL_SUCCEEDED(res)) {<br> ast_log(AST_LOG_WARNING, "SQL Alloc Handle failed!\n");<br>- SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br> return NULL;<br> }<br> <br>@@ -4295,7 +4305,7 @@<br> SQLBindParameter(stmt, 13, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->category), 0, (void *) data->category, 0, NULL);<br> }<br> res = SQLExecDirect(stmt, (unsigned char *) data->sql, SQL_NTS);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>+ if (!SQL_SUCCEEDED(res)) {<br> ast_log(AST_LOG_WARNING, "SQL Direct Execute failed!\n");<br> SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br> return NULL;<br>@@ -4312,7 +4322,7 @@<br> * \param msgnum the message index for the message to be stored.<br> *<br> * This method is used when mailboxes are stored in an ODBC back end.<br>- * The message sound file and information file is looked up on the file system. <br>+ * The message sound file and information file is looked up on the file system.<br> * A SQL query is invoked to store the message into the (MySQL) database.<br> *<br> * \return the zero on success -1 on error.<br>@@ -4337,7 +4347,9 @@<br> struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };<br> <br> delete_file(dir, msgnum);<br>- if (!(obj = ast_odbc_request_obj(odbc_database, 0))) {<br>+<br>+ obj = ast_odbc_request_obj(odbc_database, 0);<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br> return -1;<br> }<br>@@ -4400,25 +4412,25 @@<br> ast_log(AST_LOG_WARNING, "Memory map failed for sound file '%s'!\n", full_fn);<br> res = -1;<br> break;<br>- } <br>+ }<br> idata.data = fdm;<br> idata.datalen = idata.indlen = fdlen;<br> <br>- if (!ast_strlen_zero(idata.category)) <br>- snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id,category) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", odbc_table); <br>+ if (!ast_strlen_zero(idata.category))<br>+ snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id,category) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", odbc_table);<br> else<br> snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,msg_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", odbc_table);<br> <br> if ((stmt = ast_odbc_direct_execute(obj, insert_data_cb, &idata))) {<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br> } else {<br> ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br> res = -1;<br> }<br> } while (0);<br>- if (obj) {<br>- ast_odbc_release_obj(obj);<br>- }<br>+<br>+ ast_odbc_release_obj(obj);<br>+<br> if (valid_config(cfg))<br> ast_config_destroy(cfg);<br> if (fdm != MAP_FAILED)<br>@@ -4452,20 +4464,23 @@<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv };<br> <br> delete_file(ddir, dmsg);<br>+<br> obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- snprintf(msgnums, sizeof(msgnums), "%d", smsg);<br>- snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);<br>- snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?", odbc_table);<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt)<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- else<br>- SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>- ast_odbc_release_obj(obj);<br>- } else<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>- return; <br>+ return;<br>+ }<br>+<br>+ snprintf(msgnums, sizeof(msgnums), "%d", smsg);<br>+ snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);<br>+ snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?", odbc_table);<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt)<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ else<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+ ast_odbc_release_obj(obj);<br>+ return;<br> }<br> <br> /*!<br>@@ -5665,17 +5680,48 @@<br> }<br> <br> #ifdef ODBC_STORAGE<br>-static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)<br>+<br>+static int count_messages_in_folder(struct odbc_obj *odbc, const char *context, const char *mailbox, const char *folder, int *messages)<br> {<br>- int x = -1;<br> int res;<br>- SQLHSTMT stmt = NULL;<br> char sql[PATH_MAX];<br> char rowdata[20];<br>- char tmp[PATH_MAX] = "";<br>- struct odbc_obj *obj = NULL;<br>- char *context;<br>+ SQLHSTMT stmt = NULL;<br> struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };<br>+<br>+ if (!messages) {<br>+ return 0;<br>+ }<br>+<br>+ snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder);<br>+ if (!(stmt = ast_odbc_prepare_and_execute(odbc, generic_prepare, &gps))) {<br>+ ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ return 1;<br>+ }<br>+ res = SQLFetch(stmt);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+ return 1;<br>+ }<br>+ res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+ return 1;<br>+ }<br>+<br>+ *messages = atoi(rowdata);<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+<br>+ return 0;<br>+}<br>+<br>+static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)<br>+{<br>+ char tmp[PATH_MAX] = "";<br>+ struct odbc_obj *obj;<br>+ char *context;<br> <br> if (newmsgs)<br> *newmsgs = 0;<br>@@ -5717,87 +5763,28 @@<br> } else<br> context = "default";<br> <br>- if ((obj = ast_odbc_request_obj(odbc_database, 0))) {<br>- do {<br>- if (newmsgs) {<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "INBOX");<br>- if (!(stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps))) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- *newmsgs = atoi(rowdata);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- }<br>-<br>- if (oldmsgs) {<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "Old");<br>- if (!(stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps))) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>- *oldmsgs = atoi(rowdata);<br>- }<br>-<br>- if (urgentmsgs) {<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "Urgent");<br>- if (!(stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps))) {<br>- ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- break;<br>- }<br>- *urgentmsgs = atoi(rowdata);<br>- }<br>-<br>- x = 0;<br>- } while (0);<br>- } else {<br>+ obj = ast_odbc_request_obj(odbc_database, 0);<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>+ return -1;<br> }<br> <br>- if (stmt) {<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>+ if (count_messages_in_folder(obj, context, tmp, "INBOX", newmsgs)<br>+ || count_messages_in_folder(obj, context, tmp, "Old", oldmsgs)<br>+ || count_messages_in_folder(obj, context, tmp, "Urgent", urgentmsgs)) {<br>+ ast_log(AST_LOG_WARNING, "Failed to obtain message count for mailbox %s@%s\n",<br>+ tmp, context);<br> }<br>- if (obj) {<br>- ast_odbc_release_obj(obj);<br>- }<br>- return x;<br>+<br>+ ast_odbc_release_obj(obj);<br>+ return 0;<br> }<br> <br> /*!<br> * \brief Gets the number of messages that exist in a mailbox folder.<br> * \param mailbox_id<br> * \param folder<br>- * <br>+ *<br> * This method is used when ODBC backend is used.<br> * \return The number of messages in this mailbox folder (zero or more).<br> */<br>@@ -5824,37 +5811,39 @@<br> }<br> <br> obj = ast_odbc_request_obj(odbc_database, 0);<br>- if (obj) {<br>- if (!strcmp(folder, "INBOX")) {<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/INBOX' OR dir = '%s%s/%s/Urgent'", odbc_table, VM_SPOOL_DIR, context, mailbox, VM_SPOOL_DIR, context, mailbox);<br>- } else {<br>- snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder);<br>- }<br>- stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>- if (!stmt) {<br>- ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>- goto yuck;<br>- }<br>- res = SQLFetch(stmt);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- goto yuck;<br>- }<br>- res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>- if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {<br>- ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- goto yuck;<br>- }<br>- nummsgs = atoi(rowdata);<br>- SQLFreeHandle (SQL_HANDLE_STMT, stmt);<br>- } else<br>+ if (!obj) {<br> ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);<br>+ return 0;<br>+ }<br> <br>-yuck:<br>- if (obj)<br>- ast_odbc_release_obj(obj);<br>+ if (!strcmp(folder, "INBOX")) {<br>+ snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/INBOX' OR dir = '%s%s/%s/Urgent'", odbc_table, VM_SPOOL_DIR, context, mailbox, VM_SPOOL_DIR, context, mailbox);<br>+ } else {<br>+ snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder);<br>+ }<br>+<br>+ stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);<br>+ if (!stmt) {<br>+ ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);<br>+ goto bail;<br>+ }<br>+ res = SQLFetch(stmt);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+ res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);<br>+ if (!SQL_SUCCEEDED(res)) {<br>+ ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);<br>+ goto bail_with_handle;<br>+ }<br>+ nummsgs = atoi(rowdata);<br>+<br>+bail_with_handle:<br>+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);<br>+<br>+bail:<br>+ ast_odbc_release_obj(obj);<br> return nummsgs;<br> }<br> <br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/5948">change 5948</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/5948"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8e285142eaeb3146b4287a928276b70db76c902b </div>
<div style="display:none"> Gerrit-Change-Number: 5948 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean.bright@gmail.com> </div>