[svn-commits] brushtyler: branch brushtyler/voicemail_menu_branch r213785 - /team/brushtyle...

SVN commits to the Digium repositories svn-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 svn-commits mailing list