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
1.4
Tilghman Lesher 20 years ago
parent 75e3bafdfd
commit f0b985853a

@ -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))
context = args.vmbox; if (!ast_strlen_zero(args.vmbox))
if (!vmbox) context = args.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, mailbox, folder);
snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir = '%s%s/%s/%s'", odbc_table, VM_SPOOL_DIR, context, tmp, "INBOX"); 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); goto yuck;
odbc_release_obj(obj); }
goto yuck; res = odbc_smart_execute(obj, stmt);
} if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
res = odbc_smart_execute(obj, stmt); ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { SQLFreeHandle (SQL_HANDLE_STMT, stmt);
ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql); goto yuck;
SQLFreeHandle (SQL_HANDLE_STMT, stmt); }
odbc_release_obj(obj); res = SQLFetch(stmt);
goto yuck; if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
} ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql);
res = SQLFetch(stmt); SQLFreeHandle (SQL_HANDLE_STMT, stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { goto yuck;
ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n\n", sql); }
SQLFreeHandle (SQL_HANDLE_STMT, stmt); res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
odbc_release_obj(obj); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
goto yuck; ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
} SQLFreeHandle (SQL_HANDLE_STMT, stmt);
res = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL); goto yuck;
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { }
ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql); nummsgs = atoi(rowdata);
SQLFreeHandle (SQL_HANDLE_STMT, stmt); SQLFreeHandle (SQL_HANDLE_STMT, stmt);
odbc_release_obj(obj); } else
goto yuck; ast_log(LOG_WARNING, "Failed to obtain database object for '%s'!\n", odbc_database);
}
nummsgs = atoi(rowdata);
SQLFreeHandle (SQL_HANDLE_STMT, stmt);
odbc_release_obj(obj);
} else
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))) {
return 1; if (shortcircuit)
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)) {
break; if (shortcircuit) {
ret = 1;
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
*/ */

Loading…
Cancel
Save