[asterisk-commits] mmichelson: branch group/manager2 r115626 - in /team/group/manager2: ./ apps/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon May 12 10:01:49 CDT 2008


Author: mmichelson
Date: Mon May 12 10:01:48 2008
New Revision: 115626

URL: http://svn.digium.com/view/asterisk?view=rev&rev=115626
Log:
resolve and reset


Removed:
    team/group/manager2/contrib/scripts/postgres_cdr.sql
Modified:
    team/group/manager2/   (props changed)
    team/group/manager2/CHANGES
    team/group/manager2/UPGRADE.txt
    team/group/manager2/apps/app_jack.c
    team/group/manager2/apps/app_skel.c
    team/group/manager2/apps/app_voicemail.c
    team/group/manager2/cdr/cdr_pgsql.c
    team/group/manager2/channels/chan_h323.c
    team/group/manager2/channels/chan_iax2.c
    team/group/manager2/channels/chan_sip.c
    team/group/manager2/channels/chan_skinny.c
    team/group/manager2/channels/chan_unistim.c
    team/group/manager2/channels/chan_zap.c
    team/group/manager2/configs/queues.conf.sample
    team/group/manager2/configs/voicemail.conf.sample
    team/group/manager2/configure
    team/group/manager2/configure.ac
    team/group/manager2/contrib/init.d/rc.debian.asterisk
    team/group/manager2/contrib/scripts/asterisk.ldap-schema
    team/group/manager2/contrib/scripts/asterisk.ldif
    team/group/manager2/funcs/func_enum.c
    team/group/manager2/funcs/func_speex.c
    team/group/manager2/include/asterisk/app.h
    team/group/manager2/include/asterisk/autoconfig.h.in
    team/group/manager2/include/asterisk/dlinkedlists.h   (props changed)
    team/group/manager2/include/asterisk/enum.h
    team/group/manager2/main/app.c
    team/group/manager2/main/enum.c
    team/group/manager2/main/manager.c
    team/group/manager2/main/pbx.c
    team/group/manager2/main/sched.c
    team/group/manager2/res/res_config_ldap.c
    team/group/manager2/res/res_odbc.c
    team/group/manager2/sounds/Makefile

Propchange: team/group/manager2/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/group/manager2/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/manager2/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon May 12 10:01:48 2008
@@ -1,1 +1,1 @@
-/trunk:1-115477
+/trunk:1-115623

Modified: team/group/manager2/CHANGES
URL: http://svn.digium.com/view/asterisk/team/group/manager2/CHANGES?view=diff&rev=115626&r1=115625&r2=115626
==============================================================================
--- team/group/manager2/CHANGES (original)
+++ team/group/manager2/CHANGES Mon May 12 10:01:48 2008
@@ -42,6 +42,11 @@
    quite helpful.
  * Voicemail now permits a mailbox setting to wrap around from first to last
    messages, if the "messagewrap" option is set to a true value.
+ * Voicemail now permits an external script to be run, for password validation.
+   The script should output "VALID" or "INVALID" on stdout, depending upon the
+   wish to validate or invalidate the password given.  Arguments are:
+   "mailbox" "context" "oldpass" "newpass".  See the sample voicemail.conf for
+   more details
  * Dial has a new option: F(context^extension^pri), which permits a callee to
    continue in the dialplan, at the specified label, if the caller hangs up.
  * ChanSpy and ExtenSpy have a new option, 's' which suppresses speaking the
@@ -96,6 +101,12 @@
 Dialplan function changes
 -------------------------
  * TIMEOUT() has been modified to be accurate down to the millisecond.
+ * ENUM*() functions now include the following new options:
+     - 'u' returns the full URI and does not strip off the URI-scheme.
+	 - 's' triggers ISN specific rewriting
+	 - 'i' looks for branches into an Infrastructure ENUM tree
+	 - 'd' for a direct DNS lookup without any flipping of digits.
+ * TXCIDNAME() has a new zone-suffix parameter (which defaults to 'e164.arpa')
 
 AMI - The manager (TCP/TLS/HTTP)
 --------------------------------
@@ -406,6 +417,12 @@
      voicemail boxes.  The SMDI interface can also poll for MWI changes when some
      outside entity is modifying the state of the mailbox (such as IMAP storage or
      a web interface of some kind).
+  * Added the support for marking messages as "urgent." There are two methods to accomplish
+     this. One is to pass the 'U' option to VoiceMail(). Another way to mark a message as urgent
+	 is to specify "review=yes" in voicemail.conf. Doing this will cause allow the user to mark
+	 the message as urgent after he has recorded a voicemail by following the voice instructions.
+	When listening to voicemails using VoiceMailMain urgent messages will be presented before other
+	 messages
 
 Queue changes
 -------------

Modified: team/group/manager2/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/group/manager2/UPGRADE.txt?view=diff&rev=115626&r1=115625&r2=115626
==============================================================================
--- team/group/manager2/UPGRADE.txt (original)
+++ team/group/manager2/UPGRADE.txt Mon May 12 10:01:48 2008
@@ -74,6 +74,8 @@
   checking mailboxes for changes so that they can send MWI information to users.
   Examples of situations that would require this option are web interfaces to
   voicemail or an email client in the case of using IMAP storage.
