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
This commit is contained in:
Sean Bright 2017-06-29 14:58:35 -04:00
parent b62a3f0a67
commit 950b39a4f5

View file

@ -3779,12 +3779,12 @@ static SQLHSTMT generic_prepare(struct odbc_obj *obj, void *data)
SQLHSTMT stmt; SQLHSTMT stmt;
res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &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"); ast_log(AST_LOG_WARNING, "SQL Alloc Handle failed!\n");
return NULL; return NULL;
} }
res = SQLPrepare(stmt, (unsigned char *) gps->sql, SQL_NTS); 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); ast_log(AST_LOG_WARNING, "SQL Prepare failed![%s]\n", gps->sql);
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return NULL; return NULL;
@ -3862,16 +3862,21 @@ static int retrieve_file(char *dir, int msgnum)
char msgnums[80]; char msgnums[80];
char *argv[] = { dir, msgnums }; char *argv[] = { dir, msgnums };
struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv }; struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
struct odbc_obj *obj; struct odbc_obj *obj;
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return -1;
}
ast_copy_string(fmt, vmfmts, sizeof(fmt)); ast_copy_string(fmt, vmfmts, sizeof(fmt));
c = strchr(fmt, '|'); c = strchr(fmt, '|');
if (c) if (c)
*c = '\0'; *c = '\0';
if (!strcasecmp(fmt, "wav49")) if (!strcasecmp(fmt, "wav49"))
strcpy(fmt, "WAV"); strcpy(fmt, "WAV");
snprintf(msgnums, sizeof(msgnums), "%d", msgnum); snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
if (msgnum > -1) if (msgnum > -1)
make_file(fn, sizeof(fn), dir, msgnum); make_file(fn, sizeof(fn), dir, msgnum);
@ -3883,43 +3888,38 @@ static int retrieve_file(char *dir, int msgnum)
if (!(f = fopen(full_fn, "w+"))) { if (!(f = fopen(full_fn, "w+"))) {
ast_log(AST_LOG_WARNING, "Failed to open/create '%s'\n", full_fn); ast_log(AST_LOG_WARNING, "Failed to open/create '%s'\n", full_fn);
goto yuck; goto bail;
} }
snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt); snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);
snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?", odbc_table); snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?", odbc_table);
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps); stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt) { if (!stmt) {
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
ast_odbc_release_obj(obj); goto bail;
goto yuck;
} }
res = SQLFetch(stmt); res = SQLFetch(stmt);
if (res == SQL_NO_DATA) { if (!SQL_SUCCEEDED(res)) {
SQLFreeHandle (SQL_HANDLE_STMT, stmt); if (res != SQL_NO_DATA) {
ast_odbc_release_obj(obj);
goto yuck;
} else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); 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;
} }
goto bail_with_handle;
}
fd = open(full_fn, O_RDWR | O_CREAT | O_TRUNC, VOICEMAIL_FILE_MODE); fd = open(full_fn, O_RDWR | O_CREAT | O_TRUNC, VOICEMAIL_FILE_MODE);
if (fd < 0) { if (fd < 0) {
ast_log(AST_LOG_WARNING, "Failed to write '%s': %s\n", full_fn, strerror(errno)); ast_log(AST_LOG_WARNING, "Failed to write '%s': %s\n", full_fn, strerror(errno));
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
res = SQLNumResultCols(stmt, &colcount); res = SQLNumResultCols(stmt, &colcount);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Column Count error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
if (f)
fprintf(f, "[message]\n"); fprintf(f, "[message]\n");
for (x = 0; x < colcount; x++) { for (x = 0; x < colcount; x++) {
rowdata[0] = '\0'; rowdata[0] = '\0';
@ -3927,11 +3927,9 @@ static int retrieve_file(char *dir, int msgnum)
collen = sizeof(coltitle); collen = sizeof(coltitle);
res = SQLDescribeCol(stmt, x + 1, (unsigned char *) coltitle, sizeof(coltitle), &collen, res = SQLDescribeCol(stmt, x + 1, (unsigned char *) coltitle, sizeof(coltitle), &collen,
&datatype, &colsize, &decimaldigits, &nullable); &datatype, &colsize, &decimaldigits, &nullable);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Describe Column error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
if (!strcasecmp(coltitle, "recording")) { if (!strcasecmp(coltitle, "recording")) {
off_t offset; off_t offset;
@ -3949,19 +3947,14 @@ static int retrieve_file(char *dir, int msgnum)
for (offset = 0; offset < colsize2; offset += CHUNKSIZE) { for (offset = 0; offset < colsize2; offset += CHUNKSIZE) {
if ((fdm = mmap(NULL, CHUNKSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) { 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); ast_log(AST_LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
SQLFreeHandle(SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj); }
goto yuck;
} else {
res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE, NULL); res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE, NULL);
munmap(fdm, CHUNKSIZE); munmap(fdm, CHUNKSIZE);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
unlink(full_fn); unlink(full_fn);
SQLFreeHandle(SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
}
} }
} }
if (truncate(full_fn, fdlen) < 0) { if (truncate(full_fn, fdlen) < 0) {
@ -3970,30 +3963,32 @@ static int retrieve_file(char *dir, int msgnum)
} }
} else { } else {
res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
if ((res == SQL_NULL_DATA) && (!strcasecmp(coltitle, "msg_id"))) { if (res == SQL_NULL_DATA && !strcasecmp(coltitle, "msg_id")) {
char msg_id[MSG_ID_LEN]; char msg_id[MSG_ID_LEN];
generate_msg_id(msg_id); generate_msg_id(msg_id);
snprintf(rowdata, sizeof(rowdata), "%s", msg_id); snprintf(rowdata, sizeof(rowdata), "%s", msg_id);
odbc_update_msg_id(dir, msgnum, msg_id); odbc_update_msg_id(dir, msgnum, msg_id);
} else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { } else if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Get Data error! coltitle=%s\n[%s]\n\n", coltitle, sql); ast_log(AST_LOG_WARNING, "SQL Get Data error! coltitle=%s\n[%s]\n\n", coltitle, sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
if (strcasecmp(coltitle, "msgnum") && strcasecmp(coltitle, "dir") && f) if (strcasecmp(coltitle, "msgnum") && strcasecmp(coltitle, "dir")) {
fprintf(f, "%s=%s\n", coltitle, rowdata); fprintf(f, "%s=%s\n", coltitle, rowdata);
} }
} }
}
bail_with_handle:
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj);
} else bail:
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
yuck:
if (f) if (f)
fclose(f); fclose(f);
if (fd > -1) if (fd > -1)
close(fd); close(fd);
ast_odbc_release_obj(obj);
return x - 1; return x - 1;
} }
@ -4010,53 +4005,56 @@ yuck:
*/ */
static int last_message_index(struct ast_vm_user *vmu, char *dir) static int last_message_index(struct ast_vm_user *vmu, char *dir)
{ {
int x = 0; int x = -1;
int res; int res;
SQLHSTMT stmt; SQLHSTMT stmt;
char sql[PATH_MAX]; char sql[PATH_MAX];
char rowdata[20]; char rowdata[20];
char *argv[] = { dir }; char *argv[] = { dir };
struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv }; struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };
struct odbc_obj *obj; struct odbc_obj *obj;
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return -1;
}
snprintf(sql, sizeof(sql), "SELECT msgnum FROM %s WHERE dir=? order by msgnum desc", odbc_table); 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); stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt) { if (!stmt) {
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
ast_odbc_release_obj(obj); goto bail;
goto yuck;
} }
res = SQLFetch(stmt); res = SQLFetch(stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
if (res == SQL_NO_DATA) { if (res == SQL_NO_DATA) {
ast_log(AST_LOG_DEBUG, "Directory '%s' has no messages and therefore no index was retrieved.\n", dir); ast_log(AST_LOG_DEBUG, "Directory '%s' has no messages and therefore no index was retrieved.\n", dir);
} else { } else {
ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); 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); res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
if (sscanf(rowdata, "%30d", &x) != 1)
if (sscanf(rowdata, "%30d", &x) != 1) {
ast_log(AST_LOG_WARNING, "Failed to read message index!\n"); ast_log(AST_LOG_WARNING, "Failed to read message index!\n");
}
bail_with_handle:
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
bail:
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
return x; return x;
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
yuck:
return x - 1;
} }
/*! /*!
@ -4078,39 +4076,43 @@ static int message_exists(char *dir, int msgnum)
char msgnums[20]; char msgnums[20];
char *argv[] = { dir, msgnums }; char *argv[] = { dir, msgnums };
struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv }; struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
struct odbc_obj *obj; struct odbc_obj *obj;
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return 0;
}
snprintf(msgnums, sizeof(msgnums), "%d", msgnum); snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?", odbc_table); snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?", odbc_table);
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps); stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt) { if (!stmt) {
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
ast_odbc_release_obj(obj); goto bail;
goto yuck;
} }
res = SQLFetch(stmt); res = SQLFetch(stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
if (sscanf(rowdata, "%30d", &x) != 1)
if (sscanf(rowdata, "%30d", &x) != 1) {
ast_log(AST_LOG_WARNING, "Failed to read message count!\n"); ast_log(AST_LOG_WARNING, "Failed to read message count!\n");
}
bail_with_handle:
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
bail:
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
yuck:
return x; return x;
} }
@ -4125,48 +4127,50 @@ yuck:
*/ */
static int count_messages(struct ast_vm_user *vmu, char *dir) static int count_messages(struct ast_vm_user *vmu, char *dir)
{ {
int x = 0; int x = -1;
int res; int res;
SQLHSTMT stmt; SQLHSTMT stmt;
char sql[PATH_MAX]; char sql[PATH_MAX];
char rowdata[20]; char rowdata[20];
char *argv[] = { dir }; char *argv[] = { dir };
struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv }; struct generic_prepare_struct gps = { .sql = sql, .argc = 1, .argv = argv };
struct odbc_obj *obj; struct odbc_obj *obj;
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return -1;
}
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?", odbc_table); snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?", odbc_table);
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps); stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt) { if (!stmt) {
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
ast_odbc_release_obj(obj); goto bail;
goto yuck;
} }
res = SQLFetch(stmt); res = SQLFetch(stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
ast_odbc_release_obj(obj);
goto yuck;
} }
if (sscanf(rowdata, "%30d", &x) != 1)
if (sscanf(rowdata, "%30d", &x) != 1) {
ast_log(AST_LOG_WARNING, "Failed to read message count!\n"); ast_log(AST_LOG_WARNING, "Failed to read message count!\n");
}
bail_with_handle:
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
bail:
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
return x; return x;
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
yuck:
return x - 1;
} }
/*! /*!
@ -4188,20 +4192,24 @@ static void delete_file(const char *sdir, int smsg)
struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv }; struct generic_prepare_struct gps = { .sql = sql, .argc = 2, .argv = argv };
struct odbc_obj *obj; struct odbc_obj *obj;
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;
}
argv[0] = ast_strdupa(sdir); argv[0] = ast_strdupa(sdir);
obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) {
snprintf(msgnums, sizeof(msgnums), "%d", smsg); snprintf(msgnums, sizeof(msgnums), "%d", smsg);
snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?", odbc_table); snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?", odbc_table);
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps); stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt) if (!stmt) {
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
else } else {
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return; return;
} }
@ -4230,7 +4238,11 @@ static void copy_file(char *sdir, int smsg, char *ddir, int dmsg, char *dmailbox
generate_msg_id(msg_id); generate_msg_id(msg_id);
delete_file(ddir, dmsg); delete_file(ddir, dmsg);
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return;
}
snprintf(msgnums, sizeof(msgnums), "%d", smsg); snprintf(msgnums, sizeof(msgnums), "%d", smsg);
snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg); 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); 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);
@ -4240,8 +4252,7 @@ static void copy_file(char *sdir, int smsg, char *ddir, int dmsg, char *dmailbox
else else
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return; return;
} }
@ -4271,9 +4282,8 @@ static SQLHSTMT insert_data_cb(struct odbc_obj *obj, void *vdata)
SQLHSTMT stmt; SQLHSTMT stmt;
res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &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"); ast_log(AST_LOG_WARNING, "SQL Alloc Handle failed!\n");
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return NULL; return NULL;
} }
@ -4293,7 +4303,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); 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); 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"); ast_log(AST_LOG_WARNING, "SQL Direct Execute failed!\n");
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return NULL; return NULL;
@ -4335,7 +4345,9 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
delete_file(dir, msgnum); 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); ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return -1; return -1;
} }
@ -4414,9 +4426,9 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
res = -1; res = -1;
} }
} while (0); } while (0);
if (obj) {
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
}
if (valid_config(cfg)) if (valid_config(cfg))
ast_config_destroy(cfg); ast_config_destroy(cfg);
if (fdm != MAP_FAILED) if (fdm != MAP_FAILED)
@ -4450,8 +4462,13 @@ static void rename_file(char *sdir, int smsg, char *mailboxuser, char *mailboxco
struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv }; struct generic_prepare_struct gps = { .sql = sql, .argc = 6, .argv = argv };
delete_file(ddir, dmsg); delete_file(ddir, dmsg);
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return;
}
snprintf(msgnums, sizeof(msgnums), "%d", smsg); snprintf(msgnums, sizeof(msgnums), "%d", smsg);
snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg); snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);
snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?", odbc_table); snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?", odbc_table);
@ -4461,8 +4478,6 @@ static void rename_file(char *sdir, int smsg, char *mailboxuser, char *mailboxco
else else
SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt);
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return; return;
} }
@ -5663,18 +5678,49 @@ static void free_zone(struct vm_zone *z)
} }
#ifdef ODBC_STORAGE #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; int res;
SQLHSTMT stmt = NULL;
char sql[PATH_MAX]; char sql[PATH_MAX];
char rowdata[20]; char rowdata[20];
char tmp[PATH_MAX] = ""; SQLHSTMT stmt = NULL;
struct odbc_obj *obj = NULL;
char *context;
struct generic_prepare_struct gps = { .sql = sql, .argc = 0 }; 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;
char *context;
if (newmsgs) if (newmsgs)
*newmsgs = 0; *newmsgs = 0;
if (oldmsgs) if (oldmsgs)
@ -5715,80 +5761,21 @@ static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *
} else } else
context = "default"; context = "default";
if ((obj = ast_odbc_request_obj(odbc_database, 0))) { obj = ast_odbc_request_obj(odbc_database, 0);
do { if (!obj) {
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 {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database); ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return -1;
} }
if (stmt) { if (count_messages_in_folder(obj, context, tmp, "INBOX", newmsgs)
SQLFreeHandle (SQL_HANDLE_STMT, stmt); || 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); ast_odbc_release_obj(obj);
} return 0;
return x;
} }
/*! /*!
@ -5822,36 +5809,38 @@ static int messagecount(const char *mailbox_id, const char *folder)
} }
obj = ast_odbc_request_obj(odbc_database, 0); obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) { if (!obj) {
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
return 0;
}
if (!strcmp(folder, "INBOX")) { 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); 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 { } else {
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder); 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); stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
if (!stmt) { if (!stmt) {
ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
goto yuck; goto bail;
} }
res = SQLFetch(stmt); res = SQLFetch(stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
goto yuck;
} }
res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { if (!SQL_SUCCEEDED(res)) {
ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); goto bail_with_handle;
goto yuck;
} }
nummsgs = atoi(rowdata); nummsgs = atoi(rowdata);
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
} else
ast_log(AST_LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
yuck: bail_with_handle:
if (obj) SQLFreeHandle(SQL_HANDLE_STMT, stmt);
bail:
ast_odbc_release_obj(obj); ast_odbc_release_obj(obj);
return nummsgs; return nummsgs;
} }