From 0f51f6577db59b1fc7b7e1e6f9ab885ce4b25dd5 Mon Sep 17 00:00:00 2001 From: Olle Johansson <oej@edvina.net> Date: Thu, 15 Feb 2007 20:29:37 +0000 Subject: [PATCH] - add some notes, asking for help - insert a few ast_strlen_zero - Doxygen additions - A few more spaces git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@54686 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_voicemail.c | 371 +++++++++++++++++++++++-------------------- 1 file changed, 199 insertions(+), 172 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 3b8a8c34bc..7e8fe52948 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -24,8 +24,16 @@ * * \par See also * \arg \ref Config_vm + * \note For information about voicemail IMAP storage, read doc/imapstorage.txt * \ingroup applications - * \note This module requires res_adsi to load. + * \note This module requires res_adsi to load. This needs to be optional + * during compilation. + * + * + * + * \note This file is now almost impossible to work with, due to all #ifdefs. + * Feels like the database code before realtime. Someone - please come up + * with a plan to clean this up. */ /*** MODULEINFO @@ -64,6 +72,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include <sys/mman.h> #include <time.h> #include <dirent.h> + #ifdef IMAP_STORAGE #include <ctype.h> #include <signal.h> @@ -72,6 +81,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "imap4r1.h" #include "linkage.h" #endif + #include "asterisk/lock.h" #include "asterisk/file.h" #include "asterisk/logger.h" @@ -90,6 +100,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/utils.h" #include "asterisk/stringfields.h" #include "asterisk/smdi.h" + #ifdef ODBC_STORAGE #include "asterisk/res_odbc.h" #endif @@ -109,10 +120,10 @@ static char delimiter = '\0'; struct vm_state; struct ast_vm_user; -static int init_mailstream (struct vm_state *vms, int box); -static void write_file (char *filename, char *buffer, unsigned long len); -/*static void status (MAILSTREAM *stream); */ /* No need for this. */ -static void display_body (BODY *body, char *pfx, long i); +/* Forward declarations for IMAP */ +static int init_mailstream(struct vm_state *vms, int box); +static void write_file char *filename, char *buffer, unsigned long len); +static void display_body(BODY *body, char *pfx, long i); static char *get_header_by_tag(char *header, char *tag, char *buf, size_t len); static void vm_imap_delete(int msgnum, struct vm_state *vms); static char *get_user_by_mailbox(char *mailbox, char *buf, size_t len); @@ -130,12 +141,16 @@ static void get_mailbox_delimiter(MAILSTREAM *stream); static void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota); static void imap_mailbox_name(char *spec, struct vm_state *vms, int box, int target); static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms); -static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box); + + + struct vmstate { struct vm_state *vms; AST_LIST_ENTRY(vmstate) list; }; + static AST_LIST_HEAD_STATIC(vmstates, vmstate); + #endif #define SMDI_MWI_WAIT_TIMEOUT 1000 /* 1 second */ @@ -316,13 +331,14 @@ struct ast_vm_user { int maxmsg; /*!< Maximum number of msgs per folder for this mailbox */ int maxsecs; /*!< Maximum number of seconds per message for this mailbox */ #ifdef IMAP_STORAGE - char imapuser[80]; /* IMAP server login */ - char imappassword[80]; /* IMAP server password if authpassword not defined */ + char imapuser[80]; /*!< IMAP server login */ + char imappassword[80]; /*!< IMAP server password if authpassword not defined */ #endif - double volgain; /*!< Volume gain for voicemails sent via email */ + double volgain; /*!< Volume gain for voicemails sent via email */ AST_LIST_ENTRY(ast_vm_user) list; }; +/*! Voicemail time zones */ struct vm_zone { AST_LIST_ENTRY(vm_zone) list; char name[80]; @@ -330,6 +346,7 @@ struct vm_zone { char msg_format[512]; }; +/*! Voicemail mailbox state */ struct vm_state { char curbox[80]; char username[80]; @@ -346,30 +363,18 @@ struct vm_state { int starting; int repeats; #ifdef IMAP_STORAGE - int updated; /* decremented on each mail check until 1 -allows delay */ + int updated; /*!< decremented on each mail check until 1 -allows delay */ long msgArray[256]; MAILSTREAM *mailstream; int vmArrayIndex; - char imapuser[80]; /* IMAP server login */ + char imapuser[80]; /*!< IMAP server login */ int interactive; unsigned int quota_limit; unsigned int quota_usage; struct vm_state *persist_vms; #endif }; -static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain); -static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context); -static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, - char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, - signed char record_gain, struct vm_state *vms); -static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain); -static int vm_play_folder_name(struct ast_channel *chan, char *mbox); -static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname); -static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap); -#if !(defined(ODBC_STORAGE) || defined(IMAP_STORAGE)) -static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit); -#endif -static void apply_options(struct ast_vm_user *vmu, const char *options); + #ifdef ODBC_STORAGE static char odbc_database[80]; @@ -422,77 +427,74 @@ static char userscontext[AST_MAX_EXTENSION] = "default"; static char *addesc = "Comedian Mail"; -static char *synopsis_vm = -"Leave a Voicemail message"; +static char *synopsis_vm = "Leave a Voicemail message"; static char *descrip_vm = -" VoiceMail(mailbox[@context][&mailbox[@context]][...][|options]): This\n" -"application allows the calling party to leave a message for the specified\n" -"list of mailboxes. When multiple mailboxes are specified, the greeting will\n" -"be taken from the first mailbox specified. Dialplan execution will stop if the\n" -"specified mailbox does not exist.\n" -" The Voicemail application will exit if any of the following DTMF digits are\n" -"received:\n" -" 0 - Jump to the 'o' extension in the current dialplan context.\n" -" * - Jump to the 'a' extension in the current dialplan context.\n" -" This application will set the following channel variable upon completion:\n" -" VMSTATUS - This indicates the status of the execution of the VoiceMail\n" -" application. The possible values are:\n" -" SUCCESS | USEREXIT | FAILED\n\n" -" Options:\n" -" b - Play the 'busy' greeting to the calling party.\n" -" g(#) - Use the specified amount of gain when recording the voicemail\n" -" message. The units are whole-number decibels (dB).\n" -" s - Skip the playback of instructions for leaving a message to the\n" -" calling party.\n" -" u - Play the 'unavailble greeting.\n" -" j - Jump to priority n+101 if the mailbox is not found or some other\n" -" error occurs.\n"; - -static char *synopsis_vmain = -"Check Voicemail messages"; + " VoiceMail(mailbox[@context][&mailbox[@context]][...][|options]): This\n" + "application allows the calling party to leave a message for the specified\n" + "list of mailboxes. When multiple mailboxes are specified, the greeting will\n" + "be taken from the first mailbox specified. Dialplan execution will stop if the\n" + "specified mailbox does not exist.\n" + " The Voicemail application will exit if any of the following DTMF digits are\n" + "received:\n" + " 0 - Jump to the 'o' extension in the current dialplan context.\n" + " * - Jump to the 'a' extension in the current dialplan context.\n" + " This application will set the following channel variable upon completion:\n" + " VMSTATUS - This indicates the status of the execution of the VoiceMail\n" + " application. The possible values are:\n" + " SUCCESS | USEREXIT | FAILED\n\n" + " Options:\n" + " b - Play the 'busy' greeting to the calling party.\n" + " g(#) - Use the specified amount of gain when recording the voicemail\n" + " message. The units are whole-number decibels (dB).\n" + " s - Skip the playback of instructions for leaving a message to the\n" + " calling party.\n" + " u - Play the 'unavailble greeting.\n" + " j - Jump to priority n+101 if the mailbox is not found or some other\n" + " error occurs.\n"; + +static char *synopsis_vmain = "Check Voicemail messages"; static char *descrip_vmain = -" VoiceMailMain([mailbox][@context][|options]): This application allows the\n" -"calling party to check voicemail messages. A specific mailbox, and optional\n" -"corresponding context, may be specified. If a mailbox is not provided, the\n" -"calling party will be prompted to enter one. If a context is not specified,\n" -"the 'default' context will be used.\n\n" -" Options:\n" -" p - Consider the mailbox parameter as a prefix to the mailbox that\n" -" is entered by the caller.\n" -" g(#) - Use the specified amount of gain when recording a voicemail\n" -" message. The units are whole-number decibels (dB).\n" -" s - Skip checking the passcode for the mailbox.\n" -" a(#) - Skip folder prompt and go directly to folder specified.\n" -" Defaults to INBOX\n"; + " VoiceMailMain([mailbox][@context][|options]): This application allows the\n" + "calling party to check voicemail messages. A specific mailbox, and optional\n" + "corresponding context, may be specified. If a mailbox is not provided, the\n" + "calling party will be prompted to enter one. If a context is not specified,\n" + "the 'default' context will be used.\n\n" + " Options:\n" + " p - Consider the mailbox parameter as a prefix to the mailbox that\n" + " is entered by the caller.\n" + " g(#) - Use the specified amount of gain when recording a voicemail\n" + " message. The units are whole-number decibels (dB).\n" + " s - Skip checking the passcode for the mailbox.\n" + " a(#) - Skip folder prompt and go directly to folder specified.\n" + " Defaults to INBOX\n"; static char *synopsis_vm_box_exists = "Check to see if Voicemail mailbox exists"; static char *descrip_vm_box_exists = -" MailboxExists(mailbox[@context][|options]): Check to see if the specified\n" -"mailbox exists. If no voicemail context is specified, the 'default' context\n" -"will be used.\n" -" This application will set the following channel variable upon completion:\n" -" VMBOXEXISTSSTATUS - This will contain the status of the execution of the\n" -" MailboxExists application. Possible values include:\n" -" SUCCESS | FAILED\n\n" -" Options:\n" -" j - Jump to priority n+101 if the mailbox is found.\n"; - -static char *synopsis_vmauthenticate = -"Authenticate with Voicemail passwords"; + " MailboxExists(mailbox[@context][|options]): Check to see if the specified\n" + "mailbox exists. If no voicemail context is specified, the 'default' context\n" + "will be used.\n" + " This application will set the following channel variable upon completion:\n" + " VMBOXEXISTSSTATUS - This will contain the status of the execution of the\n" + " MailboxExists application. Possible values include:\n" + " SUCCESS | FAILED\n\n" + " Options:\n" + " j - Jump to priority n+101 if the mailbox is found.\n"; + +static char *synopsis_vmauthenticate = "Authenticate with Voicemail passwords"; static char *descrip_vmauthenticate = -" VMAuthenticate([mailbox][@context][|options]): This application behaves the\n" -"same way as the Authenticate application, but the passwords are taken from\n" -"voicemail.conf.\n" -" If the mailbox is specified, only that mailbox's password will be considered\n" -"valid. If the mailbox is not specified, the channel variable AUTH_MAILBOX will\n" -"be set with the authenticated mailbox.\n\n" -" Options:\n" -" s - Skip playing the initial prompts.\n"; + " VMAuthenticate([mailbox][@context][|options]): This application behaves the\n" + "same way as the Authenticate application, but the passwords are taken from\n" + "voicemail.conf.\n" + " If the mailbox is specified, only that mailbox's password will be considered\n" + "valid. If the mailbox is not specified, the channel variable AUTH_MAILBOX will\n" + "be set with the authenticated mailbox.\n\n" + " Options:\n" + " s - Skip playing the initial prompts.\n"; /* Leave a message */ static char *app = "VoiceMail"; @@ -552,6 +554,24 @@ static unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC"; static int adsiver = 1; static char emaildateformat[32] = "%A, %B %d, %Y at %r"; +/* Forward declarations - generic */ +static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu,int box); +static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain); +static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context); +static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, + char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, + signed char record_gain, struct vm_state *vms); +static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain); +static int vm_play_folder_name(struct ast_channel *chan, char *mbox); +static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname); +static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap); +static void apply_options(struct ast_vm_user *vmu, const char *options); + +#if !(defined(ODBC_STORAGE) || defined(IMAP_STORAGE)) +static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit); +#endif + + static void populate_defaults(struct ast_vm_user *vmu) { @@ -798,8 +818,7 @@ static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword) if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) { while ((category = ast_category_browse(cfg, category))) { if (!strcasecmp(category, vmu->context)) { - tmp = ast_variable_retrieve(cfg, category, vmu->mailbox); - if (!tmp) { + if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { ast_log(LOG_WARNING, "We could not find the mailbox.\n"); break; } @@ -944,7 +963,8 @@ static int create_dirpath(char *dest, int len, const char *context, const char * return 1; } -/* only return failure if ast_lock_path returns 'timeout', +/*! \brief Lock file path + only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason */ static int vm_lock_path(const char *path) @@ -1615,7 +1635,8 @@ static void copy_file(char *frompath, char *topath) copy(frompath2, topath2); } #endif -/* + +/*! \brief * A negative return value indicates an error. * \note Should always be called with a lock already set on dir. */ @@ -1696,14 +1717,14 @@ static int inchar(struct baseio *bio, FILE *fi) static int ochar(struct baseio *bio, int c, FILE *so) { - if (bio->linelength>=BASELINELEN) { - if (fputs(eol,so)==EOF) + if (bio->linelength >= BASELINELEN) { + if (fputs(eol,so) == EOF) return -1; bio->linelength= 0; } - if (putc(((unsigned char)c),so)==EOF) + if (putc(((unsigned char)c),so) == EOF) return -1; bio->linelength++; @@ -1726,24 +1747,24 @@ static int base_encode(char *filename, FILE *so) return -1; } - for (i= 0;i<9;i++) { + for (i= 0; i<9; i++) { dtable[i]= 'A'+i; dtable[i+9]= 'J'+i; dtable[26+i]= 'a'+i; dtable[26+i+9]= 'j'+i; } - for (i= 0;i<8;i++) { + for (i= 0; i<8; i++) { dtable[i+18]= 'S'+i; dtable[26+i+18]= 's'+i; } - for (i= 0;i<10;i++) { + for (i= 0; i<10; i++) { dtable[52+i]= '0'+i; } dtable[62]= '+'; dtable[63]= '/'; while (!hiteof){ - unsigned char igroup[3],ogroup[4]; + unsigned char igroup[3], ogroup[4]; int c,n; igroup[0]= igroup[1]= igroup[2]= 0; @@ -1759,8 +1780,8 @@ static int base_encode(char *filename, FILE *so) if (n> 0) { ogroup[0]= dtable[igroup[0]>>2]; - ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)]; - ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)]; + ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; + ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; ogroup[3]= dtable[igroup[2]&0x3F]; if (n<3) { @@ -1775,7 +1796,7 @@ static int base_encode(char *filename, FILE *so) } } - if (fputs(eol,so)==EOF) + if (fputs(eol,so) == EOF) return 0; fclose(fi); @@ -1816,7 +1837,8 @@ static char *quote(const char *from, char *to, size_t len) *ptr = '\0'; return to; } -/* + +/*! \brief * fill in *tm for current time according to the proper timezone, if any. * Return tm so it can be used as a function argument. */ @@ -1839,7 +1861,7 @@ static const struct tm *vmu_tm(const struct ast_vm_user *vmu, struct tm *tm) return tm; } -/* same as mkstemp, but return a FILE * */ +/*! \brief same as mkstemp, but return a FILE * */ static FILE *vm_mkftemp(char *template) { FILE *p = NULL; @@ -1870,9 +1892,8 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in gethostname(host, sizeof(host)-1); if (strchr(srcemail, '@')) ast_copy_string(who, srcemail, sizeof(who)); - else { + else snprintf(who, sizeof(who), "%s@%s", srcemail, host); - } snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); fprintf(p, "Date: %s\r\n", date); @@ -1880,7 +1901,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in /* Set date format for voicemail mail */ strftime(date, sizeof(date), emaildateformat, &tm); - if (*fromstring) { + if (!ast_strlen_zero(fromstring)) { struct ast_channel *ast; if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { char *passdata; @@ -1902,11 +1923,11 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in len_passdata = strlen(vmu->fullname) * 2 + 3; passdata2 = alloca(len_passdata); fprintf(p, "To: %s <%s>\r\n", quote(vmu->fullname, passdata2, len_passdata), vmu->email); - if (emailsubject) { + if (!ast_strlen_zero(emailsubject)) { struct ast_channel *ast; if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { char *passdata; - int vmlen = strlen(emailsubject)*3 + 200; + int vmlen = strlen(emailsubject) * 3 + 200; if ((passdata = alloca(vmlen))) { memset(passdata, 0, vmlen); prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); @@ -1917,7 +1938,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in ast_channel_free(ast); } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); - } else if (*emailtitle) { + } else if (!ast_strlen_zero(emailtitle)) { fprintf(p, emailtitle, msgnum + 1, mailbox) ; fprintf(p,"\r\n") ; } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) @@ -2019,6 +2040,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in unlink(newtmp); } } + static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category) { FILE *p=NULL; @@ -2063,73 +2085,77 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char if ((p = vm_mkftemp(tmp)) == NULL) { ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); return -1; - } else { - gethostname(host, sizeof(host)-1); - if (strchr(srcemail, '@')) - ast_copy_string(who, srcemail, sizeof(who)); - else { - snprintf(who, sizeof(who), "%s@%s", srcemail, host); - } - snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); - strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); - fprintf(p, "Date: %s\n", date); - - if (*pagerfromstring) { - struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { - char *passdata; - int vmlen = strlen(fromstring)*3 + 200; - if ((passdata = alloca(vmlen))) { - memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); - pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen); - fprintf(p, "From: %s <%s>\n", passdata, who); - } else - ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); - ast_channel_free(ast); - } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); - } else - fprintf(p, "From: Asterisk PBX <%s>\n", who); - fprintf(p, "To: %s\n", pager); - if (pagersubject) { - struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { - char *passdata; - int vmlen = strlen(pagersubject) * 3 + 200; - if ((passdata = alloca(vmlen))) { - memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); - pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen); - fprintf(p, "Subject: %s\n\n", passdata); - } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); - ast_channel_free(ast); - } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); + } + gethostname(host, sizeof(host)-1); + if (strchr(srcemail, '@')) + ast_copy_string(who, srcemail, sizeof(who)); + else + snprintf(who, sizeof(who), "%s@%s", srcemail, host); + snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); + strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); + fprintf(p, "Date: %s\n", date); + + if (*pagerfromstring) { + struct ast_channel *ast; + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + char *passdata; + int vmlen = strlen(fromstring)*3 + 200; + if ((passdata = alloca(vmlen))) { + memset(passdata, 0, vmlen); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen); + fprintf(p, "From: %s <%s>\n", passdata, who); + } else + ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); + ast_channel_free(ast); + } else + ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); + } else + fprintf(p, "From: Asterisk PBX <%s>\n", who); + fprintf(p, "To: %s\n", pager); + if (pagersubject) { + struct ast_channel *ast; + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + char *passdata; + int vmlen = strlen(pagersubject) * 3 + 200; + if ((passdata = alloca(vmlen))) { + memset(passdata, 0, vmlen); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen); + fprintf(p, "Subject: %s\n\n", passdata); + } else + ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); + ast_channel_free(ast); } else - fprintf(p, "Subject: New VM\n\n"); - strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); - if (pagerbody) { - struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { - char *passdata; - int vmlen = strlen(pagerbody)*3 + 200; - if ((passdata = alloca(vmlen))) { - memset(passdata, 0, vmlen); - prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); - pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen); - fprintf(p, "%s\n", passdata); - } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); + ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); + } else + fprintf(p, "Subject: New VM\n\n"); + + strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); + if (pagerbody) { + struct ast_channel *ast; + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + char *passdata; + int vmlen = strlen(pagerbody)*3 + 200; + if ((passdata = alloca(vmlen))) { + memset(passdata, 0, vmlen); + prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category); + pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen); + fprintf(p, "%s\n", passdata); + } else + ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); ast_channel_free(ast); - } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); - } else { - fprintf(p, "New %s long msg in box %s\n" - "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); - } - fclose(p); - snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); - ast_safe_system(tmp2); - if (option_debug) - ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd); + } else + ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); + } else { + fprintf(p, "New %s long msg in box %s\n" + "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); } + fclose(p); + snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); + ast_safe_system(tmp2); + if (option_debug) + ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd); return 0; } @@ -2469,6 +2495,7 @@ static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs) if (newmsgs) *newmsgs = 0; + if (oldmsgs) *oldmsgs = 0; @@ -4332,9 +4359,9 @@ static int play_message_callerid(struct ast_channel *chan, struct vm_state *vms, } } - else if (!res){ + else if (!res) { if (option_debug) - ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid); + ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n", callerid); /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */ if (!callback) res = wait_file2(chan, vms, "vm-from-phonenumber"); -- GitLab