+* The externnotify script should accept an additional (last) parameter
+  containing the string "URGENT" if there are new urgent messages in the INBOX.
 
 Applications:
 

Modified: team/group/manager2/apps/app_jack.c
URL: http://svn.digium.com/view/asterisk/team/group/manager2/apps/app_jack.c?view=diff&rev=115626&r1=115625&r2=115626
==============================================================================
--- team/group/manager2/apps/app_jack.c (original)
+++ team/group/manager2/apps/app_jack.c Mon May 12 10:01:48 2008
@@ -977,15 +977,12 @@
 
 static int load_module(void)
 {
-	if (ast_register_application(jack_app, jack_exec, jack_synopsis, jack_desc))
-		return AST_MODULE_LOAD_DECLINE;
-
-	if (ast_custom_function_register(&jack_hook_function)) {
-		ast_unregister_application(jack_app);
-		return AST_MODULE_LOAD_DECLINE;
-	}
-
-	return AST_MODULE_LOAD_SUCCESS;
+	int res = 0;
+
+	res |= ast_register_application(jack_app, jack_exec, jack_synopsis, jack_desc);
+	res |= ast_custom_function_register(&jack_hook_function);
+
+	return res;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "JACK Interface");

Modified: team/group/manager2/apps/app_skel.c
URL: http://svn.digium.com/view/asterisk/team/group/manager2/apps/app_skel.c?view=diff&rev=115626&r1=115625&r2=115626
==============================================================================
--- team/group/manager2/apps/app_skel.c (original)
+++ team/group/manager2/apps/app_skel.c Mon May 12 10:01:48 2008
@@ -109,17 +109,12 @@
 
 static int unload_module(void)
 {
-	int res;
-	res = ast_unregister_application(app);
-	return res;	
+	return ast_unregister_application(app);
 }
 
 static int load_module(void)
 {
-	if (ast_register_application(app, app_exec, synopsis, descrip))
-		return AST_MODULE_LOAD_DECLINE;
-
-	return AST_MODULE_LOAD_SUCCESS;
+	return ast_register_application(app, app_exec, synopsis, descrip);
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Skeleton (sample) Application");

Modified: team/group/manager2/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/group/manager2/apps/app_voicemail.c?view=diff&rev=115626&r1=115625&r2=115626
==============================================================================
--- team/group/manager2/apps/app_voicemail.c (original)
+++ team/group/manager2/apps/app_voicemail.c Mon May 12 10:01:48 2008
@@ -155,11 +155,11 @@
 static void get_mailbox_delimiter(MAILSTREAM *stream);
 static void mm_parsequota (MAILSTREAM *stream, unsigned char *msg, QUOTALIST *pquota);
 static void imap_mailbox_name(char *spec, size_t len, struct vm_state *vms, int box, int target);
-static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, char *introfile);
+static int imap_store_file(char *dir, char *mailboxuser, char *mailboxcontext, int msgnum, struct ast_channel *chan, struct ast_vm_user *vmu, char *fmt, int duration, struct vm_state *vms, char *introfile, const char *flag);
 static void update_messages_by_imapuser(const char *user, unsigned long number);
 
 static int imap_remove_file (char *dir, int msgnum);
-static int imap_retrieve_file (char *dir, int msgnum, const char *mailbox, char *context);
+static int imap_retrieve_file (char *dir, int msgnum, const char *mailbox, const char *context);
 static int imap_delete_old_greeting (char *dir, struct vm_state *vms);
 static void check_quota(struct vm_state *vms, char *mailbox);
 static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box);
@@ -201,6 +201,8 @@
 
 #define MAXMSG 100
 #define MAXMSGLIMIT 9999
+
+#define MINPASSWORD 0 /*!< Default minimum mailbox password length */
 
 #define BASELINELEN 72
 #define BASEMAXINLINE 256
@@ -228,7 +230,6 @@
 #define VM_MOVEHEARD     (1 << 16)  /*!< Move a "heard" message to Old after listening to it */
 #define VM_MESSAGEWRAP   (1 << 17)  /*!< Wrap around from the last message to the first, and vice-versa */
 #define ERROR_LOCK_PATH  -100
-#define ERROR_MAILBOX_FULL	-200
 
 
 enum {
@@ -248,6 +249,8 @@
 	OPT_PREPEND_MAILBOX =  (1 << 4),
 	OPT_AUTOPLAY =         (1 << 6),
 	OPT_DTMFEXIT =         (1 << 7),
+	OPT_MESSAGE_Urgent =   (1 << 8),
+	OPT_MESSAGE_PRIORITY = (1 << 9)
 } vm_option_flags;
 
 enum {
@@ -266,6 +269,8 @@
 	AST_APP_OPTION_ARG('d', OPT_DTMFEXIT, OPT_ARG_DTMFEXIT),
 	AST_APP_OPTION('p', OPT_PREPEND_MAILBOX),
 	AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),
