[asterisk-commits] brushtyler: branch brushtyler/voicemail_menu_branch r213785 - /team/brushtyle...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun Aug 23 12:24:50 CDT 2009
Author: brushtyler
Date: Sun Aug 23 12:24:45 2009
New Revision: 213785
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=213785
Log:
added some comments
Modified:
team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c
Modified: team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c?view=diff&rev=213785&r1=213784&r2=213785
==============================================================================
--- team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c (original)
+++ team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c Sun Aug 23 12:24:45 2009
@@ -354,7 +354,7 @@
static int load_config(int);
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms);
-static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms,
+static int forward_voicemail(struct ast_channel *chan, char *context, struct vm_state *vms,
struct ast_vm_user *sender, char *username, char *fmt, int is_tmp_message,
signed char record_gain, int urgent);
/*
@@ -1774,7 +1774,7 @@
int useadsi;
int skipuser;
char *context; /*!< conteins the called voicemail context */
- int silentexit;
+ int silentexit; /*!< used to exit when a dialout or callback are invoked */
/* struct ast_flags flags = { 0 }; */
signed char record_gain;
int play_auto;
@@ -1901,9 +1901,7 @@
* \param chan
* \param vms
* \param vmu
- * \param s_cid to return the sender cid
- *
- * This is called to retrieve information to the sender of a message
+ * \param s_cid used to return the sender cid
*
* \return -1 if an error is occurred, 1 if sender has a mailbox, 0 otherwise.
*/
@@ -1959,12 +1957,10 @@
}
/*!
- * \brief Set the channels variables to retrieve info on current selected message
+ * \brief Set the channels variables to retrieve some information on current selected message
* \param chan
* \param vms
* \param vmu
- *
- * This is called to set some channel variables to retrieve message information in the voicemail_menu.conf
*
* \return zero on success, -1 on error.
*/
@@ -2023,8 +2019,6 @@
* \param chan
* \param vms
* \param vmu
- *
- * This is called to set some channel variables to retrieve global information in the voicemail_menu.conf
*
* \return zero on success, -1 on error.
*/
@@ -2064,8 +2058,8 @@
* \param args the string to parse
* \param chan
* \param vms
- * \param fold to return the folder as second param in args
- * \param num to return the message number as first param in args
+ * \param fold used to return the folder as second param in args
+ * \param num used to return the message number as first param in args
*
* This is called to parse a string that contains as first arg a message number and as second arg a folder name.
* If the folder name is omitted the message number is relative on the current message, if is "current" or an existent
@@ -2143,8 +2137,8 @@
* \param vm_var
* \param result none
*
- * This function calls the parse_message_num() to retrieve the number and folder
- * from args, then sets that message as current message
+ * Reads the number and folder from args (invoke the parse_message_num() to retrieve these information),
+ * then sets that message as current message
*
* \return zero on success, 1 on error that affects only the current
* action, -1 on other errors.
@@ -2231,8 +2225,7 @@
* \param vm_var
* \param result is "1" if the message exists, "0" otherwise
*
- * This function retrieves the message number and folder or the special message
- * name from args and makes an existence test
+ * Reads the message number and folder or the special message name from args and then test if that message exists
*/
static int vmm_msg_exists(const char* args, struct ast_channel* chan, struct vm_state* vms,
struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
@@ -2310,7 +2303,7 @@
* \param vm_var
* \param result none
*
- * This function takes from args the name of a folder and then saves the current
+ * Read the name of a folder from args and then saves the current
* selected message in that folder.
*
* \return zero on success, 1 if an error occurred but affects only the current
@@ -2420,20 +2413,19 @@
struct ast_vm_user* vmu, struct exec_main_var* vm_var);
/*!
- * \brief Record a temporary message (voice message and information file)
- * or a greeting message (voice message only)
- * \param args none
+ * \brief Record a temporary message (voice message and information file) or a greeting message (voice message only)
+ * \param args the message type
* \param chan
* \param vms
* \param vmu
* \param vm_var
* \param result none
*
- * This is used to record a temporary message or greeting message. If args
- * contains the name of a greeting message (unv, busy, name, temp) then record
- * only the voice message and save it, else if contains the keyword for
- * temporary message (rec) the voice message are recorded and the information
- * file are created too.
+ * This is used to record a temporary message or greeting message.
+ * If want record a greeting message (unv, busy, name, temp)
+ * invoke the review_record_store_delete() function to record the voice message and then save it
+ * If want record a temporary message (rec)
+ * invoke the record_voicemail() function to create the information file and record the voice message
*
* \return zero on success, 1 if an error occurred but affects only the current
* action, -1 on other errors.
@@ -2467,8 +2459,7 @@
* \param vm_var
* \param result none
*
- * This function plays a sound file using args as name of the file to play. Is
- * used in voicemail_menu.conf to play the menu instructions.
+ * This function plays a sound file its name. In voicemail_menu.conf is used to play the menu instructions.
*
* \return zero on success, -1 on errors.
*/
@@ -2513,8 +2504,7 @@
* \param vm_var
* \param result none
*
- * This function retrieves the message number and folder from args and then
- * sets that message as current and plays it.
+ * Reads the message number and folder from args and then sets that message as current and plays it.
*
* \return zero on success, 1 if an error occurred but affects only the current
* action, -1 on other errors.
@@ -2562,10 +2552,9 @@
* \param vmu
* \param vm_var
*
- * This function is used to record both the voice message and the related
- * information file. It creates the information file and then records the
- * voice message. If an error occurs or if the recorded file is too short,
- * both the two files are deleted.
+ * Is used to record both the voice message and the related information file.
+ * It creates the information file and then records the voice message.
+ * If an error occurs or if the recorded file is too short, both the two files are deleted.
*
* \return zero on success, 1 if an error occurred but affects only the current
* action, -1 on other errors.
@@ -2810,7 +2799,7 @@
if (cmd < 0)
return -1;
- if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0)
+ if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword)-1, 2000, 10000, "#")) < 0)
return -1;
}
cmd = check_password(vmu, newpassword); /* perform password validation */
@@ -2826,7 +2815,7 @@
else {
if (cmd < 0)
return -1;
- if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) {
+ if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2)-1, 2000, 10000, "#")) < 0) {
return -1;
}
}
@@ -2840,7 +2829,7 @@
if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd))
vm_change_password_shell(vmu, newpassword);
- ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
+ ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int)strlen(newpassword));
cmd = ast_play_and_wait(chan, "vm-passchanged");
return 0;
@@ -2894,8 +2883,7 @@
/*!
* \brief Set or unset a message for deletion or delete a greeting/temporary message
- * \param args can contains the message number and folder or a special
- * message type (unv, busy, name, temp, rec)
+ * \param args can contains the message number and folder or a special message type (unv, busy, name, temp, rec)
* \param chan
* \param vms
* \param vmu
@@ -2957,17 +2945,20 @@
}
/*!
- * \brief Forward a message to another mailbox
- * \param args the recipient mailbox and optionally the type of special message
- * to forward
+ * \brief Sends a message to a mailbox
+ * \param args the recipient mailbox and optionally the type of special message to send
* \param chan
* \param vms
* \param vmu
* \param vm_var
* \param result none
*
- * \return zero on success, 1 if an error occurred but affects only the current
- * action, -1 on other errors.
+ * Reads the recipient mailbox from args. If there is a second param in args,
+ * it is the type of the special message to send, otherwise the current
+ * selected message is sent.
+ * Then invokes the forward_voicemail() function to send the message.
+ *
+ * \return zero on success, 1 if an error occurred but affects only the current action, -1 on other errors.
*/
static int vmm_forward_msg(const char* args, struct ast_channel* chan, struct vm_state* vms,
struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
@@ -3012,12 +3003,12 @@
}
if (ptype) {
- res = forward_message(chan, vmu->context, vms, vmu, username, vmfmts, 1, vm_var->record_gain, vm_var->in_urgent);
+ res = forward_voicemail(chan, vmu->context, vms, vmu, username, vmfmts, 1, vm_var->record_gain, vm_var->in_urgent);
if (res == ERROR_LOCK_PATH) {
return -1;
}
} else if (vms->lastmsg > -1) {
- res = forward_message(chan, vmu->context, vms, vmu, username, vmfmts, 0, vm_var->record_gain, vm_var->in_urgent);
+ res = forward_voicemail(chan, vmu->context, vms, vmu, username, vmfmts, 0, vm_var->record_gain, vm_var->in_urgent);
if (res == ERROR_LOCK_PATH) {
return -1;
}
@@ -3064,9 +3055,13 @@
* \param vmu
* \param vm_var
* \param result none
+ *
+ * This function permit to the user to call a number. If the number is valid
+ * then the number is saved in the channel and the voicemail application is
+ * terminated.
*
- * \return zero on success, 1 if an error occurred but affects only the current
- * action, -1 on other errors.
+ * \return zero on success, 1 if user digited no number or he want repeat it,
+ * -1 on error.
*/
static int vmm_dialout(const char* args, struct ast_channel* chan, struct vm_state* vms,
struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
@@ -3103,6 +3098,15 @@
* \param res used to return menu informations (i.e. jump to other menu, pressed digits)
* or NULL if only the function execution is required (i.e. test a condition)
*
+ * This function is called to execute a function.
+ * First, it searches for the function argument. If the argument is found,
+ * tries to exec it as a new function (recursive call), if no argument is
+ * found, makes a variables substitution and then executes the function.
+ * To do this, the function is first searched among those implentented by
+ * the voicemail and, if not found, is used the dialplan functions.
+ * The result of the function execution is returned and replaces the argument
+ * on the previous recursive level.
+ *
* \return zero on success, -1 on error, the digit pressed by user.
*/
static int exec_function(struct ast_channel *chan, struct vm_state* vms, struct ast_vm_user *vmu,
@@ -3196,7 +3200,7 @@
* when try to exec one of these actions */
if (!strcasecmp(name, "return")) {
if (!res) {
- ast_log(AST_LOG_WARNING, "Finded a return function in a condition: check the conf file.\n");
+ ast_log(AST_LOG_WARNING, "Found a return function in a condition: check the conf file.\n");
return -1;
}
@@ -3205,7 +3209,7 @@
res->steps = atoi(buf);
} else if (!strcasecmp(name, "exit")) {
if (!res) {
- ast_log(AST_LOG_WARNING, "Finded an exit function in a condition: check the conf file.\n");
+ ast_log(AST_LOG_WARNING, "Found an exit function in a condition: check the conf file.\n");
return -1;
}
@@ -3217,7 +3221,7 @@
return -1;
} else if (!strcasecmp(name, "jump")) {
if (!res) {
- ast_log(AST_LOG_WARNING, "Finded a jump function in a condition: check the conf file.\n");
+ ast_log(AST_LOG_WARNING, "Found a jump function in a condition: check the conf file.\n");
return -1;
}
@@ -3226,7 +3230,7 @@
res->code = VMM_JUMP;
} else if (!strcasecmp(name, "call")) {
if (!res) {
- ast_log(AST_LOG_WARNING, "Finded a call function in a condition: check the conf file.\n");
+ ast_log(AST_LOG_WARNING, "Found a call function in a condition: check the conf file.\n");
return -1;
}
@@ -3349,8 +3353,11 @@
* \param vmu
* \param vm_var
*
- * \return zero if result is NULL or "0" or an empty string (condition not verified),
- * -1 if no condition, 1 in the other cases (condition is verified).
+ * This function invokes the exec_function() to exec the entry condition to
+ * evaluate its result.
+ *
+ * \return zero if the result is NULL or "0" or an empty string (condition not
+ * verified), -1 if no condition, 1 in the other cases (condition verified).
*/
static int enabled(const char *condition, struct ast_channel *chan, struct vm_state* vms,
struct ast_vm_user *vmu, struct exec_main_var* vm_var)
@@ -3393,14 +3400,32 @@
return 1; /* condition is true */
}
-/*
+/*!
+ * \brief Evaluates an entry condition
+ * \param condition the entry condition to evaluate
+ * \param chan
+ * \param vms
+ * \param vmu
+ * \param vm_var
+ *
* This is the function that implements the menu.
- * We loop forever, in different internal states:
- * VMM_MS_INIT the first time we enter a menu. We don't want to read
- * user input, but instead try to match the 'init' action.
- * VMM_MS_DEFAULT timeout or input not recognised.
- * VMM_MS_TIMEOUT the default action has been executed max_retries times.
- * VMM_MS_WORKING normal operation.
+ * It loops forever, in different internal states:
+ * - when enter in a menu, the internal state is set to VMM_MS_INIT. In
+ * this state we execute the 'init' actions list (if exists) and then,
+ * if the digits buffer is empty, wait for user input.
+ * - when no input or the user input is not recognised, the function wonk
+ * on VMM_MS_DEFAULT state. In this state we execute the 'default'
+ * actions list (if exists) and then, if the digits buffer is empty,
+ * wait for the user input.
+ * - when the default action has been executed max_retries times, the
+ * internal state change to VMM_MS_TIMEOUT. If exists, the 'timeout'
+ * actions list is executed, else we exit from voicemail application.
+ * - when the user input match any pattern, VMM_MS_WORKING is used as the
+ * internal state.
+ * To execute the actions in the list, invokes the exec_actions() function
+ * that returns the menu action to do or none if no menu action we must do.
+ *
+ * \return zero on success, -1 on error.
*/
static int do_menu(struct ast_channel *chan, struct ast_category * menu_cat,
const char *menu_name, int depth, struct vm_state* vms,
@@ -3648,14 +3673,23 @@
return 1;
}
-/*
+/*!
+ * \brief Exec a list of actions
+ * \param menu the current menu category
+ * \param body the list of actions to execute
+ * \param chan
+ * \param vms
+ * \param vmu
+ * \param vm_var
+ *
* This function takes a string representing a list of action in the configuration
- * file and execute it; it returns:
- * VMM_ERROR on error
- * VMM_JUMP if a jump to menu is called
- * VMM_CONTINUE if every function in list has been executed
- * VMM_RETURN if a return has been called
- *
+ * file and execute it. It returns:
+ * VMM_ERROR on error
+ * VMM_JUMP if a jump to menu is called
+ * VMM_CONTINUE if every function in list has been executed
+ * VMM_RETURN if a return has been called
+ *
+ * \return the menu action to do.
*/
struct exec_result vm_exec_actions(struct ast_category *menu, const char *body,
struct ast_channel *chan, int depth, struct vm_state* vms, struct ast_vm_user *vmu,
@@ -3772,7 +3806,6 @@
int valid = 0;
char prefixstr[80] = "";
char ext_context[256] = "";
- /*int box;*/ /*EX information about starting folder*/
int useadsi = 0;
int skipuser = 0;
struct vm_state vms;
@@ -3870,7 +3903,7 @@
ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
- skipuser++; /*se trovo l'utente lo memorizzo in VMUS*/
+ skipuser++;
else
valid = 0;
}
@@ -4062,662 +4095,6 @@
return res;
}
-#if 0
-
-/*!
- * \brief Sends email notification that a user has a new voicemail waiting for them.
- * \param chan
- * \param vmu
- * \param vms
- * \param msgnum
- * \param duration
- * \param fmt
- * \param cidnum The Caller ID phone number value.
- * \param cidname The Caller ID name value.
- *
- * \return zero on success, -1 on error.
- */
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag)
-{
- char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
- int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;
- const char *category;
- char *myserveremail = serveremail;
-
- ast_channel_lock(chan);
- if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) {
- category = ast_strdupa(category);
- }
- ast_channel_unlock(chan);
-
- make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
- make_file(fn, sizeof(fn), todir, msgnum);
- snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
-
- if (!ast_strlen_zero(vmu->attachfmt)) {
- if (strstr(fmt, vmu->attachfmt))
- fmt = vmu->attachfmt;
- else
- ast_log(AST_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->mailbox, vmu->context);
- }
-
- /* Attach only the first format */
- fmt = ast_strdupa(fmt);
- stringp = fmt;
- strsep(&stringp, "|");
-
- if (!ast_strlen_zero(vmu->serveremail))
- myserveremail = vmu->serveremail;
-
- if (!ast_strlen_zero(vmu->email)) {
- int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
- if (!attach_user_voicemail)
- attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
-
- if (attach_user_voicemail)
- RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
-
- /* XXX possible imap issue, should category be NULL XXX */
-// sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag);
-
- if (attach_user_voicemail)
- DISPOSE(todir, msgnum);
- }
-
- if (!ast_strlen_zero(vmu->pager)) {
-// sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category, flag);
- }
-
- if (ast_test_flag(vmu, VM_DELETE))
- DELETE(todir, msgnum, fn, vmu);
-
- /* Leave voicemail for someone */
- if (ast_app_has_voicemail(ext_context, NULL))
- ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs);
-
- queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs);
-
- manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
- run_externnotify(vmu->context, vmu->mailbox, flag);
-
-#ifdef IMAP_STORAGE
- vm_delete(fn); /* Delete the file, but not the IMAP message */
- if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */
- vm_imap_delete(vms->curmsg, vmu);
- vms->newmessages--; /* Fix new message count */
- }
-#endif
-
- return 0;
-}
-
-/*!
- * \brief Gets the current date and time, as formatted string.
- * \param s The buffer to hold the output formatted date.
- * \param len the length of the buffer. Used to prevent buffer overflow in ast_strftime.
- *
- * The date format string used is "%a %b %e %r UTC %Y".
- *
- * \return zero on success, -1 on error.
- */
-static int get_date(char *s, int len)
-{
- struct ast_tm tm;
- struct timeval t = ast_tvnow();
-
- ast_localtime(&t, &tm, "UTC");
-
- return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm);
-}
-
-static int invent_message(struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
-{
- int res;
- char fn[PATH_MAX];
- char dest[PATH_MAX];
-
- snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
-
- if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) {
- ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn);
- return -1;
- }
-
- RETRIEVE(fn, -1, ext, context);
- if (ast_fileexists(fn, NULL, NULL) > 0) {
- res = ast_stream_and_wait(chan, fn, ecodes);
- if (res) {
- DISPOSE(fn, -1);
- return res;
- }
- } else {
- /* Dispose just in case */
- DISPOSE(fn, -1);
- res = ast_stream_and_wait(chan, "vm-theperson", ecodes);
- if (res)
- return res;
- res = ast_say_digit_str(chan, ext, ecodes, chan->language);
- if (res)
- return res;
- }
- res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes);
- return res;
-}
-
-/*!
- * \brief Prompts the user and records a voicemail to a mailbox.
- * \param chan
- * \param ext
- * \param options OPT_BUSY_GREETING, OPT_UNAVAIL_GREETING
- *
- *
- *
- * \return zero on success, -1 on error.
- */
-static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
-{
-#ifdef IMAP_STORAGE
- int newmsgs, oldmsgs;
-#else
- char urgdir[PATH_MAX];
-#endif
- char txtfile[PATH_MAX];
- char tmptxtfile[PATH_MAX];
- struct vm_state *vms = NULL;
- char callerid[256];
- FILE *txt;
- char date[256];
- int txtdes;
- int res = 0;
- int msgnum;
- int duration = 0;
- int ausemacro = 0;
- int ousemacro = 0;
- int ouseexten = 0;
- char tmpdur[16];
- char priority[16];
- char origtime[16];
- char dir[PATH_MAX];
- char tmpdir[PATH_MAX];
- char fn[PATH_MAX];
- char prefile[PATH_MAX] = "";
- char tempfile[PATH_MAX] = "";
- char ext_context[256] = "";
- char fmt[80];
- char *context;
- char ecodes[17] = "#";
- struct ast_str *tmp = ast_str_create(16);
- char *tmpptr;
- struct ast_vm_user *vmu;
- struct ast_vm_user svm;
- const char *category = NULL;
- const char *code;
- const char *alldtmf = "0123456789ABCD*#";
- char flag[80];
-
- if (!tmp) {
- return -1;
- }
-
- ext = ast_strdupa(ext);
- if ((context = strchr(ext, '@'))) {
- *context++ = '\0';
- tmpptr = strchr(context, '&');
- } else {
- tmpptr = strchr(ext, '&');
- }
-
- if (tmpptr)
- *tmpptr++ = '\0';
-
- ast_channel_lock(chan);
- if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) {
- category = ast_strdupa(category);
- }
- ast_channel_unlock(chan);
-
- if (ast_test_flag(options, OPT_MESSAGE_Urgent)) {
- ast_copy_string(flag, "Urgent", sizeof(flag));
- } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) {
- ast_copy_string(flag, "PRIORITY", sizeof(flag));
- } else {
- flag[0] = '\0';
- }
-
- ast_debug(3, "Before find_user\n");
- if (!(vmu = find_user(&svm, context, ext))) {
- ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- ast_free(tmp);
- return res;
- }
- /* Setup pre-file if appropriate */
- if (strcmp(vmu->context, "default"))
- snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
- else
- ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
-
- /* Set the path to the prefile. Will be one of
- VM_SPOOL_DIRcontext/ext/busy
- VM_SPOOL_DIRcontext/ext/unavail
- Depending on the flag set in options.
- */
- if (ast_test_flag(options, OPT_BUSY_GREETING)) {
- snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
- } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
- snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
- }
- /* Set the path to the tmpfile as
- VM_SPOOL_DIR/context/ext/temp
- and attempt to create the folder structure.
- */
- snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
- if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) {
- ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
- ast_free(tmp);
- return -1;
- }
- RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context);
- if (ast_fileexists(tempfile, NULL, NULL) > 0)
- ast_copy_string(prefile, tempfile, sizeof(prefile));
-
- DISPOSE(tempfile, -1);
- /* It's easier just to try to make it than to check for its existence */
- create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
-
- /* Check current or macro-calling context for special extensions */
- if (ast_test_flag(vmu, VM_OPERATOR)) {
- if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ouseexten = 1;
- }
- } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ouseexten = 1;
- } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
- strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
- ousemacro = 1;
- }
- }
-
- if (!ast_strlen_zero(vmu->exit)) {
- if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
- strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
- ausemacro = 1;
- }
-
- if (ast_test_flag(options, OPT_DTMFEXIT)) {
- for (code = alldtmf; *code; code++) {
- char e[2] = "";
- e[0] = *code;
- if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num))
- strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
- }
- }
-
- /* Play the beginning intro if desired */
- if (!ast_strlen_zero(prefile)) {
-#ifdef ODBC_STORAGE
- int success =
-#endif
- RETRIEVE(prefile, -1, ext, context);
- if (ast_fileexists(prefile, NULL, NULL) > 0) {
- if (ast_streamfile(chan, prefile, chan->language) > -1)
- res = ast_waitstream(chan, ecodes);
-#ifdef ODBC_STORAGE
- if (success == -1) {
- /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
- ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
- store_file(prefile, vmu->mailbox, vmu->context, -1);
- }
-#endif
- } else {
- ast_debug(1, "%s doesn't exist, doing what we can\n", prefile);
- res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
- }
- DISPOSE(prefile, -1);
- if (res < 0) {
- ast_debug(1, "Hang up during prefile playback\n");
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- ast_free(tmp);
- return -1;
- }
- }
- if (res == '#') {
- /* On a '#' we skip the instructions */
- ast_set_flag(options, OPT_SILENT);
- res = 0;
- }
- if (!res && !ast_test_flag(options, OPT_SILENT)) {
- res = ast_stream_and_wait(chan, INTRO, ecodes);
- if (res == '#') {
- ast_set_flag(options, OPT_SILENT);
- res = 0;
- }
- }
- if (res > 0)
- ast_stopstream(chan);
- /* Check for a '*' here in case the caller wants to escape from voicemail to something
- other than the operator -- an automated attendant or mailbox login for example */
- if (res == '*') {
- chan->exten[0] = 'a';
- chan->exten[1] = '\0';
- if (!ast_strlen_zero(vmu->exit)) {
- ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
- } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
- ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
- }
- chan->priority = 0;
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- ast_free(tmp);
- return 0;
- }
-
- /* Check for a '0' here */
- if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
- transfer:
- if (ouseexten || ousemacro) {
- chan->exten[0] = 'o';
- chan->exten[1] = '\0';
- if (!ast_strlen_zero(vmu->exit)) {
- ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
- } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
- ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
- }
- ast_play_and_wait(chan, "transfer");
- chan->priority = 0;
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- }
- ast_free(tmp);
- return 0;
- }
-
- /* Allow all other digits to exit Voicemail and return to the dialplan */
- if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) {
- if (!ast_strlen_zero(options->exitcontext))
- ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context));
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
- ast_free(tmp);
- return res;
- }
-
- if (res < 0) {
- free_user(vmu);
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- ast_free(tmp);
- return -1;
- }
- /* The meat of recording the message... All the announcements and beeps have been played*/
- ast_copy_string(fmt, vmfmts, sizeof(fmt));
- if (!ast_strlen_zero(fmt)) {
- msgnum = 0;
-
-#ifdef IMAP_STORAGE
- /* Is ext a mailbox? */
- /* must open stream for this user to get info! */
- res = inboxcount(ext_context, &newmsgs, &oldmsgs);
- if (res < 0) {
- ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n");
- ast_free(tmp);
- return -1;
- }
- if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) {
- /* It is possible under certain circumstances that inboxcount did not
- * create a vm_state when it was needed. This is a catchall which will
- * rarely be used.
- */
- if (!(vms = create_vm_state_from_user(vmu))) {
- ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n");
- ast_free(tmp);
- return -1;
- }
- }
- vms->newmessages++;
-
- /* here is a big difference! We add one to it later */
- msgnum = newmsgs + oldmsgs;
- ast_debug(3, "Messagecount set to %d\n",msgnum);
- snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
- /* set variable for compatibility */
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
-
- /* Check if mailbox is full */
- check_quota(vms, imapfolder);
- if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
- ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
- ast_play_and_wait(chan, "vm-mailboxfull");
- ast_free(tmp);
- return -1;
- }
-
- /* Check if we have exceeded maxmsg */
- if (msgnum >= vmu->maxmsg) {
- ast_log(AST_LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
- ast_play_and_wait(chan, "vm-mailboxfull");
- ast_free(tmp);
- return -1;
- }
-#else
- if (count_messages(vmu, dir) >= vmu->maxmsg) {
- res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- ast_log(AST_LOG_WARNING, "No more messages possible\n");
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- goto leave_vm_out;
- }
-
-#endif
- snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
- txtdes = mkstemp(tmptxtfile);
- chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
- if (txtdes < 0) {
- res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
- if (!res)
- res = ast_waitstream(chan, "");
- ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- goto leave_vm_out;
- }
-
- /* Now play the beep once we have the message number for our next message. */
- if (res >= 0) {
- /* Unless we're *really* silent, try to send the beep */
- res = ast_stream_and_wait(chan, "beep", "");
- }
-
- /* Store information in real-time storage */
- if (ast_check_realtime("voicemail_data")) {
- snprintf(priority, sizeof(priority), "%d", chan->priority);
- snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL));
- get_date(date, sizeof(date));
- ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", S_OR(category,""), "filename", tmptxtfile, SENTINEL);
- }
-
- /* Store information */
- txt = fdopen(txtdes, "w+");
- if (txt) {
- get_date(date, sizeof(date));
- fprintf(txt,
- ";\n"
- "; Message Information file\n"
- ";\n"
- "[message]\n"
- "origmailbox=%s\n"
- "context=%s\n"
- "macrocontext=%s\n"
- "exten=%s\n"
- "priority=%d\n"
- "callerchan=%s\n"
- "callerid=%s\n"
- "origdate=%s\n"
- "origtime=%ld\n"
- "category=%s\n",
- ext,
- chan->context,
- chan->macrocontext,
- chan->exten,
- chan->priority,
- chan->name,
- ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
- date, (long)time(NULL),
- category ? category : "");
- } else
- ast_log(AST_LOG_WARNING, "Error opening text file for output\n");
-// res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag);
-
- if (txt) {
- fprintf(txt, "flag=%s\n", flag);
- if (duration < vmminsecs) {
- fclose(txt);
- if (option_verbose > 2)
- ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs);
- ast_filedelete(tmptxtfile, NULL);
- unlink(tmptxtfile);
- if (ast_check_realtime("voicemail_data")) {
- ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL);
- }
- } else {
- fprintf(txt, "duration=%d\n", duration);
- fclose(txt);
- if (vm_lock_path(dir)) {
- ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir);
- /* Delete files */
- ast_filedelete(tmptxtfile, NULL);
- unlink(tmptxtfile);
- } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
- ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
- unlink(tmptxtfile);
- ast_unlock_path(dir);
- if (ast_check_realtime("voicemail_data")) {
- ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL);
- }
- } else {
-#ifndef IMAP_STORAGE
- msgnum = last_message_index(vmu, dir) + 1;
-#endif
- make_file(fn, sizeof(fn), dir, msgnum);
-
- /* assign a variable with the name of the voicemail file */
-#ifndef IMAP_STORAGE
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
-#else
- pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
-#endif
-
- snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
- ast_filerename(tmptxtfile, fn, NULL);
- rename(tmptxtfile, txtfile);
-
- /* Properly set permissions on voicemail text descriptor file.
- Unfortunately mkstemp() makes this file 0600 on most unix systems. */
- if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0)
- ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno));
-
- ast_unlock_path(dir);
- if (ast_check_realtime("voicemail_data")) {
- snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
- ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL);
- }
- /* We must store the file first, before copying the message, because
- * ODBC storage does the entire copy with SQL.
- */
- if (ast_fileexists(fn, NULL, NULL) > 0) {
- STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag);
- }
-
- /* Are there to be more recipients of this message? */
- while (tmpptr) {
- struct ast_vm_user recipu, *recip;
- char *exten, *cntx;
-
- exten = strsep(&tmpptr, "&");
- cntx = strchr(exten, '@');
- if (cntx) {
- *cntx = '\0';
- cntx++;
- }
- if ((recip = find_user(&recipu, cntx, exten))) {
-// copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag);
- free_user(recip);
- }
- }
-#ifndef IMAP_STORAGE
- if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */
- /* Move the message from INBOX to Urgent folder if this is urgent! */
- char sfn[PATH_MAX];
- char dfn[PATH_MAX];
- int x;
- /* It's easier just to try to make it than to check for its existence */
- create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent");
- ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n",sfn,dfn);
- x = last_message_index(vmu, urgdir) + 1;
- make_file(sfn, sizeof(sfn), dir, msgnum);
- make_file(dfn, sizeof(dfn), urgdir, x);
- RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn);
- }
-#endif
- /* Notification needs to happen after the copy, though. */
- if (ast_fileexists(fn, NULL, NULL)) {
-#ifdef IMAP_STORAGE
- notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
-#else
- notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
-#endif
- }
-
- /* Disposal needs to happen after the optional move and copy */
- if (ast_fileexists(fn, NULL, NULL)) {
- DISPOSE(dir, msgnum);
- }
- }
- }
- }
- if (res == '0') {
- goto transfer;
- } else if (res > 0)
- res = 0;
-
- if (duration < vmminsecs)
- /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
- else
- pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
- } else
- ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n");
-leave_vm_out:
- free_user(vmu);
-
-#ifdef IMAP_STORAGE
- /* expunge message - use UID Expunge if supported on IMAP server*/
- ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n",expungeonhangup);
- if (expungeonhangup == 1) {
- ast_mutex_lock(&vms->lock);
-#ifdef HAVE_IMAP_TK2006
[... 63 lines stripped ...]
More information about the asterisk-commits
mailing list