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