+	AST_APP_OPTION('U', OPT_MESSAGE_Urgent),
+	AST_APP_OPTION('P', OPT_MESSAGE_PRIORITY)
 });
 
 static int load_config(int reload);
@@ -422,6 +427,7 @@
 	int lastmsg;
 	int newmessages;
 	int oldmessages;
+	int urgentmessages;
 	int starting;
 	int repeats;
 #ifdef IMAP_STORAGE
@@ -443,7 +449,7 @@
 static char odbc_table[80];
 #define RETRIEVE(a,b,c,d) retrieve_file(a,b)
 #define DISPOSE(a,b) remove_file(a,b)
-#define STORE(a,b,c,d,e,f,g,h,i,j) store_file(a,b,c,d)
+#define STORE(a,b,c,d,e,f,g,h,i,j,k) store_file(a,b,c,d)
 #define EXISTS(a,b,c,d) (message_exists(a,b))
 #define RENAME(a,b,c,d,e,f,g,h) (rename_file(a,b,c,d,e,f))
 #define COPY(a,b,c,d,e,f,g,h) (copy_file(a,b,c,d,e,f))
@@ -452,8 +458,8 @@
 #ifdef IMAP_STORAGE
 #define RETRIEVE(a,b,c,d) (imap_retrieve_file(a,b,c,d ))
 #define DISPOSE(a,b) (imap_remove_file(a,b))
-#define STORE(a,b,c,d,e,f,g,h,i,j) (imap_store_file(a,b,c,d,e,f,g,h,i,j))
-#define EXISTS(a,b,c,d) (ast_fileexists(c, NULL, d) > 0)
+#define STORE(a,b,c,d,e,f,g,h,i,j,k) (imap_store_file(a,b,c,d,e,f,g,h,i,j,k))
+#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0)
 #define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h));
 #define COPY(a,b,c,d,e,f,g,h) (copy_file(g,h));
 #define IMAP_DELETE(a,b,c,d) (vm_imap_delete(b,d))
@@ -461,10 +467,10 @@
 #else
 #define RETRIEVE(a,b,c,d)
 #define DISPOSE(a,b)
-#define STORE(a,b,c,d,e,f,g,h,i,j)
-#define EXISTS(a,b,c,d) (ast_fileexists(c, NULL, d) > 0)
+#define STORE(a,b,c,d,e,f,g,h,i,j,k)
+#define EXISTS(a,b,c,d) (ast_fileexists(c,NULL,d) > 0)
 #define RENAME(a,b,c,d,e,f,g,h) (rename_file(g,h));
-#define COPY(a,b,c,d,e,f,g,h) (copy_plain_file(g,h));
+#define COPY(a,b,c,d,e,f,g,h) (copy_plain_file(g,h)); 
 #define DELETE(a,b,c) (vm_delete(c))
 #endif
 #endif
@@ -472,6 +478,7 @@
 static char VM_SPOOL_DIR[PATH_MAX];
 
 static char ext_pass_cmd[128];
+static char ext_pass_check_cmd[128];
 
 int my_umask;
 
@@ -510,14 +517,16 @@
 	"               application. The possible values are:\n"
 	"               SUCCESS | USEREXIT | FAILED\n\n"
 	"  Options:\n"
-	"    b      - Play the 'busy' greeting to the calling party.\n"
+	"    b    - Play the 'busy' greeting to the calling party.\n"
 	"    d([c]) - Accept digits for a new extension in context c, if played during\n"
 	"             the greeting.  Context defaults to the current context.\n"
-	"    g(#)   - Use the specified amount of gain when recording the voicemail\n"
-	"             message. The units are whole-number decibels (dB).\n"
-	"    s      - Skip the playback of instructions for leaving a message to the\n"
-	"             calling party.\n"
-	"    u      - Play the 'unavailable' greeting.\n";
+	"    g(#) - Use the specified amount of gain when recording the voicemail\n"
+	"           message. The units are whole-number decibels (dB).\n"
+	"    s    - Skip the playback of instructions for leaving a message to the\n"
+	"           calling party.\n"
+	"    u    - Play the 'unavailable' greeting.\n"
+	"    U    - Mark message as Urgent.\n"
+	"    P    - Mark message as PRIORITY.\n";
 
 static char *synopsis_vmain = "Check Voicemail messages";
 
@@ -587,6 +596,7 @@
 static int maxgreet;
 static int skipms;
 static int maxlogins;
+static int minpassword;
 
 /*! Poll mailboxes for changes since there is something external to
  *  app_voicemail that may change them. */
@@ -616,6 +626,7 @@
  */
 struct mwi_sub {
 	AST_RWLIST_ENTRY(mwi_sub) entry;
+	int old_urgent;
 	int old_new;
 	int old_old;
 	uint32_t uniqueid;
@@ -645,6 +656,7 @@
 static char vm_passchanged[80] = "vm-passchanged";
 static char vm_reenterpassword[80] = "vm-reenterpassword";
 static char vm_mismatch[80] = "vm-mismatch";
+static char vm_invalid_password[80] = "vm-invalid-password";
 
 static struct ast_flags globalflags = {0};
 
@@ -676,11 +688,11 @@
 static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context);
 static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime,
 			char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir,
