mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-06 21:09:47 +00:00
Bug 7167 - Fix VMCOUNT if using USE_ODBC_STORAGE (different fix for trunk than for 1.2)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@28300 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
6
app.c
6
app.c
@@ -146,18 +146,22 @@ int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxle
|
|||||||
|
|
||||||
static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL;
|
static int (*ast_has_voicemail_func)(const char *mailbox, const char *folder) = NULL;
|
||||||
static int (*ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL;
|
static int (*ast_messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs) = NULL;
|
||||||
|
static int (*ast_messagecount2_func)(const char *context, const char *mailbox, const char *folder) = NULL;
|
||||||
|
|
||||||
void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
|
void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
|
||||||
int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs))
|
int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs),
|
||||||
|
int (*messagecount2_func)(const char *context, const char *mailbox, const char *folder))
|
||||||
{
|
{
|
||||||
ast_has_voicemail_func = has_voicemail_func;
|
ast_has_voicemail_func = has_voicemail_func;
|
||||||
ast_messagecount_func = messagecount_func;
|
ast_messagecount_func = messagecount_func;
|
||||||
|
ast_messagecount2_func = messagecount2_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_uninstall_vm_functions(void)
|
void ast_uninstall_vm_functions(void)
|
||||||
{
|
{
|
||||||
ast_has_voicemail_func = NULL;
|
ast_has_voicemail_func = NULL;
|
||||||
ast_messagecount_func = NULL;
|
ast_messagecount_func = NULL;
|
||||||
|
ast_messagecount2_func = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_app_has_voicemail(const char *mailbox, const char *folder)
|
int ast_app_has_voicemail(const char *mailbox, const char *folder)
|
||||||
|
@@ -79,26 +79,6 @@ static char *hasnewvoicemail_descrip =
|
|||||||
|
|
||||||
LOCAL_USER_DECL;
|
LOCAL_USER_DECL;
|
||||||
|
|
||||||
static int hasvoicemail_internal(char *context, char *box, char *folder)
|
|
||||||
{
|
|
||||||
char vmpath[256];
|
|
||||||
DIR *vmdir;
|
|
||||||
struct dirent *vment;
|
|
||||||
int count=0;
|
|
||||||
|
|
||||||
snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, box, folder);
|
|
||||||
if ((vmdir = opendir(vmpath))) {
|
|
||||||
/* No matter what the format of VM, there will always be a .txt file for each message. */
|
|
||||||
while ((vment = readdir(vmdir))) {
|
|
||||||
if (!strncmp(vment->d_name + 7, ".txt", 4)) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(vmdir);
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hasvoicemail_exec(struct ast_channel *chan, void *data)
|
static int hasvoicemail_exec(struct ast_channel *chan, void *data)
|
||||||
{
|
{
|
||||||
struct localuser *u;
|
struct localuser *u;
|
||||||
@@ -130,11 +110,10 @@ static int hasvoicemail_exec(struct ast_channel *chan, void *data)
|
|||||||
|
|
||||||
AST_STANDARD_APP_ARGS(args, input);
|
AST_STANDARD_APP_ARGS(args, input);
|
||||||
|
|
||||||
if ((vmbox = strsep(&args.vmbox, "@")))
|
vmbox = strsep(&args.vmbox, "@");
|
||||||
|
|
||||||
if (!ast_strlen_zero(args.vmbox))
|
if (!ast_strlen_zero(args.vmbox))
|
||||||
context = args.vmbox;
|
context = args.vmbox;
|
||||||
if (!vmbox)
|
|
||||||
vmbox = args.vmbox;
|
|
||||||
|
|
||||||
vmfolder = strchr(vmbox, '/');
|
vmfolder = strchr(vmbox, '/');
|
||||||
if (vmfolder) {
|
if (vmfolder) {
|
||||||
@@ -149,7 +128,7 @@ static int hasvoicemail_exec(struct ast_channel *chan, void *data)
|
|||||||
priority_jump = 1;
|
priority_jump = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmcount = hasvoicemail_internal(context, vmbox, vmfolder);
|
vmcount = ast_app_messagecount2(context, vmbox, vmfolder);
|
||||||
/* Set the count in the channel variable */
|
/* Set the count in the channel variable */
|
||||||
if (varname) {
|
if (varname) {
|
||||||
snprintf(tmp, sizeof(tmp), "%d", vmcount);
|
snprintf(tmp, sizeof(tmp), "%d", vmcount);
|
||||||
@@ -198,7 +177,7 @@ static int acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *argsstr,
|
|||||||
args.folder = "INBOX";
|
args.folder = "INBOX";
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buf, len, "%d", hasvoicemail_internal(context, args.vmbox, args.folder));
|
snprintf(buf, len, "%d", ast_app_messagecount2(context, args.vmbox, args.folder));
|
||||||
|
|
||||||
LOCAL_USER_REMOVE(u);
|
LOCAL_USER_REMOVE(u);
|
||||||
|
|
||||||
|
@@ -2127,76 +2127,73 @@ yuck:
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int has_voicemail(const char *mailbox, const char *folder)
|
static int messagecount2(const char *context, const char *mailbox, const char *folder)
|
||||||
{
|
{
|
||||||
struct odbc_obj *obj;
|
struct odbc_obj *obj = NULL;
|
||||||
int nummsgs = 0;
|
int nummsgs = 0;
|
||||||
int res;
|
int res;
|
||||||
SQLHSTMT stmt;
|
SQLHSTMT stmt = NULL;
|
||||||
char sql[256];
|
char sql[256];
|
||||||
char rowdata[20];
|
char rowdata[20];
|
||||||
char tmp[256]="";
|
|
||||||
char *context;
|
|
||||||
if (!folder)
|
if (!folder)
|
||||||
folder = "INBOX";
|
folder = "INBOX";
|
||||||
/* If no mailbox, return immediately */
|
/* If no mailbox, return immediately */
|
||||||
if (ast_strlen_zero(mailbox))
|
if (ast_strlen_zero(mailbox))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ast_copy_string(tmp, mailbox, sizeof(tmp));
|
|
||||||
|
|
||||||
context = strchr(tmp, '@');
|
|
||||||
if (context) {
|
|
||||||
*context = '\0';
|
|
||||||
context++;
|
|
||||||
} else
|
|
||||||
context = "default";
|
|
||||||
|
|
||||||
obj = odbc_request_obj(odbc_database, 0);
|
obj = odbc_request_obj(odbc_database, 0);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
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 ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
||||||
ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
|
ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
|
||||||
odbc_release_obj(obj);
|
|
||||||
goto yuck;
|
goto yuck;
|
||||||
}
|
}
|
||||||
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "INBOX");
|
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, mailbox, folder);
|
||||||
res = SQLPrepare(stmt, sql, SQL_NTS);
|
res = SQLPrepare(stmt, sql, SQL_NTS);
|
||||||
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
||||||
ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
|
ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
|
||||||
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
||||||
odbc_release_obj(obj);
|
|
||||||
goto yuck;
|
goto yuck;
|
||||||
}
|
}
|
||||||
res = odbc_smart_execute(obj, stmt);
|
res = odbc_smart_execute(obj, stmt);
|
||||||
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
||||||
ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
|
ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
|
||||||
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
||||||
odbc_release_obj(obj);
|
|
||||||
goto yuck;
|
goto yuck;
|
||||||
}
|
}
|
||||||
res = SQLFetch(stmt);
|
res = SQLFetch(stmt);
|
||||||
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
||||||
ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
|
ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
|
||||||
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
||||||
odbc_release_obj(obj);
|
|
||||||
goto yuck;
|
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 ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
|
||||||
ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
|
ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
|
||||||
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
||||||
odbc_release_obj(obj);
|
|
||||||
goto yuck;
|
goto yuck;
|
||||||
}
|
}
|
||||||
nummsgs = atoi(rowdata);
|
nummsgs = atoi(rowdata);
|
||||||
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
|
||||||
odbc_release_obj(obj);
|
|
||||||
} else
|
} else
|
||||||
ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
|
ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
|
||||||
|
|
||||||
yuck:
|
yuck:
|
||||||
if (nummsgs>=1)
|
if (obj)
|
||||||
|
odbc_release_obj(obj);
|
||||||
|
return nummsgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int has_voicemail(const char *mailbox, const char *folder)
|
||||||
|
{
|
||||||
|
char *context, tmp[256];
|
||||||
|
ast_copy_string(tmp, mailbox, sizeof(tmp));
|
||||||
|
if ((context = strchr(tmp, '@')))
|
||||||
|
*context++ = '\0';
|
||||||
|
else
|
||||||
|
context = "default";
|
||||||
|
|
||||||
|
if (messagecount2(context, tmp, folder))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2204,7 +2201,7 @@ yuck:
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static int has_voicemail(const char *mailbox, const char *folder)
|
static int __has_voicemail(const char *mailbox, const char *folder, int shortcircuit)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
@@ -2212,7 +2209,7 @@ static int has_voicemail(const char *mailbox, const char *folder)
|
|||||||
char tmp[256]="";
|
char tmp[256]="";
|
||||||
char *mb, *cur;
|
char *mb, *cur;
|
||||||
char *context;
|
char *context;
|
||||||
int ret;
|
int ret = 0;
|
||||||
if (!folder)
|
if (!folder)
|
||||||
folder = "INBOX";
|
folder = "INBOX";
|
||||||
/* If no mailbox, return immediately */
|
/* If no mailbox, return immediately */
|
||||||
@@ -2224,11 +2221,13 @@ static int has_voicemail(const char *mailbox, const char *folder)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
while((cur = strsep(&mb, ","))) {
|
while((cur = strsep(&mb, ","))) {
|
||||||
if (!ast_strlen_zero(cur)) {
|
if (!ast_strlen_zero(cur)) {
|
||||||
if (has_voicemail(cur, folder))
|
if ((ret += __has_voicemail(cur, folder, shortcircuit))) {
|
||||||
|
if (shortcircuit)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
ast_copy_string(tmp, mailbox, sizeof(tmp));
|
ast_copy_string(tmp, mailbox, sizeof(tmp));
|
||||||
context = strchr(tmp, '@');
|
context = strchr(tmp, '@');
|
||||||
@@ -2242,15 +2241,29 @@ static int has_voicemail(const char *mailbox, const char *folder)
|
|||||||
if (!dir)
|
if (!dir)
|
||||||
return 0;
|
return 0;
|
||||||
while ((de = readdir(dir))) {
|
while ((de = readdir(dir))) {
|
||||||
if (!strncasecmp(de->d_name, "msg", 3))
|
if (!strncasecmp(de->d_name, "msg", 3)) {
|
||||||
|
if (shortcircuit) {
|
||||||
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
} else if (!strncasecmp(de->d_name + 8, "txt", 3))
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
if (de)
|
return ret;
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int has_voicemail(const char *mailbox, const char *folder)
|
||||||
|
{
|
||||||
|
return __has_voicemail(mailbox, folder, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int messagecount2(const char *context, const char *mailbox, const char *folder)
|
||||||
|
{
|
||||||
|
char tmp[256];
|
||||||
|
snprintf(tmp, sizeof(tmp), "%s@%s", mailbox, context);
|
||||||
|
return __has_voicemail(tmp, folder, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
|
static int messagecount(const char *mailbox, int *newmsgs, int *oldmsgs)
|
||||||
{
|
{
|
||||||
@@ -6641,7 +6654,7 @@ static int load_module(void *mod)
|
|||||||
/* compute the location of the voicemail spool directory */
|
/* compute the location of the voicemail spool directory */
|
||||||
snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
|
snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
|
||||||
|
|
||||||
ast_install_vm_functions(has_voicemail, messagecount);
|
ast_install_vm_functions(has_voicemail, messagecount, messagecount2);
|
||||||
|
|
||||||
#if defined(USE_ODBC_STORAGE) && !defined(EXTENDED_ODBC_STORAGE)
|
#if defined(USE_ODBC_STORAGE) && !defined(EXTENDED_ODBC_STORAGE)
|
||||||
ast_log(LOG_WARNING, "The current ODBC storage table format will be changed soon."
|
ast_log(LOG_WARNING, "The current ODBC storage table format will be changed soon."
|
||||||
|
@@ -100,7 +100,8 @@ int ast_app_getdata(struct ast_channel *c, char *prompt, char *s, int maxlen, in
|
|||||||
int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd);
|
int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd);
|
||||||
|
|
||||||
void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
|
void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
|
||||||
int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs));
|
int (*messagecount_func)(const char *mailbox, int *newmsgs, int *oldmsgs),
|
||||||
|
int (*messagecount2_func)(const char *context, const char *mailbox, const char *folder));
|
||||||
|
|
||||||
void ast_uninstall_vm_functions(void);
|
void ast_uninstall_vm_functions(void);
|
||||||
|
|
||||||
@@ -110,6 +111,9 @@ int ast_app_has_voicemail(const char *mailbox, const char *folder);
|
|||||||
/*! Determine number of new/old messages in a mailbox */
|
/*! Determine number of new/old messages in a mailbox */
|
||||||
int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs);
|
int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs);
|
||||||
|
|
||||||
|
/*! Determine number of messages in a given mailbox and folder */
|
||||||
|
int ast_app_messagecount2(const char *context, const char *mailbox, const char *folder);
|
||||||
|
|
||||||
/*! Safely spawn an external program while closing file descriptors
|
/*! Safely spawn an external program while closing file descriptors
|
||||||
\note This replaces the \b system call in all Asterisk modules
|
\note This replaces the \b system call in all Asterisk modules
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user