[asterisk-commits] oej: branch oej/minivoicemail r57960 - in
/team/oej/minivoicemail: apps/ conf...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Mar 5 14:15:57 MST 2007
Author: oej
Date: Mon Mar 5 15:15:56 2007
New Revision: 57960
URL: http://svn.digium.com/view/asterisk?view=rev&rev=57960
Log:
Numerous updates
- New applications:
minivmNotify
minivmDelete
- New dialplan funcion
MINIVMACCOUNT()
- And bug fixes en masse
Also added accountcode and pin code to account data structure, so one can build
a voicemail system using dialplan scripting...
Modified:
team/oej/minivoicemail/apps/app_minivm.c
team/oej/minivoicemail/configs/minivm.conf.sample
Modified: team/oej/minivoicemail/apps/app_minivm.c
URL: http://svn.digium.com/view/asterisk/team/oej/minivoicemail/apps/app_minivm.c?view=diff&rev=57960&r1=57959&r2=57960
==============================================================================
--- team/oej/minivoicemail/apps/app_minivm.c (original)
+++ team/oej/minivoicemail/apps/app_minivm.c Mon Mar 5 15:15:56 2007
@@ -20,7 +20,7 @@
/*! \file
*
- * \brief MiniVoiceMail - A Minimal Voicemail System
+ * \brief MiniVoiceMail - A Minimal Voicemail System for Asterisk
*
* A voicemail system in small building blocks, working together
* based on the Comedian Mail voicemail system (app_voicemail.c).
@@ -31,32 +31,57 @@
*
* \ingroup applications
*
- * \page App_minivm Markodian Mail - A minimal voicemail system
+ * \page App_minivm Asterisk Mini-voicemail - A minimal voicemail system
*
* This is a minimal voicemail system, building blocks for something
- * else. Currently, there's two applications in here:
- * - minivm_send - record voicemail and send as e-mail
- * - minivm_greet - Play user's greeting or default greeting
+ * else.
*
+ * Dialplan applications
+ * - minivmRecord - record voicemail and send as e-mail ( \ref minivm_record_exec() )
+ * - minivmGreet - Play user's greeting or default greeting ( \ref minivm_greet_exec() )
+ * - minivmNotify - Notify user of message ( \ref minivm_notify_exec() )
+ * - minivmDelete - Delete voicemail message ( \ref minivm_delete_exec() )
+ *
+ * Dialplan functions
+ * - MINIVMACCOUNT() - A dialplan function
+ *
+ * CLI Commands
+ * - minivm list accounts
+ * - minivm list zones
+ * - minivm list templates
+ * - minivm show stats
+ * - minivm show settings
+ *
+ * Some notes
* - General configuration in minivm.conf
* - Users in realtime or configuration file
* - Or configured on the command line with just the e-mail address
*
- * Voicemail accounts are identified
- * by userid and domain
+ * Voicemail accounts are identified by userid and domain
*
* Language codes are like setlocale - langcode_countrycode
- * \note Don't use language codes like the rest of Asterisk, two letter countrycode
+ * \note Don't use language codes like the rest of Asterisk, two letter countrycode. Use
+ * language_country like setlocale().
+ *
+ * Examples:
+ * - Swedish, Sweden sv_se
+ * - Swedish, Finland sv_fi
+ * - English, USA en_us
+ * - English, GB en_gb
*
* \par See also
* \arg \ref Config_minivm
* \arg \ref app_minivm.c
* \arg Comedian mail: app_voicemail.c
+ * \arg \ref descrip_minivm_greet
+ * \arg \ref descrip_minivm_record
+ * \arg \ref descrip_minivm_delete
+ * \arg \ref descrip_minivm_notify
*
+ * \arg \ref App_minivm_todo
*/
-/*! \page App_minivm_todo Markodian Minimail - todo
- * - Do not create directories by default for users, just check if they exist
+/*! \page App_minivm_todo Asterisk Mini-Voicemail - todo
* - Record all voice files in standard temp directory - configurable
* - add documentation -not done
* - Implement log file
@@ -64,8 +89,17 @@
* - test, test, test, test
* - fix "vm-theextensionis.gsm" voiceprompt from Allison in various formats
* "The extension you are calling"
- * - Maybe split recording from actual forwarding in e-mail into two applications
* - For trunk, consider using channel storage for information passing between small applications
+ * - Set default directory for voicemail
+ * - New app for recording busy, unavailable and temporary greeting
+ * - New app for creating directory for account if it does not exist
+ * - Re-insert code for IMAP storage at some point
+ * - Jabber integration for notifications
+ *
+ * For Asterisk 1.4
+ * - Use string fields for minivm_account
+ *
+ * Back: \ref App_minivm
*/
#include <stdlib.h>
@@ -150,16 +184,20 @@
/* Module declarations */
static char *tdesc = "Mini VoiceMail (A minimal Voicemail e-mail System)";
-static char *app = "MiniVM"; /* Leave a message */
-static char *app_greet = "MiniVMgreet"; /* Play voicemail prompts */
-
-static char *synopsis_vm = "Receive Mini-Voicemail and forward via e-mail";
-static char *descrip_vm =
- "Syntax: minivm(username at domain[,options])\n"
+static char *app_minivm_record = "MinivmRecord"; /* Leave a message */
+static char *app_minivm_greet = "MinivmGreet"; /* Play voicemail prompts */
+static char *app_minivm_notify = "MinivmNotify"; /* Notify about voicemail by using one of several methods */
+static char *app_minivm_delete = "MinivmDelete"; /* Notify about voicemail by using one of several methods */
+
+static char *synopsis_minivm_record = "Receive Mini-Voicemail and forward via e-mail";
+static char *descrip_minivm_record =
+ "Syntax: MinivmRecord(username at domain[,options])\n"
"This application is part of the Mini-Voicemail system, configured in minivm.conf.\n"
"MiniVM records audio file in configured format and forwards message to e-mail and pager.\n"
"If there's no user account for that address, a temporary account will\n"
"be used with default options.\n"
+ "The recorded file name and path will be stored in MINIVM_FILENAME and the \n"
+ "duration of the message will be stored in MINIVM_DURATION\n"
"The application will exit if any of the following DTMF digits are \n"
"received and the requested extension exist in the current context.\n"
" 0 - Jump to the 'o' extension in the current dialplan context.\n"
@@ -172,19 +210,49 @@
" message. The units are whole-number decibels (dB).\n"
"\n";
-static char *synopsis_vm_greet = "Play Mini-Voicemail prompts";
-static char *descrip_vm_greet =
- "Syntax: minivm_greet(username at domain[,options])\n"
+static char *synopsis_minivm_greet = "Play Mini-Voicemail prompts";
+static char *descrip_minivm_greet =
+ "Syntax: MinivmGreet(username at domain[,options])\n"
"This application is part of the Mini-Voicemail system, configured in minivm.conf.\n"
- "minivm_greet() plays default prompts or user specific prompts.\n"
+ "MinivmGreet() plays default prompts or user specific prompts for an account.\n"
+ "Busy and unavailable messages can be choosen, but will be overridden if a temporary\n"
+ "message exists for the account.\n"
"\n"
- "Result is given in channel variable MINIVM_STATUS\n"
+ "Result is given in channel variable MINIVMGREETSTATUS\n"
" The possible values are: SUCCESS | USEREXIT | FAILED\n\n"
" Options:\n"
" b - Play the 'busy' greeting to the calling party.\n"
" s - Skip the playback of instructions for leaving a message to the\n"
" calling party.\n"
" u - Play the 'unavailable greeting.\n"
+ "\n";
+
+static char *synopsis_minivm_notify = "Notify voicemail owner about new messages.\n";
+static char *descrip_minivm_notify =
+ "Syntax: MinivmNotify(username at domain[,template])\n"
+ "This application is part of the Mini-Voicemail system, configured in minivm.conf.\n"
+ "MiniVMnotify forwards messages about new voicemail to e-mail and pager.\n"
+ "If there's no user account for that address, a temporary account will\n"
+ "be used with default options (set in minivm.conf).\n"
+ "The recorded file name and path will be read from MVM_FILENAME and the \n"
+ "duration of the message will be accessed from MVM_DURATION (set by MinivmRecord() )\n"
+ "If not template is given, the default email template will be used to send email and\n"
+ "default pager template to send paging message (if the user account is configured with\n"
+ "a paging address.\n"
+ "\n"
+ "Result is given in channel variable MINIVMNOTIFYSTATUS\n"
+ " The possible values are: SUCCESS | FAILED\n"
+ "\n";
+
+static char *synopsis_minivm_delete = "Delete Mini-Voicemail voicemail messages";
+static char *descrip_minivm_delete =
+ "Syntax: MinivmDelete(username at domain [,filename])\n"
+ "This application is part of the Mini-Voicemail system, configured in minivm.conf.\n"
+ "It deletes voicemail file set in MVM_FILENAME or given filename.\n"
+ "\n"
+ "Result is given in channel variable MINIVMDELETESTATUS\n"
+ " The possible values are: SUCCESS | FAILED\n"
+ " FAILED is set if the file does not exist or can't be deleted.\n"
"\n";
enum {
@@ -211,16 +279,18 @@
-/*! \brief Structure for linked list of Mini-Voicemail users */
-struct minivm_user {
+/*! \brief Structure for linked list of Mini-Voicemail users: \ref minivm_accounts */
+struct minivm_account {
char username[AST_MAX_CONTEXT]; /*!< Mailbox username */
char domain[AST_MAX_CONTEXT]; /*!< Voicemail domain */
- char password[80]; /*!< Secret pin code, numbers only */
- char fullname[80]; /*!< Full name, for directory app */
+
+ char pincode[10]; /*!< Secret pin code, numbers only */
+ char fullname[120]; /*!< Full name, for directory app */
char email[80]; /*!< E-mail address - override */
char pager[80]; /*!< E-mail address to pager (no attachment) */
+ char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Voicemail account account code */
char serveremail[80]; /*!< From: Mail address */
- char mailcmd[160]; /*!< Configurable mail command */
+ char externnotify[160]; /*!< Configurable notification command */
char language[MAX_LANGUAGE]; /*!< Config: Language setting */
char zonetag[80]; /*!< Time zone */
char uniqueid[20]; /*!< Unique integer identifier */
@@ -231,13 +301,17 @@
unsigned int flags; /*!< MVM_ flags */
struct ast_variable *chanvars; /*!< Variables for e-mail template */
double volgain; /*!< Volume gain for voicemails sent via e-mail */
- AST_LIST_ENTRY(minivm_user) list;
+ AST_LIST_ENTRY(minivm_account) list;
};
+
+/*! \brief The list of e-mail accounts */
+static AST_LIST_HEAD_STATIC(minivm_accounts, minivm_account);
/*! \brief Linked list of e-mail templates in various languages
These are used as templates for e-mails, pager messages and jabber messages
+ \ref message_templates
*/
-struct minivm_message {
+struct minivm_template {
char name[80]; /*!< Template name */
char *body; /*!< Body of this template */
char fromstring[100]; /*!< Who's sending the e-mail? */
@@ -245,13 +319,13 @@
char charset[32]; /*!< Default character set for this template */
char dateformat[80]; /*!< Date format to use in this attachment */
int attachment; /*!< Attachment of media yes/no - no for pager messages */
- AST_LIST_ENTRY(minivm_message) list; /*!< List mechanics */
+ AST_LIST_ENTRY(minivm_template) list; /*!< List mechanics */
};
-static AST_LIST_HEAD_STATIC(message_templates, minivm_message); /*!< The list of e-mail templates */
-static AST_LIST_HEAD_STATIC(minivm_users, minivm_user); /*!< The list of e-mail templates */
-
-/*! Options for leaving voicemail with the voicemail() application */
+/*! \brief The list of e-mail templates */
+static AST_LIST_HEAD_STATIC(message_templates, minivm_template);
+
+/*! \brief Options for leaving voicemail with the voicemail() application */
struct leave_vm_options {
unsigned int flags;
signed char record_gain;
@@ -268,13 +342,14 @@
/*! \brief Voicemail time zones */
struct minivm_zone {
- char name[80]; /* Name of this time zone */
- char timezone[80];
- char msg_format[512];
+ char name[80]; /*!< Name of this time zone */
+ char timezone[80]; /*!< Timezone definition */
+ char msg_format[BUFSIZ]; /*!< Not used in minivm ...yet */
AST_LIST_ENTRY(minivm_zone) list; /*!< List mechanics */
};
-static AST_LIST_HEAD_STATIC(minivm_zones, minivm_zone); /*!< The list of e-mail templates */
+/*! \brief The list of e-mail time zones */
+static AST_LIST_HEAD_STATIC(minivm_zones, minivm_zone);
/*! \brief Structure for gathering statistics */
struct minivm_stats {
@@ -310,6 +385,7 @@
static double global_volgain; /*!< Volume gain for voicmemail via e-mail */
+/*! \brief Default dateformat, can be overridden in configuration file */
#define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r"
#define DEFAULT_CHARSET "ISO-8859-1"
@@ -320,14 +396,14 @@
static char *message_template_parse_filebody(char *filename);
static char *message_template_parse_emailbody(char *body);
static int create_vmaccount(char *name, struct ast_variable *var, int realtime);
-static struct minivm_user *find_user_realtime(const char *domain, const char *username);
+static struct minivm_account *find_user_realtime(const char *domain, const char *username);
/*! \brief Create message template */
-static struct minivm_message *message_template_create(char *name)
-{
- struct minivm_message *template;
-
- template = calloc(1, sizeof(struct minivm_message));
+static struct minivm_template *message_template_create(char *name)
+{
+ struct minivm_template *template;
+
+ template = calloc(1, sizeof(struct minivm_template));
if (!template)
return NULL;
@@ -342,7 +418,7 @@
}
/*! \brief Release memory allocated by message template */
-static void message_template_free(struct minivm_message *template)
+static void message_template_free(struct minivm_template *template)
{
if (template->body)
free(template->body);
@@ -353,7 +429,7 @@
/*! \brief Build message template from configuration */
static int message_template_build(char *name, struct ast_variable *var)
{
- struct minivm_message *template;
+ struct minivm_template *template;
int error = 0;
template = message_template_create(name);
@@ -410,9 +486,9 @@
}
/*! \brief Find named template */
-static struct minivm_message *message_template_find(char *name)
-{
- struct minivm_message *this, *res = NULL;
+static struct minivm_template *message_template_find(char *name)
+{
+ struct minivm_template *this, *res = NULL;
if (ast_strlen_zero(name))
return NULL;
@@ -433,7 +509,7 @@
/*! \brief Clear list of templates */
static void message_destroy_list(void)
{
- struct minivm_message *this;
+ struct minivm_template *this;
AST_LIST_LOCK(&message_templates);
while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list)))
message_template_free(this);
@@ -576,7 +652,7 @@
/*! \brief Free user structure - if it's allocated */
-static void free_user(struct minivm_user *vmu)
+static void free_user(struct minivm_account *vmu)
{
if (vmu->chanvars)
ast_variables_destroy(vmu->chanvars);
@@ -588,14 +664,14 @@
/*! \brief Prepare for voicemail template by adding channel variables
to the channel
*/
-static void prep_email_sub_vars(struct ast_channel *channel, const struct minivm_user *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date)
+static void prep_email_sub_vars(struct ast_channel *channel, const struct minivm_account *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date)
{
char callerid[256];
struct ast_variable *var;
- if (vmu->chanvars) {
for (var = vmu->chanvars ; var ; var = var->next)
- pbx_builtin_setvar_helper(channel, var->name, var->value);}
+ pbx_builtin_setvar_helper(channel, var->name, var->value);
+
/* Prepare variables for substition in email body and subject */
pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname);
pbx_builtin_setvar_helper(channel, "MVM_DUR", dur);
@@ -608,7 +684,7 @@
}
/*! \brief Set default values for Mini-Voicemail users */
-static void populate_defaults(struct minivm_user *vmu)
+static void populate_defaults(struct minivm_account *vmu)
{
ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);
ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt));
@@ -635,11 +711,11 @@
/*! \brief Allocate new vm user and set default values */
-static struct minivm_user *mvm_user_alloc(void)
-{
- struct minivm_user *new;
-
- new = calloc(1, sizeof(struct minivm_user));
+static struct minivm_account *mvm_user_alloc(void)
+{
+ struct minivm_account *new;
+
+ new = calloc(1, sizeof(struct minivm_account));
if (!new)
return NULL;
populate_defaults(new);
@@ -651,18 +727,18 @@
/*! \brief Clear list of users */
static void vmaccounts_destroy_list(void)
{
- struct minivm_user *this;
- AST_LIST_LOCK(&minivm_users);
- while ((this = AST_LIST_REMOVE_HEAD(&minivm_users, list)))
+ struct minivm_account *this;
+ AST_LIST_LOCK(&minivm_accounts);
+ while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list)))
free(this);
- AST_LIST_UNLOCK(&minivm_users);
+ AST_LIST_UNLOCK(&minivm_accounts);
}
/*! \brief Find user from static memory object list */
-static struct minivm_user *find_user(const char *domain, const char *username)
-{
- struct minivm_user *vmu = NULL, *cur;
+static struct minivm_account *find_account(const char *domain, const char *username)
+{
+ struct minivm_account *vmu = NULL, *cur;
if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
@@ -672,18 +748,18 @@
if (option_debug > 2)
ast_log(LOG_DEBUG, "-_-_-_- Looking for voicemail user %s in domain %s\n", username, domain);
- AST_LIST_LOCK(&minivm_users);
- AST_LIST_TRAVERSE(&minivm_users, cur, list) {
- ast_log(LOG_DEBUG, " ---> Checking %s@%s\n", cur->username, cur->domain);
+ AST_LIST_LOCK(&minivm_accounts);
+ AST_LIST_TRAVERSE(&minivm_accounts, cur, list) {
/* Is this the voicemail account we're looking for? */
if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username))
break;
}
- AST_LIST_UNLOCK(&minivm_users);
+ AST_LIST_UNLOCK(&minivm_accounts);
if (cur) {
if (option_debug > 2)
ast_log(LOG_DEBUG, "-_-_- Found account for %s@%s\n", username, domain);
+ vmu = cur;
} else
vmu = find_user_realtime(domain, username);
@@ -704,12 +780,12 @@
}
/*! \brief Find user in realtime storage
- Returns pointer to minivm_user structure
+ Returns pointer to minivm_account structure
*/
-static struct minivm_user *find_user_realtime(const char *domain, const char *username)
+static struct minivm_account *find_user_realtime(const char *domain, const char *username)
{
struct ast_variable *var;
- struct minivm_user *retval;
+ struct minivm_account *retval;
char name[MAXHOSTNAMELEN];
retval = mvm_user_alloc();
@@ -735,7 +811,7 @@
}
/*! Send voicemail with audio file as an attachment */
-static int sendmail(struct minivm_message *template, char *srcemail, struct minivm_user *vmu, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type)
+static int sendmail(struct minivm_template *template, char *srcemail, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type)
{
FILE *p = NULL;
int pfd;
@@ -754,6 +830,7 @@
int len_passdata;
char *passdata2;
struct ast_channel *ast;
+ char *finalfilename;
if (type == MVM_MESSAGE_EMAIL) {
if (vmu && !ast_strlen_zero(vmu->email)) {
@@ -786,18 +863,20 @@
if (option_debug > 2)
ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
tmpfd = mkstemp(newtmp);
- snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
+ snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
ast_safe_system(tmpcmd);
- attach = newtmp;
+ finalfilename = newtmp;
if (option_debug > 2)
- ast_log (LOG_DEBUG, "-- VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, vmu->username);
+ ast_log (LOG_DEBUG, "-- VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
+ } else {
+ finalfilename = ast_strdupa(filename);
}
/* Create file name */
- snprintf(fname, sizeof(fname), "%s.%s", attach, format);
+ snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format);
if (option_debug && template->attachment)
- ast_log(LOG_DEBUG, "-- Attaching file '%s', format '%s', uservm is '%d'\n", attach, format, attach_user_voicemail);
+ ast_log(LOG_DEBUG, "-- Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail);
/* Make a temporary file instead of piping directly to sendmail, in case the mail
command hangs */
pfd = mkstemp(tmp);
@@ -939,7 +1018,7 @@
/*! \brief Create directory based on components */
static int make_dir(char *dest, int len, const char *domain, const char *username, const char *folder)
{
- return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder);
+ return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : "");
}
/*! \brief Checks if directory exists. Does not create directory, but builds string in dest
@@ -952,7 +1031,7 @@
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
{
struct stat filestat;
- make_dir(dest, len, domain, username, folder);
+ make_dir(dest, len, domain, username, folder ? folder : "");
if (stat(dest, &filestat)== -1)
return FALSE;
else
@@ -1063,6 +1142,7 @@
{
char *txt;
int txtsize = 0;
+ int res;
if (option_debug)
ast_log(LOG_DEBUG, "--- Deleting voicemail file %s\n", file);
@@ -1073,14 +1153,15 @@
* but trying to eliminate all sprintf's anyhow
*/
snprintf(txt, txtsize, "%s.txt", file);
- unlink(txt);
- return ast_filedelete(file, NULL);
+ res = unlink(txt);
+ res |= ast_filedelete(file, NULL);
+ return res;
}
/*! \brief Record voicemail message & let caller review or re-record it, or set options if applicable */
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt,
- int outsidecaller, struct minivm_user *vmu, int *duration, const char *unlockdir,
+ int outsidecaller, struct minivm_account *vmu, int *duration, const char *unlockdir,
signed char record_gain)
{
int cmd = 0;
@@ -1222,20 +1303,40 @@
}
}
+/*! \brief Run external notification for voicemail message */
+static void run_externnotify(struct ast_channel *chan, struct minivm_account *vmu)
+{
+ char arguments[BUFSIZ];
+
+ if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify))
+ return;
+
+ snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&",
+ ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify,
+ vmu->username, vmu->domain,
+ chan->cid.cid_name, chan->cid.cid_num);
+
+ if (option_debug)
+ ast_log(LOG_DEBUG, "Executing: %s\n", arguments);
+
+ ast_safe_system(arguments);
+}
+
/*! \brief Send message to voicemail account owner */
-static int notify_new_message(struct ast_channel *chan, struct minivm_user *vmu, char *filename, long duration, char *fmt, char *cidnum, char *cidname)
+static int notify_new_message(struct ast_channel *chan, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname)
{
char ext_context[PATH_MAX], *stringp;
char *myserveremail;
- struct minivm_message *etemplate;
+ struct minivm_template *etemplate;
+ char *messageformat;
snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->username, vmu->domain);
if (!ast_strlen_zero(vmu->attachfmt)) {
- if (strstr(fmt, vmu->attachfmt)) {
- fmt = vmu->attachfmt;
+ if (strstr(format, vmu->attachfmt)) {
+ format = vmu->attachfmt;
} else
- ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'. Falling back to default format for '%s@%s'.\n", vmu->attachfmt, fmt, vmu->username, vmu->domain);
+ ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'. Falling back to default format for '%s@%s'.\n", vmu->attachfmt, format, vmu->username, vmu->domain);
}
etemplate = message_template_find(vmu->etemplate);
@@ -1243,8 +1344,7 @@
etemplate = message_template_find("email-default");
/* Attach only the first format */
- fmt = ast_strdupa(fmt);
- stringp = fmt;
+ stringp = messageformat = ast_strdupa(format);
strsep(&stringp, "|");
@@ -1253,7 +1353,7 @@
else
myserveremail = etemplate->fromstring;
- sendmail(etemplate, myserveremail, vmu, cidnum, cidname, filename, fmt, duration, etemplate->attachment, MVM_MESSAGE_EMAIL);
+ sendmail(etemplate, myserveremail, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL);
if (!ast_strlen_zero(vmu->pager)) {
/* Find template for paging */
@@ -1261,20 +1361,18 @@
if (!etemplate)
etemplate = message_template_find("pager-default");
- sendmail(etemplate, myserveremail, vmu, cidnum, cidname, filename, fmt, duration, etemplate->attachment, MVM_MESSAGE_PAGE);
- }
-
- vm_delete(filename);
-
- manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentMail\rn\nMailbox: %s@%s\r\n", vmu->username, vmu->domain);
- // this needs to come back at a later time
- //run_externnotify(vmu->context, vmu->mailbox);
+ sendmail(etemplate, myserveremail, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE);
+ }
+
+
+ manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\n", vmu->username, vmu->domain);
+
+ run_externnotify(chan, vmu); /* Run external notification */
return 0;
}
-/*! \brief Record voicemail message, store into file prepared for sending e-mail
-*/
+/*! \brief Record voicemail message, store into file prepared for sending e-mail */
static int leave_voicemail(struct ast_channel *chan, char *username, struct leave_vm_options *options)
{
char tmptxtfile[PATH_MAX];
@@ -1289,7 +1387,7 @@
char fmt[80];
char *domain;
char tmp[256] = "";
- struct minivm_user *vmu;
+ struct minivm_account *vmu;
int userdir;
ast_copy_string(tmp, username, sizeof(tmp));
@@ -1300,9 +1398,9 @@
domain++;
}
- if (!(vmu = find_user(domain, username))) {
+ if (!(vmu = find_account(domain, username))) {
/* We could not find user, let's exit */
- ast_log(LOG_WARNING, "No entry in voicemail config file for '%s@%s'\n", username, domain);
+ ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain);
if (ast_test_flag(options, OPT_PRIORITY_JUMP) || option_priority_jumping)
ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "FAILED");
@@ -1414,11 +1512,17 @@
ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
unlink(tmptxtfile);
pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "FAILED");
+ if(ast_test_flag(vmu, MVM_ALLOCED))
+ free_user(vmu);
return 0;
}
- /* assign a variable with the name of the voicemail file */
- pbx_builtin_setvar_helper(chan, "MVM_MESSAGEFILE", tmptxtfile);
+ /* Set channel variables for the notify application */
+ pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile);
+ snprintf(timebuf, sizeof(timebuf), "%d", duration);
+ pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf);
+ pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt);
+
/* Notify of new message to e-mail and pager */
notify_new_message(chan, vmu, tmptxtfile, duration, fmt, chan->cid.cid_num, chan->cid.cid_name);
}
@@ -1434,12 +1538,160 @@
if (res > 0)
res = 0;
+ if(ast_test_flag(vmu, MVM_ALLOCED))
+ free_user(vmu);
+
pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "SUCCESS");
return res;
}
+/*! \brief Notify voicemail account owners - either generic template or user specific */
+static int minivm_notify_exec(struct ast_channel *chan, void *data)
+{
+ struct localuser *u;
+ int argc;
+ char *argv[2];
+ int res = 0;
+ char tmp[PATH_MAX];
+ char *domain;
+ char *tmpptr;
+ struct minivm_account *vmu;
+ char *username = argv[0];
+ const char *template;
+ const char *filename;
+ const char *format;
+ const char *duration_string;
+
+ LOCAL_USER_ADD(u);
+
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+ tmpptr = ast_strdupa((char *)data);
+ if (!tmpptr) {
+ ast_log(LOG_ERROR, "Out of memory\n");
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+ argc = ast_app_separate_args(tmpptr, '|', argv, sizeof(argv) / sizeof(argv[0]));
+
+ if (argc == 2 && !ast_strlen_zero(argv[1]))
+ template = argv[1];
+
+ ast_copy_string(tmp, argv[0], sizeof(tmp));
+ username = tmp;
+ domain = strchr(tmp, '@');
+ if (domain) {
+ *domain = '\0';
+ domain++;
+ }
+ if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
+ ast_log(LOG_ERROR, "Need username at domain as argument. Sorry. Argument 0 %s\n", argv[0]);
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+
+ if(!(vmu = find_account(domain, username))) {
+ /* We could not find user, let's exit */
+ ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
+ pbx_builtin_setvar_helper(chan, "MINIVMNOTIFYSTATUS", "FAILED");
+ }
+
+ filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME");
+ format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT");
+ duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION");
+ /* Notify of new message to e-mail and pager */
+ if (!ast_strlen_zero(filename))
+ notify_new_message(chan, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name);
+ else
+
+
+ if(ast_test_flag(vmu, MVM_ALLOCED))
+ free_user(vmu);
+
+
+ /* Ok, we're ready to rock and roll. Return to dialplan */
+ LOCAL_USER_REMOVE(u);
+
+ return res;
+
+}
+
+/*! \brief Dialplan function to record voicemail */
+static int minivm_record_exec(struct ast_channel *chan, void *data)
+{
+ int res = 0;
+ struct localuser *u;
+ char *tmp;
+ struct leave_vm_options leave_options;
+ int argc;
+ char *argv[2];
+ struct ast_flags flags = { 0 };
+ char *opts[OPT_ARG_ARRAY_SIZE];
+
+ LOCAL_USER_ADD(u);
+
+ memset(&leave_options, 0, sizeof(leave_options));
+
+ /* Answer channel if it's not already answered */
+ if (chan->_state != AST_STATE_UP)
+ ast_answer(chan);
+
+ if (ast_strlen_zero(data)) {
+ ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+ tmp = ast_strdupa((char *)data);
+ if (!tmp) {
+ ast_log(LOG_ERROR, "Out of memory\n");
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+ argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ if (argc == 2) {
+ if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+ ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
+ if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
+ int gain;
+
+ if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
+ ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ } else
+ leave_options.record_gain = (signed char) gain;
+ }
+ }
+
+ /* Now run the appliation and good luck to you! */
+ res = leave_voicemail(chan, argv[0], &leave_options);
+
+ if (res == ERROR_LOCK_PATH) {
+ ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
+ /* Send the call to n+101 priority, where n is the current priority*/
+ if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || option_priority_jumping)
+ if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
+ ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
+ pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "FAILED");
+ res = 0;
+ }
+ pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "SUCCESS");
+
+
+ LOCAL_USER_REMOVE(u);
+
+ return res;
+}
+
/*! \brief Play voicemail prompts - either generic or user specific */
-static int minivm_prompt_exec(struct ast_channel *chan, void *data)
+static int minivm_greet_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
struct leave_vm_options leave_options = { 0, '\0'};
@@ -1453,20 +1705,16 @@
int ouseexten = 0;
char tmp[PATH_MAX];
char dest[PATH_MAX];
- char prefile[PATH_MAX] = "";
+ char prefile[PATH_MAX];
char tempfile[PATH_MAX] = "";
char ext_context[256] = "";
char *domain;
char ecodes[16] = "#";
char *tmpptr;
- struct minivm_user *vmu;
+ struct minivm_account *vmu;
char *username = argv[0];
LOCAL_USER_ADD(u);
-
- /* Answer channel if it's not already answered */
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
@@ -1480,6 +1728,7 @@
return -1;
}
argc = ast_app_separate_args(tmpptr, '|', argv, sizeof(argv) / sizeof(argv[0]));
+
if (argc == 2) {
if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
LOCAL_USER_REMOVE(u);
@@ -1496,21 +1745,22 @@
domain++;
}
if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
- ast_log(LOG_ERROR, "Need username at domain as argument. Sorry. Argument 0 %s\n", argv[0]);
+ ast_log(LOG_ERROR, "Need username at domain as argument. Sorry. Argument: %s\n", argv[0]);
LOCAL_USER_REMOVE(u);
return -1;
}
if (option_debug)
- ast_log(LOG_DEBUG, "-_-_- Trying to find prompts for user %s in domain %s\n", username, domain);
-
- if (!(vmu = find_user(domain, username))) {
- /* We could not find user, let's exit */
- ast_log(LOG_WARNING, "No entry in voicemail config file for '%s@%s'\n", username, domain);
- if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || option_priority_jumping)
- ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "MINIVMGREETSTATUS", "FAILED");
- return res;
- }
+ ast_log(LOG_DEBUG, "-_-_- Trying to find configuration for user %s in domain %s\n", username, domain);
+
+ if (!(vmu = find_account(domain, username))) {
+ ast_log(LOG_ERROR, "Could not allocate memory. \n");
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+
+ /* Answer channel if it's not already answered */
+ if (chan->_state != AST_STATE_UP)
+ ast_answer(chan);
/* Setup pre-file if appropriate */
if (strcmp(vmu->domain, "localhost"))
@@ -1578,6 +1828,9 @@
if (option_debug > 1)
ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
pbx_builtin_setvar_helper(chan, "MINIVMGREETSTATUS", "FAILED");
+ if(ast_test_flag(vmu, MVM_ALLOCED))
+ free_user(vmu);
+ LOCAL_USER_REMOVE(u);
return -1;
}
if (res == '#') {
@@ -1622,7 +1875,7 @@
chan->priority = 0;
pbx_builtin_setvar_helper(chan, "MINIVMGREETSTATUS", "USEREXIT");
}
- return 0;
+ res = 0;
} else if (res < 0) {
pbx_builtin_setvar_helper(chan, "MINIVMGREETSTATUS", "FAILED");
res = -1;
@@ -1640,72 +1893,42 @@
}
-/*! \brief Dialplan core function */
-static int minivm_exec(struct ast_channel *chan, void *data)
+/*! \brief Dialplan application to delete voicemail */
+static int minivm_delete_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
- char *tmp;
- struct leave_vm_options leave_options;
- int argc;
- char *argv[2];
- struct ast_flags flags = { 0 };
- char *opts[OPT_ARG_ARRAY_SIZE];
+ char *filename;
LOCAL_USER_ADD(u);
- memset(&leave_options, 0, sizeof(leave_options));
-
- /* Answer channel if it's not already answered */
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- if (ast_strlen_zero(data)) {
- ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
+ if (!ast_strlen_zero(data))
+ filename = data;
+ else
+ filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME");
+
+ if (ast_strlen_zero(filename)) {
LOCAL_USER_REMOVE(u);
- return -1;
- }
- tmp = ast_strdupa((char *)data);
- if (!tmp) {
- ast_log(LOG_ERROR, "Out of memory\n");
- LOCAL_USER_REMOVE(u);
- return -1;
- }
- argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
- if (argc == 2) {
- if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
- LOCAL_USER_REMOVE(u);
- return -1;
- }
- ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
- if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
- int gain;
-
- if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
- ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
- LOCAL_USER_REMOVE(u);
- return -1;
- } else
- leave_options.record_gain = (signed char) gain;
- }
+ ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n");
}
- /* Now run the appliation and good luck to you! */
- res = leave_voicemail(chan, argv[0], &leave_options);
-
- if (res == ERROR_LOCK_PATH) {
- ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
- /* Send the call to n+101 priority, where n is the current priority*/
- if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || option_priority_jumping)
- if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
- ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
- pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "FAILED");
- res = 0;
- }
- pbx_builtin_setvar_helper(chan, "MINIVMSTATUS", "SUCCESS");
-
- if(ast_test_flag(vmu, MVM_ALLOCED))
- free_user(vmu);
+ /* Go ahead and delete audio files from system, they're not needed any more */
+ if (ast_fileexists(filename, NULL, NULL) < 0) {
+ res = vm_delete(filename);
+ if (res) {
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "Can't delete file: %s\n", filename);
+ pbx_builtin_setvar_helper(chan, "MINIVMDELETESTATUS", "FAILED");
+ } else {
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "-_-_- Deleted voicemail file :: %s \n", filename);
+ pbx_builtin_setvar_helper(chan, "MINIVMDELETESTATUS", "SUCCESS");
+ }
+ } else {
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "Filename does not exist: %s\n", filename);
+ pbx_builtin_setvar_helper(chan, "MINIVMDELETESTATUS", "FAILED");
+ }
LOCAL_USER_REMOVE(u);
@@ -1716,7 +1939,7 @@
/*! \brief Append new mailbox to mailbox list from configuration file */
static int create_vmaccount(char *name, struct ast_variable *var, int realtime)
{
- struct minivm_user *vmu;
+ struct minivm_account *vmu;
char *domain;
char *username;
char accbuf[BUFSIZ];
@@ -1740,7 +1963,7 @@
ast_log(LOG_DEBUG, "Creating static account for user %s domain %s\n", username, domain);
/* Allocate user account */
- vmu = calloc(1, sizeof(struct minivm_user));
+ vmu = calloc(1, sizeof(struct minivm_account));
if (!vmu)
return 0;
@@ -1759,12 +1982,18 @@
ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail));
} else if (!strcasecmp(var->name, "email")) {
ast_copy_string(vmu->email, var->value, sizeof(vmu->email));
+ } else if (!strcasecmp(var->name, "accountcode")) {
+ ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode));
+ } else if (!strcasecmp(var->name, "pincode")) {
+ ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode));
} else if (!strcasecmp(var->name, "domain")) {
ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain));
} else if (!strcasecmp(var->name, "language")) {
ast_copy_string(vmu->language, var->value, sizeof(vmu->language));
- } else if (!strcasecmp(var->name, "zone")) {
+ } else if (!strcasecmp(var->name, "timezone")) {
ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag));
[... 459 lines stripped ...]
More information about the asterisk-commits
mailing list