-			signed char record_gain, struct vm_state *vms);
+			signed char record_gain, struct vm_state *vms, char *flag);
 static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain);
 static int vm_play_folder_name(struct ast_channel *chan, char *mbox);
-static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname);
-static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap);
+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);
+static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag);
 static void apply_options(struct ast_vm_user *vmu, const char *options);
 static int add_email_attachment(FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum);
 static int is_valid_dtmf(const char *key);
@@ -748,33 +760,33 @@
 #endif
 	} else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
 		ast_set2_flag(vmu, ast_true(value), VM_DELETE);	
-	} else if (!strcasecmp(var, "saycid")) {
+	} else if (!strcasecmp(var, "saycid")){
 		ast_set2_flag(vmu, ast_true(value), VM_SAYCID);	
-	} else if (!strcasecmp(var, "sendvoicemail")) {
+	} else if (!strcasecmp(var,"sendvoicemail")){
 		ast_set2_flag(vmu, ast_true(value), VM_SVMAIL);	
-	} else if (!strcasecmp(var, "review")) {
+	} else if (!strcasecmp(var, "review")){
 		ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
-	} else if (!strcasecmp(var, "tempgreetwarn")) {
+	} else if (!strcasecmp(var, "tempgreetwarn")){
 		ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);	
 	} else if (!strcasecmp(var, "messagewrap")){
 		ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP);	
 	} else if (!strcasecmp(var, "operator")) {
 		ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);	
-	} else if (!strcasecmp(var, "envelope")) {
+	} else if (!strcasecmp(var, "envelope")){
 		ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);	
-	} else if (!strcasecmp(var, "moveheard")) {
+	} else if (!strcasecmp(var, "moveheard")){
 		ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD);
-	} else if (!strcasecmp(var, "sayduration")) {
+	} else if (!strcasecmp(var, "sayduration")){
 		ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);	
-	} else if (!strcasecmp(var, "saydurationm")) {
+	} else if (!strcasecmp(var, "saydurationm")){
 		if (sscanf(value, "%d", &x) == 1) {
 			vmu->saydurationm = x;
 		} else {
 			ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n");
 		}
-	} else if (!strcasecmp(var, "forcename")) {
+	} else if (!strcasecmp(var, "forcename")){
 		ast_set2_flag(vmu, ast_true(value), VM_FORCENAME);	
-	} else if (!strcasecmp(var, "forcegreetings")) {
+	} else if (!strcasecmp(var, "forcegreetings")){
 		ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);	
 	} else if (!strcasecmp(var, "callback")) {
 		ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
@@ -820,6 +832,85 @@
 	} else if (!strcasecmp(var, "options")) {
 		apply_options(vmu, value);
 	}
+}
+
+static char *vm_check_password_shell(char *command, char *buf, size_t len) 
+{
+	int fds[2], pid = 0;
+
+	memset(buf, 0, len);
+
+	if (pipe(fds)) {
+		snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno));
+	} else {
+		/* good to go*/
+		pid = ast_safe_fork(0);
+
+		if (pid < 0) {
+			/* ok maybe not */
+			close(fds[0]);
+			close(fds[1]);
+			snprintf(buf, len, "FAILURE: Fork failed");
+		} else if (pid) {
+			/* parent */
+			close(fds[1]);
+			read(fds[0], buf, len);
+			close(fds[0]);
+		} else {
+			/*  child */
+			AST_DECLARE_APP_ARGS(arg,
+				AST_APP_ARG(v)[20];
+			);
+			char *mycmd = ast_strdupa(command);
+
+			close(fds[0]);
+			dup2(fds[1], STDOUT_FILENO);
+			close(fds[1]);
+			ast_close_fds_above_n(STDOUT_FILENO);
+
+			AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' ');
+
+			execv(arg.v[0], arg.v); 
+			printf("FAILURE: %s", strerror(errno));
+			_exit(0);
+		}
+	}
+	return buf;
+}
+
+/*!
+ * \brief Check that password meets minimum required length
+ * \param vmu The voicemail user to change the password for.
+ * \param password The password string to check
+ *
+ * \return zero on ok, 1 on not ok.
+ */
+static int check_password(struct ast_vm_user *vmu, char *password)
+{
+	/* check minimum length */
+	if (strlen(password) < minpassword)
+		return 1;
+	if (!ast_strlen_zero(ext_pass_check_cmd)) {
+		char cmd[255], buf[255];
+
+		ast_log(LOG_DEBUG, "Verify password policies for %s\n", password);
+
+		snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password);
+		if (vm_check_password_shell(cmd, buf, sizeof(buf))) {
+			ast_debug(5, "Result: %s\n", buf);
+			if (!strncasecmp(buf, "VALID", 5)) {
+				ast_debug(3, "Passed password check: '%s'\n", buf);
+				return 0;
+			} else if (!strncasecmp(buf, "FAILURE", 7)) {
+				ast_log(LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf);
+				return 0;
+			} else {
+				ast_log(LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password);
+				return 1;
+			}
+		}
+	}
+	return 0;
 }
 
 /*! 
@@ -974,7 +1065,7 @@
 static struct ast_vm_user *find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
 {
 	/* This function could be made to generate one from a database, too */
