@ -2109,6 +2109,36 @@ static const char *mbox(int id)
} ;
return ( id > = 0 & & id < ( sizeof ( msgs ) / sizeof ( msgs [ 0 ] ) ) ) ? msgs [ id ] : " Unknown " ;
}
# ifdef IMAP_STORAGE
static int folder_int ( const char * folder )
{
/*assume a NULL folder means INBOX*/
if ( ! folder )
return 0 ;
if ( ! strcasecmp ( folder , " INBOX " ) )
return 0 ;
else if ( ! strcasecmp ( folder , " Old " ) )
return 1 ;
else if ( ! strcasecmp ( folder , " Work " ) )
return 2 ;
else if ( ! strcasecmp ( folder , " Family " ) )
return 3 ;
else if ( ! strcasecmp ( folder , " Friends " ) )
return 4 ;
else if ( ! strcasecmp ( folder , " Cust1 " ) )
return 5 ;
else if ( ! strcasecmp ( folder , " Cust2 " ) )
return 6 ;
else if ( ! strcasecmp ( folder , " Cust3 " ) )
return 7 ;
else if ( ! strcasecmp ( folder , " Cust4 " ) )
return 8 ;
else if ( ! strcasecmp ( folder , " Cust5 " ) )
return 9 ;
else /*assume they meant INBOX if folder is not found otherwise*/
return 0 ;
}
# endif
# ifdef ODBC_STORAGE
/*! XXX \todo Fix this function to support multiple mailboxes in the intput string */
@ -2328,63 +2358,24 @@ static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, i
}
static int inboxcount( const char * mailbox , int * newmsgs , int * oldmsgs )
static int messagecount( const char * context , const char * mailbox , const char * folder )
{
SEARCHPGM * pgm ;
SEARCHHEADER * hdr ;
struct ast_vm_user * vmu ;
struct vm_state * vms_p ;
char tmp [ PATH_MAX ] = " " ;
char * mb , * cur ;
char * mailboxnc ;
char * context ;
int ret = 0 ;
if ( newmsgs )
* newmsgs = 0 ;
if ( oldmsgs )
* oldmsgs = 0 ;
if ( option_debug > 2 )
ast_log ( LOG_DEBUG , " Mailbox is set to %s \n " , mailbox ) ;
/* If no mailbox, return immediately */
int fold = folder_int ( folder ) ;
if ( ast_strlen_zero ( mailbox ) )
return 0 ;
if ( strchr ( mailbox , ' , ' ) ) {
int tmpnew , tmpold ;
ast_copy_string ( tmp , mailbox , sizeof ( tmp ) ) ;
mb = tmp ;
ret = 0 ;
while ( ( cur = strsep ( & mb , " , " ) ) ) {
if ( ! ast_strlen_zero ( cur ) ) {
if ( inboxcount ( cur , newmsgs ? & tmpnew : NULL , oldmsgs ? & tmpold : NULL ) )
return - 1 ;
else {
if ( newmsgs )
* newmsgs + = tmpnew ;
if ( oldmsgs )
* oldmsgs + = tmpold ;
}
}
}
return 0 ;
}
ast_copy_string ( tmp , mailbox , sizeof ( tmp ) ) ;
context = strchr ( tmp , ' @ ' ) ;
if ( context ) {
* context = ' \0 ' ;
mailboxnc = tmp ;
context + + ;
} else {
context = " default " ;
mailboxnc = ( char * ) mailbox ;
}
/* We have to get the user before we can open the stream! */
/* ast_log (LOG_DEBUG,"Before find_user, context is %s and mailbox is %s\n",context,mailbox); */
vmu = find_user ( NULL , context , mailbox nc ) ;
vmu = find_user ( NULL , context , mailbox ) ;
if ( ! vmu ) {
ast_log ( LOG_ERROR , " Couldn't find mailbox %s in context %s \n " , mailbox nc , context ) ;
ast_log ( LOG_ERROR , " Couldn't find mailbox %s in context %s \n " , mailbox , context ) ;
return - 1 ;
} else {
/* No IMAP account available */
@ -2398,21 +2389,25 @@ static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
/* check if someone is accessing this box right now... */
vms_p = get_vm_state_by_imapuser ( vmu - > imapuser , 1 ) ;
if ( ! vms_p ) {
vms_p = get_vm_state_by_mailbox ( mailbox nc , 1 ) ;
vms_p = get_vm_state_by_mailbox ( mailbox , 1 ) ;
}
if ( vms_p ) {
if ( option_debug > 2 )
ast_log ( LOG_DEBUG , " Returning before search - user is logged in \n " ) ;
* newmsgs = vms_p - > newmessages ;
* oldmsgs = vms_p - > oldmessages ;
free_user ( vmu ) ;
return 0 ;
if ( fold = = 0 ) { /*INBOX*/
free_user ( vmu ) ;
return vms_p - > newmessages ;
}
if ( fold = = 1 ) { /*Old messages*/
free_user ( vmu ) ;
return vms_p - > oldmessages ;
}
}
/* add one if not there... */
vms_p = get_vm_state_by_imapuser ( vmu - > imapuser , 0 ) ;
if ( ! vms_p ) {
vms_p = get_vm_state_by_mailbox ( mailbox nc , 0 ) ;
vms_p = get_vm_state_by_mailbox ( mailbox , 0 ) ;
}
if ( ! vms_p ) {
@ -2423,91 +2418,157 @@ static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
return - 1 ;
}
ast_copy_string ( vms_p - > imapuser , vmu - > imapuser , sizeof ( vms_p - > imapuser ) ) ;
ast_copy_string ( vms_p - > username , mailbox nc , sizeof ( vms_p - > username ) ) ; /* save for access from interactive entry point */
ast_copy_string ( vms_p - > username , mailbox , sizeof ( vms_p - > username ) ) ; /* save for access from interactive entry point */
vms_p - > mailstream = NIL ; /* save for access from interactive entry point */
if ( option_debug > 2 )
ast_log ( LOG_DEBUG , " Copied %s to %s \n " , vmu - > imapuser , vms_p - > imapuser ) ;
vms_p - > updated = 1 ;
/* set mailbox to INBOX! */
ast_copy_string ( vms_p - > curbox , mbox ( 0 ) , sizeof ( vms_p - > curbox ) ) ;
ast_copy_string ( vms_p - > curbox , mbox ( fold ) , sizeof ( vms_p - > curbox ) ) ;
init_vm_state ( vms_p ) ;
vmstate_insert ( vms_p ) ;
}
ret = init_mailstream ( vms_p , 0 ) ;
ret = init_mailstream ( vms_p , fold ) ;
if ( ! vms_p - > mailstream ) {
ast_log ( LOG_ERROR , " IMAP mailstream is NULL \n " ) ;
free_user ( vmu ) ;
return - 1 ;
}
if ( newmsgs & & ret= = 0 & & vms_p - > updated > 0 ) {
if ( ret = = 0 ) {
pgm = mail_newsearchpgm ( ) ;
hdr = mail_newsearchheader ( " X-Asterisk-VM-Extension " , ( char * ) mailbox nc ) ;
hdr = mail_newsearchheader ( " X-Asterisk-VM-Extension " , ( char * ) mailbox ) ;
pgm - > header = hdr ;
pgm - > unseen = 1 ;
pgm - > seen = 0 ;
if ( fold ! = 1 ) {
pgm - > unseen = 1 ;
pgm - > seen = 0 ;
}
/* In the special case where fold is 1 (old messages) we have to do things a bit
* differently . Old messages are stored in the INBOX but are marked as " seen "
*/
else {
pgm - > unseen = 0 ;
pgm - > seen = 1 ;
}
pgm - > undeleted = 1 ;
pgm - > deleted = 0 ;
vms_p - > vmArrayIndex = 0 ;
mail_search_full ( vms_p - > mailstream , NULL , pgm , NIL ) ;
* newmsgs = vms_p - > vmArrayIndex ;
vms_p - > newmessages = vms_p - > vmArrayIndex ;
if ( fold = = 0 )
vms_p - > newmessages = vms_p - > vmArrayIndex ;
if ( fold = = 1 )
vms_p - > oldmessages = vms_p - > vmArrayIndex ;
/*Freeing the searchpgm also frees the searchhdr*/
mail_free_searchpgm ( & pgm ) ;
free_user ( vmu ) ;
vms_p - > updated = 0 ;
return vms_p - > vmArrayIndex ;
} else {
mail_ping ( vms_p - > mailstream ) ;
}
if ( oldmsgs & & ret = = 0 & & vms_p - > updated > 0 ) {
pgm = mail_newsearchpgm ( ) ;
hdr = mail_newsearchheader ( " X-Asterisk-VM-Extension " , ( char * ) mailboxnc ) ;
pgm - > header = hdr ;
pgm - > unseen = 0 ;
pgm - > seen = 1 ;
pgm - > deleted = 0 ;
pgm - > undeleted = 1 ;
free_user ( vmu ) ;
return 0 ;
}
static int inboxcount ( const char * mailbox_context , int * newmsgs , int * oldmsgs )
{
char tmp [ PATH_MAX ] = " " ;
char * mailboxnc ;
char * context ;
char * mb ;
char * cur ;
if ( newmsgs )
* newmsgs = 0 ;
if ( oldmsgs )
* oldmsgs = 0 ;
vms_p - > vmArrayIndex = 0 ;
ast_log ( LOG_DEBUG , " inboxcount called \n " ) ;
if ( option_debug > 2 )
ast_log ( LOG_DEBUG , " Mailbox is set to %s \n " , mailbox_context ) ;
/* If no mailbox, return immediately */
if ( ast_strlen_zero ( mailbox_context ) )
return 0 ;
mail_search_full ( vms_p - > mailstream , NULL , pgm , NIL ) ;
* oldmsgs = vms_p - > vmArrayIndex ;
vms_p - > oldmessages = vms_p - > vmArrayIndex ;
mail_free_searchpgm ( & pgm ) ;
ast_copy_string ( tmp , mailbox_context , sizeof ( tmp ) ) ;
context = strchr ( tmp , ' @ ' ) ;
if ( strchr ( mailbox_context , ' , ' ) ) {
int tmpnew , tmpold ;
ast_copy_string ( tmp , mailbox_context , sizeof ( tmp ) ) ;
mb = tmp ;
while ( ( cur = strsep ( & mb , " , " ) ) ) {
if ( ! ast_strlen_zero ( cur ) ) {
if ( inboxcount ( cur , newmsgs ? & tmpnew : NULL , oldmsgs ? & tmpold : NULL ) )
return - 1 ;
else {
if ( newmsgs )
* newmsgs + = tmpnew ;
if ( oldmsgs )
* oldmsgs + = tmpold ;
}
}
}
return 0 ;
}
if ( vms_p - > updated > 1 ) { /* changes, so we did the searches above */
vms_p - > updated = 0 ;
} else { /* no changes, so don't search */
mail_ping ( vms_p - > mailstream ) ;
/* Keep the old data */
* newmsgs = vms_p - > newmessages ;
* oldmsgs = vms_p - > oldmessages ;
if ( context) {
* context = ' \0 ' ;
mailboxnc = tmp ;
context + + ;
} else {
context = " default " ;
mailboxnc = ( char * ) mailbox_context ;
}
free_user ( vmu ) ;
if ( newmsgs )
if ( ( * newmsgs = messagecount ( context , mailboxnc , " INBOX " ) ) < 0 )
{
ast_log ( LOG_DEBUG , " messagecount failed somehow... \n " ) ;
return - 1 ;
}
if ( oldmsgs )
if ( ( * oldmsgs = messagecount ( context , mailboxnc , " Old " ) ) < 0 )
{
ast_log ( LOG_DEBUG , " messagecount failed somehow... \n " ) ;
return - 1 ;
}
return 0 ;
}
/*! XXX \todo Fix this function to support multiple mailboxes separated
* by commas */
static int has_voicemail ( const char * mailbox , const char * folder )
{
int newmsgs , oldmsgs ;
if ( inboxcount ( mailbox , & newmsgs , & oldmsgs ) )
return 0 ;
char tmp [ 256 ] , * tmp2 , * mbox , * context ;
ast_copy_string ( tmp , mailbox , sizeof ( tmp ) ) ;
tmp2 = tmp ;
while ( strcmp ( ( mbox = strsep ( & tmp2 , " , " ) ) , mailbox ) ) {
if ( has_voicemail ( mbox , folder ) )
return 1 ;
}
if ( ( context = strchr ( tmp , ' @ ' ) ) )
* context + + = ' \0 ' ;
else
return folder ? oldmsgs : newmsgs ;
context = " default " ;
return messagecount ( context , tmp , folder ) ? 1 : 0 ;
}
static int messagecount ( const char * context , const char * mailbox , const char * folder )
static int copy_message( struct ast_channel * chan , struct ast_vm_user * vmu , int imbox , int msgnum , long duration , struct ast_vm_user * recip , char * fmt , char * di r)
{
int newmsgs , oldmsgs ;
char tmp [ 256 ] = " " ;
if ( ast_strlen_zero ( mailbox ) )
return 0 ;
sprintf ( tmp , " %s@%s " , mailbox , ast_strlen_zero ( context ) ? " default " : context ) ;
if ( inboxcount ( tmp , & newmsgs , & oldmsgs ) )
char dest [ 256 ] ;
struct vm_state * sendvms = NULL , * destvms = NULL ;
char messagestring [ 10 ] ; /*I guess this could be a problem if someone has more than 999999999 messages...*/
if ( ! ( sendvms = get_vm_state_by_imapuser ( vmu - > imapuser , 2 ) ) )
{
ast_log ( LOG_ERROR , " Couldn't get vm_state for originator's mailbox!! \n " ) ;
return - 1 ;
}
if ( ! ( destvms = get_vm_state_by_imapuser ( recip - > imapuser , 2 ) ) )
{
ast_log ( LOG_ERROR , " Couldn't get vm_state for destination mailbox! \n " ) ;
return - 1 ;
}
imap_mailbox_name ( dest , destvms , imbox , 1 ) ;
snprintf ( messagestring , sizeof ( messagestring ) , " %ld " , sendvms - > msgArray [ msgnum ] ) ;
if ( ( mail_copy ( sendvms - > mailstream , messagestring , dest ) = = T ) )
return 0 ;
else
return folder ? oldmsgs : newmsgs ;
ast_log ( LOG_WARNING , " Unable to copy message from mailbox %s to mailbox %s \n " , vmu - > mailbox , recip - > mailbox ) ;
return - 1 ;
}
# endif
@ -3034,7 +3095,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
rename ( tmptxtfile , txtfile ) ;
ast_unlock_path ( dir ) ;
# ifndef IMAP_STORAGE
/* We must store the file first, before copying the message, because
* ODBC storage does the entire copy with SQL .
*/
@ -3058,7 +3118,6 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_
free_user ( recip ) ;
}
}
# endif
/* Notification and disposal needs to happen after the copy, though. */
if ( ast_fileexists ( fn , NULL , NULL ) ) {
notify_new_message ( chan , vmu , msgnum , duration , fmt , S_OR ( chan - > cid . cid_num , NULL ) , S_OR ( chan - > cid . cid_name , NULL ) ) ;
@ -8211,7 +8270,6 @@ void mm_searched(MAILSTREAM *stream, unsigned long number)
char * user ;
mailbox = stream - > mailbox ;
user = get_user_by_mailbox ( mailbox ) ;
vms = get_vm_state_by_imapuser ( user , 2 ) ;
if ( vms ) {
if ( option_debug > 2 )