<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>