-	struct ast_vm_user *vmu = NULL, *cur;
+	struct ast_vm_user *vmu=NULL, *cur;
 	AST_LIST_LOCK(&users);
 
 	if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
@@ -1037,11 +1128,11 @@
  */
 static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
 {
-	struct ast_config *cfg = NULL;
-	struct ast_variable *var = NULL;
-	struct ast_category *cat = NULL;
-	char *category = NULL, *value = NULL, *new = NULL;
-	const char *tmp = NULL;
+	struct ast_config   *cfg=NULL;
+	struct ast_variable *var=NULL;
+	struct ast_category *cat=NULL;
+	char *category=NULL, *value=NULL, *new=NULL;
+	const char *tmp=NULL;
 	struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
 	if (!change_password_realtime(vmu, newpassword))
 		return;
@@ -1054,13 +1145,13 @@
 					ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n");
 					break;
 				}
-				value = strstr(tmp, ",");
+				value = strstr(tmp,",");
 				if (!value) {
 					ast_log(AST_LOG_WARNING, "variable has bad format.\n");
 					break;
 				}
-				new = alloca(strlen(value) + strlen(newpassword) + 1);
-				sprintf(new, "%s%s", newpassword, value);
+				new = alloca((strlen(value)+strlen(newpassword)+1));
+				sprintf(new,"%s%s", newpassword, value);
 				if (!(cat = ast_category_get(cfg, category))) {
 					ast_log(AST_LOG_WARNING, "Failed to get category structure.\n");
 					break;
@@ -1086,7 +1177,7 @@
 					ast_debug(3, "looks like we need to make vmsecret!\n");
 					var = ast_variable_new("vmsecret", newpassword, "");
 				} 
-				new = alloca(strlen(newpassword) + 1);
+				new = alloca(strlen(newpassword)+1);
 				sprintf(new, "%s", newpassword);
 				if (!(cat = ast_category_get(cfg, category))) {
 					ast_debug(4, "failed to get category!\n");
@@ -1108,7 +1199,7 @@
 static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
 {
 	char buf[255];
-	snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword);
+	snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
 	if (!ast_safe_system(buf)) {
 		ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
 		/* Reset the password in memory, too */
@@ -1155,10 +1246,10 @@
 		ast_log(AST_LOG_WARNING, "msgnum %d, mailbox message %lu is zero.\n", msgnum, messageNum);
 		return;
 	}
-	ast_debug(3, "deleting msgnum %d, which is mailbox message %lu\n", msgnum, messageNum);
+	ast_debug(3, "deleting msgnum %d, which is mailbox message %lu\n",msgnum,messageNum);
 	/* delete message */
-	snprintf(arg, sizeof(arg), "%lu", messageNum);
-	mail_setflag(vms->mailstream, arg, "\\DELETED");
+	snprintf (arg, sizeof(arg), "%lu",messageNum);
+	mail_setflag (vms->mailstream,arg,"\\DELETED");
 }
 
 #endif
@@ -1251,13 +1342,13 @@
 {
 	int x = 0;
 	int res;
-	int fd = -1;
+	int fd=-1;
 	size_t fdlen = 0;
 	void *fdm = MAP_FAILED;
-	SQLSMALLINT colcount = 0;
+	SQLSMALLINT colcount=0;
 	SQLHSTMT stmt;
 	char sql[PATH_MAX];
-	char fmt[80] = "";
+	char fmt[80]="";
 	char *c;
 	char coltitle[256];
 	SQLSMALLINT collen;
@@ -1266,7 +1357,7 @@
 	SQLSMALLINT nullable;
 	SQLULEN colsize;
 	SQLLEN colsize2;
-	FILE *f = NULL;
+	FILE *f=NULL;
 	char rowdata[80];
 	char fn[PATH_MAX];
 	char full_fn[PATH_MAX];
@@ -1283,8 +1374,7 @@
 			*c = '\0';
 		if (!strcasecmp(fmt, "wav49"))
 			strcpy(fmt, "WAV");
-
-		snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
+		snprintf(msgnums, sizeof(msgnums),"%d", msgnum);
 		if (msgnum > -1)
 			make_file(fn, sizeof(fn), dir, msgnum);
 		else
@@ -1299,7 +1389,7 @@
 		}
 		
 		snprintf(full_fn, sizeof(full_fn), "%s.%s", fn, fmt);
-		snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?", odbc_table);
+		snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE dir=? AND msgnum=?",odbc_table);
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt) {
 			ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1333,7 +1423,7 @@
 		}
 		if (f) 
 			fprintf(f, "[message]\n");
-		for (x = 0; x < colcount; x++) {
+		for (x=0;x<colcount;x++) {
 			rowdata[0] = '\0';
 			collen = sizeof(coltitle);
 			res = SQLDescribeCol(stmt, x + 1, (unsigned char *)coltitle, sizeof(coltitle), &collen, 
@@ -1349,7 +1439,7 @@
 				res = SQLGetData(stmt, x + 1, SQL_BINARY, rowdata, 0, &colsize2);
 				fdlen = colsize2;
 				if (fd > -1) {
-					char tmp[1] = "";
+					char tmp[1]="";
 					lseek(fd, fdlen - 1, SEEK_SET);
 					if (write(fd, tmp, 1) != 1) {
 						close(fd);
@@ -1380,7 +1470,7 @@
 			} else {
 				res = SQLGetData(stmt, x + 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
 				if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
-					ast_log(AST_LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
+					ast_log(AST_LOG_WARNING, "SQL Get Data error! coltitle=%s\n[%s]\n\n", coltitle, sql);
 					SQLFreeHandle (SQL_HANDLE_STMT, stmt);
 					ast_odbc_release_obj(obj);
 					goto yuck;
@@ -1455,7 +1545,7 @@
 	struct odbc_obj *obj;
 	obj = ast_odbc_request_obj(odbc_database, 0);
 	if (obj) {
-		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?", odbc_table);
+		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=?",odbc_table);
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt) {
 			ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1510,7 +1600,7 @@
 	obj = ast_odbc_request_obj(odbc_database, 0);
 	if (obj) {
 		snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
-		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?", odbc_table);
+		snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s WHERE dir=? AND msgnum=?",odbc_table);
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt) {
 			ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1580,7 +1670,7 @@
 	obj = ast_odbc_request_obj(odbc_database, 0);
 	if (obj) {
 		snprintf(msgnums, sizeof(msgnums), "%d", smsg);
-		snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?", odbc_table);
+		snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE dir=? AND msgnum=?",odbc_table);
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt)
 			ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1618,7 +1708,7 @@
 	if (obj) {
 		snprintf(msgnums, sizeof(msgnums), "%d", smsg);
 		snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);
-		snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, context, macrocontext, callerid, origtime, duration, recording, mailboxuser, mailboxcontext) SELECT ?,?,context,macrocontext,callerid,origtime,duration,recording,?,? FROM %s WHERE dir=? AND msgnum=?", odbc_table, odbc_table);
+		snprintf(sql, sizeof(sql), "INSERT INTO %s (dir, msgnum, context, macrocontext, callerid, origtime, duration, recording, mailboxuser, mailboxcontext, flag) SELECT ?,?,context,macrocontext,callerid,origtime,duration,recording,flag,?,? FROM %s WHERE dir=? AND msgnum=?",odbc_table,odbc_table);
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt)
 			ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s] (You probably don't have MySQL 4.1 or later installed)\n\n", sql);
@@ -1644,6 +1734,7 @@
 	char *mailboxuser;
 	char *mailboxcontext;
 	const char *category;
+	const char *flag;
 };
 
 static SQLHSTMT insert_data_cb(struct odbc_obj *obj, void *vdata)
@@ -1670,8 +1761,9 @@
 	SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->duration), 0, (void *)data->duration, 0, NULL);
 	SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->mailboxuser), 0, (void *)data->mailboxuser, 0, NULL);
 	SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->mailboxcontext), 0, (void *)data->mailboxcontext, 0, NULL);
+	SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->flag), 0, (void *)data->flag, 0, NULL);
 	if (!ast_strlen_zero(data->category)) {
-		SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->category), 0, (void *)data->category, 0, NULL);
+		SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(data->category), 0, (void *)data->category, 0, NULL);
 	}
 	res = SQLExecDirect(stmt, (unsigned char *)data->sql, SQL_NTS);
 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
@@ -1707,9 +1799,9 @@
 	char msgnums[20];
 	char fn[PATH_MAX];
 	char full_fn[PATH_MAX];
-	char fmt[80] = "";
+	char fmt[80]="";
 	char *c;
-	struct ast_config *cfg = NULL;
+	struct ast_config *cfg=NULL;
 	struct odbc_obj *obj;
 	struct insert_data idata = { .sql = sql, .msgnums = msgnums, .dir = dir, .mailboxuser = mailboxuser, .mailboxcontext = mailboxcontext };
 	struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
@@ -1727,7 +1819,7 @@
 			*c = '\0';
 		if (!strcasecmp(fmt, "wav49"))
 			strcpy(fmt, "WAV");
-		snprintf(msgnums, sizeof(msgnums), "%d", msgnum);
+		snprintf(msgnums, sizeof(msgnums),"%d", msgnum);
 		if (msgnum > -1)
 			make_file(fn, sizeof(fn), dir, msgnum);
 		else
@@ -1760,11 +1852,14 @@
 			if (!(idata.category = ast_variable_retrieve(cfg, "message", "category"))) {
 				idata.category = "";
 			}
+			if (!(idata.flag = ast_variable_retrieve(cfg, "message", "flag"))) {
+				idata.flag = "";
+			}
 		}
 		fdlen = lseek(fd, 0, SEEK_END);
 		lseek(fd, 0, SEEK_SET);
 		printf("Length is %zd\n", fdlen);
-		fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+		fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
 		if (fdm == MAP_FAILED) {
 			ast_log(AST_LOG_WARNING, "Memory map failed!\n");
 			res = -1;
@@ -1774,9 +1869,9 @@
 		idata.datalen = fdlen;
 
 		if (!ast_strlen_zero(idata.category)) 
-			snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,category) VALUES (?,?,?,?,?,?,?,?,?,?,?)", odbc_table);
+			snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag,category) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",odbc_table); 
 		else
-			snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext) VALUES (?,?,?,?,?,?,?,?,?,?)", odbc_table);
+			snprintf(sql, sizeof(sql), "INSERT INTO %s (dir,msgnum,recording,context,macrocontext,callerid,origtime,duration,mailboxuser,mailboxcontext,flag) VALUES (?,?,?,?,?,?,?,?,?,?,?)",odbc_table);
 
 		if ((stmt = ast_odbc_direct_execute(obj, insert_data_cb, &idata))) {
 			SQLFreeHandle (SQL_HANDLE_STMT, stmt);
@@ -1825,7 +1920,7 @@
 	if (obj) {
 		snprintf(msgnums, sizeof(msgnums), "%d", smsg);
 		snprintf(msgnumd, sizeof(msgnumd), "%d", dmsg);
-		snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?", odbc_table);
+		snprintf(sql, sizeof(sql), "UPDATE %s SET dir=?, msgnum=?, mailboxuser=?, mailboxcontext=? WHERE dir=? AND msgnum=?",odbc_table);
 		stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
 		if (!stmt)
 			ast_log(AST_LOG_WARNING, "SQL Execute error!\n[%s]\n\n", sql);
@@ -1860,8 +1955,9 @@
 
 	if ((vmdir = opendir(dir))) {
 		while ((vment = readdir(vmdir))) {
-			if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
+			if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) {
 				vmcount++;
+			}
 		}
 		closedir(vmdir);
 	}
@@ -1881,7 +1977,7 @@
 {
 	char stxt[PATH_MAX];
 	char dtxt[PATH_MAX];
-	ast_filerename(sfn, dfn, NULL);
+	ast_filerename(sfn,dfn,NULL);
 	snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
 	snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
 	if (ast_check_realtime("voicemail_data")) {
@@ -1889,9 +1985,7 @@
 	}
 	rename(stxt, dtxt);
 }
-#endif
-
-#ifndef IMAP_STORAGE
+
 /*! 
  * \brief Determines the highest message number in use for a given user and mailbox folder.
  * \param vmu 
@@ -1930,8 +2024,6 @@
 	return x - 1;
 }
 
-#endif /* #ifndef IMAP_STORAGE */
-#endif /* #else of #ifdef ODBC_STORAGE */
 
 /*!
  * \brief Utility function to copy a file.
@@ -2005,7 +2097,7 @@
 static void copy_plain_file(char *frompath, char *topath)
 {
 	char frompath2[PATH_MAX], topath2[PATH_MAX];
-	struct ast_variable *tmp, *var = NULL;
+	struct ast_variable *tmp,*var = NULL;
 	const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL;
 	ast_filecopy(frompath, topath, NULL);
 	snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
@@ -2044,6 +2136,9 @@
 	ast_variables_destroy(var);
 }
 
+#endif /* #ifndef IMAP_STORAGE */
+#endif /* #else of #ifdef ODBC_STORAGE */
+#ifndef ODBC_STORAGE
 /*! 
  * \brief Removes the voicemail sound and information file.
  * \param file The path to the sound file. This will be the the folder and message index, without the extension.
@@ -2057,7 +2152,7 @@
 	char *txt;
 	int txtsize = 0;
 
-	txtsize = (strlen(file) + 5) * sizeof(char);
+	txtsize = (strlen(file) + 5)*sizeof(char);
 	txt = alloca(txtsize);
 	/* Sprintf here would safe because we alloca'd exactly the right length,
 	 * but trying to eliminate all sprintf's anyhow
@@ -2069,6 +2164,7 @@
 	unlink(txt);
 	return ast_filedelete(file, NULL);
 }
+#endif
 
 /*!
  * \brief utility used by inchar(), for base_encode()
@@ -2080,7 +2176,7 @@
 	if (bio->ateof)
 		return 0;
 
-	if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) {
+	if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
 		if (ferror(fi))
 			return -1;
 
@@ -2088,8 +2184,8 @@
 		return 0;
 	}
 
-	bio->iolen = l;
-	bio->iocp = 0;
+	bio->iolen= l;
+	bio->iocp= 0;
 
 	return 1;
 }
@@ -2099,7 +2195,7 @@
  */
 static int inchar(struct baseio *bio, FILE *fi)
 {
-	if (bio->iocp >= bio->iolen) {
+	if (bio->iocp>=bio->iolen) {
 		if (!inbuf(bio, fi))
 			return EOF;
 	}
@@ -2113,13 +2209,13 @@
 static int ochar(struct baseio *bio, int c, FILE *so)
 {
 	if (bio->linelength >= BASELINELEN) {
-		if (fputs(eol, so) == EOF)
+		if (fputs(eol,so) == EOF)
 			return -1;
 
 		bio->linelength= 0;
 	}
 
-	if (putc(((unsigned char)c), so) == EOF)
+	if (putc(((unsigned char)c),so) == EOF)
 		return -1;
 
 	bio->linelength++;
@@ -2142,7 +2238,7 @@
 		'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
 		'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
 		'1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
-	int i, hiteof = 0;
+	int i,hiteof= 0;
 	FILE *fi;
 	struct baseio bio;
 
@@ -2154,48 +2250,48 @@
 		return -1;
 	}
 
-	while (!hiteof) {
+	while (!hiteof){
 		unsigned char igroup[3], ogroup[4];
-		int c, n;
-
-		igroup[0] = igroup[1] = igroup[2] = 0;
-
-		for (n = 0; n < 3; n++) {
+		int c,n;
+
+		igroup[0]= igroup[1]= igroup[2]= 0;
+
+		for (n= 0;n<3;n++) {
 			if ((c = inchar(&bio, fi)) == EOF) {
-				hiteof = 1;
+				hiteof= 1;
 				break;
 			}
 
-			igroup[n] = (unsigned char)c;
-		}
-
-		if (n > 0) {
-			ogroup[0] = dtable[igroup[0] >> 2];
-			ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
-			ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
-			ogroup[3] = dtable[igroup[2] & 0x3F];
-
-			if (n < 3) {
-				ogroup[3] = '=';
-
-				if (n < 2)
-					ogroup[2] = '=';
-			}
-
-			for (i = 0; i < 4; i++)
+			igroup[n]= (unsigned char)c;
+		}
+
+		if (n> 0) {
+			ogroup[0]= dtable[igroup[0]>>2];
+			ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)];
+			ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)];
+			ogroup[3]= dtable[igroup[2]&0x3F];
+
+			if (n<3) {
+				ogroup[3]= '=';
+
+				if (n<2)
+					ogroup[2]= '=';
+			}
+
+			for (i= 0;i<4;i++)
 				ochar(&bio, ogroup[i], so);
 		}
 	}
 
 	fclose(fi);
 	
-	if (fputs(eol, so) == EOF)
+	if (fputs(eol,so)==EOF)
 		return 0;
 
 	return 1;
 }
 
-static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category)
+static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category, const char *flag)
 {
 	char callerid[256];
 	/* Prepare variables for substitution in email body and subject */
@@ -2210,6 +2306,7 @@
 	pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
 	pbx_builtin_setvar_helper(ast, "VM_DATE", date);
 	pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
+	pbx_builtin_setvar_helper(ast, "VM_FLAG", flag);
 }
 
 /*!
@@ -2295,7 +2392,7 @@
  *
  * The email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email.  That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function.
  */
-static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
+static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag)
 {
 	char date[256];
 	char host[MAXHOSTNAMELEN] = "";
@@ -2314,7 +2411,7 @@
 #define ENDL "\n"
 #endif
 
-	gethostname(host, sizeof(host) - 1);
+	gethostname(host, sizeof(host)-1);
 
 	if (strchr(srcemail, '@'))
 		ast_copy_string(who, srcemail, sizeof(who));
@@ -2336,10 +2433,10 @@
 		struct ast_channel *ast;
 		if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
 			char *passdata;
-			int vmlen = strlen(fromstring) * 3 + 200;
+			int vmlen = strlen(fromstring)*3 + 200;
 			passdata = alloca(vmlen);
 			memset(passdata, 0, vmlen);
-			prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
+			prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
 			pbx_substitute_variables_helper(ast, fromstring, passdata, vmlen);
 			len_passdata = strlen(passdata) * 2 + 3;
 			passdata2 = alloca(len_passdata);
@@ -2359,16 +2456,26 @@
 			int vmlen = strlen(emailsubject) * 3 + 200;
 			passdata = alloca(vmlen);
 			memset(passdata, 0, vmlen);
-			prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
+			prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category, flag);
 			pbx_substitute_variables_helper(ast, emailsubject, passdata, vmlen);
 			fprintf(p, "Subject: %s" ENDL, passdata);
 			ast_channel_free(ast);
 		} else
 			ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
-	} else if (ast_test_flag((&globalflags), VM_PBXSKIP))
-		fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
-	else
-		fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
+	} else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
+		if (ast_strlen_zero(flag)) {
+			fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
+		} else {
+			fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox);
+		}
+	} else {
+		if (ast_strlen_zero(flag)) {

[... 6668 lines stripped ...]



More information about the asterisk-commits mailing list