Tue Apr 28 22:50:18 2009

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

#include "asterisk.h"
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
struct  users
struct  vm_state
struct  vm_zone
struct  zones

Defines

#define ASTERISK_USERNAME   "asterisk"
#define BASELINELEN   72
#define BASEMAXINLINE   256
#define BASEMAXINLINE   256
#define CHUNKSIZE   65536
#define COMMAND_TIMEOUT   5000
#define COPY(a, b, c, d, e, f, g, h)   (copy_plain_file(g,h));
#define DELETE(a, b, c, d)   (vm_delete(c))
#define DISPOSE(a, b)
#define ENDL   "\n"
#define eol   "\r\n"
#define ERROR_LOCK_PATH   -100
#define ERROR_MAILBOX_FULL   -200
#define EXISTS(a, b, c, d)   (ast_fileexists(c,NULL,d) > 0)
#define INTRO   "vm-intro"
#define MAX_DATETIME_FORMAT   512
#define MAX_NUM_CID_CONTEXTS   10
#define MAXMSG   100
#define MAXMSGLIMIT   9999
#define RENAME(a, b, c, d, e, f, g, h)   (rename_file(g,h));
#define RETRIEVE(a, b, c)
#define SENDMAIL   "/usr/sbin/sendmail -t"
#define SMDI_MWI_WAIT_TIMEOUT   1000
#define STORE(a, b, c, d, e, f, g, h, i)
#define tdesc   "Comedian Mail (Voicemail System)"
#define VM_ALLOCED   (1 << 13)
#define VM_ATTACH   (1 << 11)
#define VM_DELETE   (1 << 12)
#define VM_DIRECFORWARD   (1 << 10)
#define VM_ENVELOPE   (1 << 4)
#define VM_FORCEGREET   (1 << 8)
#define VM_FORCENAME   (1 << 7)
#define VM_OPERATOR   (1 << 1)
#define VM_PBXSKIP   (1 << 9)
#define VM_REVIEW   (1 << 0)
#define VM_SAYCID   (1 << 2)
#define VM_SAYDURATION   (1 << 5)
#define VM_SEARCH   (1 << 14)
#define VM_SKIPAFTERCMD   (1 << 6)
#define VM_SVMAIL   (1 << 3)
#define VM_TEMPGREETWARN   (1 << 15)
#define VOICEMAIL_CONFIG   "voicemail.conf"
#define VOICEMAIL_DIR_MODE   0777
#define VOICEMAIL_FILE_MODE   0666

Enumerations

enum  {
  OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3),
  OPT_PREPEND_MAILBOX = (1 << 4), OPT_PRIORITY_JUMP = (1 << 5), OPT_AUTOPLAY = (1 << 6)
}
enum  { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_ARRAY_SIZE = 2 }

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
static void __reg_module (void)
static void __unreg_module (void)
static void adsi_begin (struct ast_channel *chan, int *useadsi)
static void adsi_delete (struct ast_channel *chan, struct vm_state *vms)
static void adsi_folders (struct ast_channel *chan, int start, char *label)
static void adsi_goodbye (struct ast_channel *chan)
static int adsi_load_vmail (struct ast_channel *chan, int *useadsi)
static void adsi_login (struct ast_channel *chan)
static int adsi_logo (unsigned char *buf)
static void adsi_message (struct ast_channel *chan, struct vm_state *vms)
static void adsi_password (struct ast_channel *chan)
static void adsi_status (struct ast_channel *chan, struct vm_state *vms)
static void adsi_status2 (struct ast_channel *chan, struct vm_state *vms)
static int advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
static int append_mailbox (char *context, char *mbox, char *data)
static void apply_option (struct ast_vm_user *vmu, const char *var, const char *value)
static void apply_options (struct ast_vm_user *vmu, const char *options)
static void apply_options_full (struct ast_vm_user *retval, struct ast_variable *var)
static int base_encode (char *filename, FILE *so)
static int change_password_realtime (struct ast_vm_user *vmu, const char *password)
static int check_mime (const char *str)
 Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.
static int close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu)
static char * complete_voicemail_show_users (const char *line, const char *word, int pos, int state)
static int copy (char *infile, char *outfile)
static int copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
static void copy_plain_file (char *frompath, char *topath)
static int count_messages (struct ast_vm_user *vmu, char *dir)
static int create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder)
 basically mkdir -p $dest/$context/$ext/$folder
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static char * encode_mime_str (const char *start, char *end, size_t endsize, size_t preamble, size_t postamble)
 Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.
static struct ast_vm_userfind_or_create (char *context, char *mbox)
static struct ast_vm_userfind_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static struct ast_vm_userfind_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static int forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
static void free_user (struct ast_vm_user *vmu)
static void free_vm_users (void)
static void free_zone (struct vm_zone *z)
static int get_date (char *s, int len)
static int get_folder (struct ast_channel *chan, int start)
static int get_folder2 (struct ast_channel *chan, char *fn, int start)
static int handle_voicemail_show_users (int fd, int argc, char *argv[])
static int handle_voicemail_show_zones (int fd, int argc, char *argv[])
static int has_voicemail (const char *mailbox, const char *folder)
static int inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs)
static int inbuf (struct baseio *bio, FILE *fi)
static int inchar (struct baseio *bio, FILE *fi)
static int invent_message (struct ast_channel *chan, struct ast_vm_user *vmu, char *ext, int busy, char *ecodes)
static int last_message_index (struct ast_vm_user *vmu, char *dir)
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
static int load_config (void)
static int load_module (void)
static int make_dir (char *dest, int len, const char *context, const char *ext, const char *folder)
static void make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
static int make_file (char *dest, const int len, const char *dir, const int num)
static char * mbox (int id)
static int messagecount (const char *context, const char *mailbox, const char *folder)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static int ochar (struct baseio *bio, int c, FILE *so)
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int play_greeting (struct ast_channel *chan, struct ast_vm_user *vmu, char *filename, char *ecodes)
static int play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
static int play_message_category (struct ast_channel *chan, const char *category)
static int play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
static int play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
static int play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, signed char record_gain, struct vm_state *vms)
static void populate_defaults (struct ast_vm_user *vmu)
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 char * quote (const char *from, char *to, size_t len)
static int reload (void)
static void rename_file (char *sfn, char *dfn)
static int resequence_mailbox (struct ast_vm_user *vmu, char *dir)
static int reset_user_pw (const char *context, const char *mailbox, const char *newpass)
static void run_externnotify (char *context, char *extension)
static int save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
static int say_and_wait (struct ast_channel *chan, int num, const char *language)
static int sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category)
static int sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category)
static char * strip_control (const char *input, char *buf, size_t buflen)
static int unload_module (void)
static int vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
static int vm_box_exists (struct ast_channel *chan, void *data)
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_latin (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static void vm_change_password (struct ast_vm_user *vmu, const char *newpassword)
static void vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword)
static int vm_delete (char *file)
static int vm_exec (struct ast_channel *chan, void *data)
static int vm_execmain (struct ast_channel *chan, void *data)
static int vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts, char *context, signed char record_gain, long *duration, struct vm_state *vms)
static int vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_intro_cz (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_he (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_it (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
static int vm_intro_nl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_no (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_se (struct ast_channel *chan, struct vm_state *vms)
static int vm_lock_path (const char *path)
static FILE * vm_mkftemp (char *template)
static int vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_options (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 vm_play_folder_name_gr (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_pl (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_ua (struct ast_channel *chan, char *mbox)
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 vmauthenticate (struct ast_channel *chan, void *data)
static struct tm * vmu_tm (const struct ast_vm_user *vmu, struct tm *tm)
static int wait_file (struct ast_channel *chan, struct vm_state *vms, char *file)
static int wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, }
static char * addesc = "Comedian Mail"
static unsigned char adsifdn [4] = "\x00\x00\x00\x0F"
static unsigned char adsisec [4] = "\x9B\xDB\xF7\xAC"
static int adsiver = 1
static char * app = "VoiceMail"
static char * app2 = "VoiceMailMain"
static char * app3 = "MailboxExists"
static char * app4 = "VMAuthenticate"
static const struct ast_module_infoast_module_info = &__mod_info
static char callcontext [AST_MAX_CONTEXT]
static char charset [32] = "ISO-8859-1"
static char cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64]
static struct ast_cli_entry cli_show_voicemail_users_deprecated
static struct ast_cli_entry cli_show_voicemail_zones_deprecated
static struct ast_cli_entry cli_voicemail []
static char * descrip_vm
static char * descrip_vm_box_exists
static char * descrip_vmain
static char * descrip_vmauthenticate
static char dialcontext [AST_MAX_CONTEXT]
static char * emailbody = NULL
static char emaildateformat [32] = "%A, %B %d, %Y at %r"
static char * emailsubject = NULL
static char emailtitle [100]
static char exitcontext [AST_MAX_CONTEXT]
static char ext_pass_cmd [128]
static char externnotify [160]
static char fromstring [100]
static struct ast_flags globalflags = {0}
static char mailcmd [160]
static int maxgreet
static int maxlogins
static int maxmsg
static int maxsilence
int my_umask
static char * pagerbody = NULL
static char pagerfromstring [100]
static char * pagersubject = NULL
static int saydurationminfo
static char serveremail [80]
static int silencethreshold = 128
static int skipms
static struct ast_smdi_interfacesmdi_iface = NULL
static char * synopsis_vm
static char * synopsis_vm_box_exists
static char * synopsis_vmain
static char * synopsis_vmauthenticate
static char userscontext [AST_MAX_EXTENSION] = "default"
static struct ast_app_option vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 },}
enum { ... }  vm_option_args
enum { ... }  vm_option_flags
static char VM_SPOOL_DIR [PATH_MAX]
static char vmfmts [80]
static int vmmaxmessage
static int vmminmessage
static char voicemail_show_users_help []
static char voicemail_show_zones_help []
static double volgain
static char zonetag [80]


Detailed Description

Comedian Mail - Voicemail System.

Author:
Mark Spencer <markster@digium.com>
See also
Note:
This module requires res_adsi to load.

Definition in file app_voicemail.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 168 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 184 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 185 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 185 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 165 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 161 of file app_voicemail.c.

#define COPY ( a,
b,
c,
d,
e,
f,
g,
 )     (copy_plain_file(g,h));

Definition at line 438 of file app_voicemail.c.

Referenced by copy_message().

#define DELETE ( a,
b,
c,
 )     (vm_delete(c))

Definition at line 439 of file app_voicemail.c.

Referenced by notify_new_message(), play_record_review(), and vm_tempgreeting().

#define DISPOSE ( a,
 ) 

Definition at line 434 of file app_voicemail.c.

Referenced by advanced_options(), forward_message(), leave_voicemail(), notify_new_message(), play_greeting(), play_message(), play_record_review(), vm_intro(), vm_options(), and vm_tempgreeting().

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 186 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 207 of file app_voicemail.c.

Referenced by close_mailbox(), copy_message(), count_messages(), last_message_index(), resequence_mailbox(), save_to_folder(), vm_exec(), and vm_execmain().

#define ERROR_MAILBOX_FULL   -200

Definition at line 208 of file app_voicemail.c.

Referenced by save_to_folder().

#define EXISTS ( a,
b,
c,
 )     (ast_fileexists(c,NULL,d) > 0)

Definition at line 436 of file app_voicemail.c.

Referenced by close_mailbox(), copy_message(), leave_voicemail(), resequence_mailbox(), and save_to_folder().

#define INTRO   "vm-intro"

Definition at line 174 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 188 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 189 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 176 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 178 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define RENAME ( a,
b,
c,
d,
e,
f,
g,
 )     (rename_file(g,h));

Definition at line 437 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
b,
 ) 

Definition at line 433 of file app_voicemail.c.

Referenced by advanced_options(), forward_message(), leave_voicemail(), notify_new_message(), play_greeting(), play_message(), vm_intro(), vm_options(), and vm_tempgreeting().

#define SENDMAIL   "/usr/sbin/sendmail -t"

Definition at line 172 of file app_voicemail.c.

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 159 of file app_voicemail.c.

Referenced by run_externnotify().

#define STORE ( a,
b,
c,
d,
e,
f,
g,
h,
 ) 

Definition at line 435 of file app_voicemail.c.

Referenced by copy_message(), forward_message(), leave_voicemail(), and play_record_review().

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 454 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 204 of file app_voicemail.c.

Referenced by find_user(), find_user_realtime(), free_user(), and free_vm_users().

#define VM_ATTACH   (1 << 11)

Definition at line 202 of file app_voicemail.c.

Referenced by apply_option(), forward_message(), load_config(), notify_new_message(), and sendmail().

#define VM_DELETE   (1 << 12)

Definition at line 203 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 201 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 195 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_message().

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

Definition at line 199 of file app_voicemail.c.

Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().

#define VM_FORCENAME   (1 << 7)

Have new users record their name

Definition at line 198 of file app_voicemail.c.

Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().

#define VM_OPERATOR   (1 << 1)

Definition at line 192 of file app_voicemail.c.

Referenced by apply_option(), leave_voicemail(), load_config(), and play_record_review().

#define VM_PBXSKIP   (1 << 9)

Definition at line 200 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 191 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_record_review().

#define VM_SAYCID   (1 << 2)

Definition at line 193 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_message().

#define VM_SAYDURATION   (1 << 5)

Definition at line 196 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and play_message().

#define VM_SEARCH   (1 << 14)

Definition at line 205 of file app_voicemail.c.

Referenced by find_or_create(), find_user(), find_user_realtime(), and load_config().

#define VM_SKIPAFTERCMD   (1 << 6)

Definition at line 197 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Definition at line 194 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and vm_execmain().

#define VM_TEMPGREETWARN   (1 << 15)

Remind user tempgreeting is set

Definition at line 206 of file app_voicemail.c.

Referenced by apply_option(), load_config(), and vm_intro().

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 167 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 163 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

Definition at line 164 of file app_voicemail.c.

Referenced by copy(), leave_voicemail(), make_email_file(), and vm_mkftemp().


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_PRIORITY_JUMP 
OPT_AUTOPLAY 

Definition at line 211 of file app_voicemail.c.

00211      {
00212    OPT_SILENT =           (1 << 0),
00213    OPT_BUSY_GREETING =    (1 << 1),
00214    OPT_UNAVAIL_GREETING = (1 << 2),
00215    OPT_RECORDGAIN =       (1 << 3),
00216    OPT_PREPEND_MAILBOX =  (1 << 4),
00217    OPT_PRIORITY_JUMP =    (1 << 5),
00218    OPT_AUTOPLAY =         (1 << 6),
00219 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 221 of file app_voicemail.c.

00221      {
00222    OPT_ARG_RECORDGAIN = 0,
00223    OPT_ARG_PLAYFOLDER = 1,
00224    /* This *must* be the last value in this enum! */
00225    OPT_ARG_ARRAY_SIZE = 2,
00226 } vm_option_args;


Function Documentation

static int __has_voicemail ( const char *  context,
const char *  mailbox,
const char *  folder,
int  shortcircuit 
) [static]

Definition at line 3749 of file app_voicemail.c.

References ast_strlen_zero().

Referenced by has_voicemail(), inboxcount(), and messagecount().

03750 {
03751    DIR *dir;
03752    struct dirent *de;
03753    char fn[256];
03754    int ret = 0;
03755    if (!folder)
03756       folder = "INBOX";
03757    /* If no mailbox, return immediately */
03758    if (ast_strlen_zero(mailbox))
03759       return 0;
03760    if (!context)
03761       context = "default";
03762    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
03763    dir = opendir(fn);
03764    if (!dir)
03765       return 0;
03766    while ((de = readdir(dir))) {
03767       if (!strncasecmp(de->d_name, "msg", 3)) {
03768          if (shortcircuit) {
03769             ret = 1;
03770             break;
03771          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
03772             ret++;
03773       }
03774    }
03775    closedir(dir);
03776    return ret;
03777 }

static void __reg_module ( void   )  [static]

Definition at line 9216 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 9216 of file app_voicemail.c.

static void adsi_begin ( struct ast_channel chan,
int *  useadsi 
) [static]

Definition at line 4505 of file app_voicemail.c.

References adsi_load_vmail(), ast_adsi_available(), ast_adsi_load_session(), and ast_log().

Referenced by vm_authenticate(), and vm_execmain().

04506 {
04507    int x;
04508    if (!ast_adsi_available(chan))
04509       return;
04510    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04511    if (x < 0)
04512       return;
04513    if (!x) {
04514       if (adsi_load_vmail(chan, useadsi)) {
04515          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04516          return;
04517       }
04518    } else
04519       *useadsi = 1;
04520 }

static void adsi_delete ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 4694 of file app_voicemail.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), vm_state::curmsg, and keys.

Referenced by vm_execmain().

04695 {
04696    int bytes=0;
04697    unsigned char buf[256];
04698    unsigned char keys[8];
04699 
04700    int x;
04701 
04702    if (!ast_adsi_available(chan))
04703       return;
04704 
04705    /* New meaning for keys */
04706    for (x=0;x<5;x++)
04707       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04708 
04709    keys[6] = 0x0;
04710    keys[7] = 0x0;
04711 
04712    if (!vms->curmsg) {
04713       /* No prev key, provide "Folder" instead */
04714       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04715    }
04716    if (vms->curmsg >= vms->lastmsg) {
04717       /* If last message ... */
04718       if (vms->curmsg) {
04719          /* but not only message, provide "Folder" instead */
04720          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04721       } else {
04722          /* Otherwise if only message, leave blank */
04723          keys[3] = 1;
04724       }
04725    }
04726 
04727    /* If deleted, show "undeleted" */
04728    if (vms->deleted[vms->curmsg]) 
04729       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04730 
04731    /* Except "Exit" */
04732    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04733    bytes += ast_adsi_set_keys(buf + bytes, keys);
04734    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04735 
04736    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04737 }

static void adsi_folders ( struct ast_channel chan,
int  start,
char *  label 
) [static]

Definition at line 4570 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), and keys.

Referenced by vm_execmain().

04571 {
04572    unsigned char buf[256];
04573    int bytes=0;
04574    unsigned char keys[8];
04575    int x,y;
04576 
04577    if (!ast_adsi_available(chan))
04578       return;
04579 
04580    for (x=0;x<5;x++) {
04581       y = ADSI_KEY_APPS + 12 + start + x;
04582       if (y > ADSI_KEY_APPS + 12 + 4)
04583          y = 0;
04584       keys[x] = ADSI_KEY_SKT | y;
04585    }
04586    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
04587    keys[6] = 0;
04588    keys[7] = 0;
04589 
04590    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
04591    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
04592    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04593    bytes += ast_adsi_set_keys(buf + bytes, keys);
04594    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04595 
04596    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04597 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 4842 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), and ast_adsi_voice_mode().

Referenced by vm_execmain().

04843 {
04844    unsigned char buf[256];
04845    int bytes=0;
04846 
04847    if (!ast_adsi_available(chan))
04848       return;
04849    bytes += adsi_logo(buf + bytes);
04850    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
04851    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
04852    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04853    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04854 
04855    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04856 }

static int adsi_load_vmail ( struct ast_channel chan,
int *  useadsi 
) [static]

Definition at line 4374 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, ast_adsi_begin_download(), ast_adsi_data_mode(), ast_adsi_display(), ast_adsi_download_disconnect(), ast_adsi_end_download(), ast_adsi_load_session(), ast_adsi_load_soft_key(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_log(), LOG_DEBUG, mbox(), and option_debug.

Referenced by adsi_begin().

04375 {
04376    unsigned char buf[256];
04377    int bytes=0;
04378    int x;
04379    char num[5];
04380 
04381    *useadsi = 0;
04382    bytes += ast_adsi_data_mode(buf + bytes);
04383    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04384 
04385    bytes = 0;
04386    bytes += adsi_logo(buf);
04387    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04388 #ifdef DISPLAY
04389    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04390 #endif
04391    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04392    bytes += ast_adsi_data_mode(buf + bytes);
04393    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04394 
04395    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04396       bytes = 0;
04397       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04398       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04399       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04400       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04401       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04402       return 0;
04403    }
04404 
04405 #ifdef DISPLAY
04406    /* Add a dot */
04407    bytes = 0;
04408    bytes += ast_adsi_logo(buf);
04409    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04410    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04411    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04412    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04413 #endif
04414    bytes = 0;
04415    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04416    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04417    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04418    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04419    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04420    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04421    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04422 
04423 #ifdef DISPLAY
04424    /* Add another dot */
04425    bytes = 0;
04426    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04427    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04428 
04429    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04430    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04431 #endif
04432 
04433    bytes = 0;
04434    /* These buttons we load but don't use yet */
04435    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04436    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04437    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04438    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04439    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04440    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04441    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04442 
04443 #ifdef DISPLAY
04444    /* Add another dot */
04445    bytes = 0;
04446    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04447    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04448    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04449 #endif
04450 
04451    bytes = 0;
04452    for (x=0;x<5;x++) {
04453       snprintf(num, sizeof(num), "%d", x);
04454       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04455    }
04456    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04457    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04458 
04459 #ifdef DISPLAY
04460    /* Add another dot */
04461    bytes = 0;
04462    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04463    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04464    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04465 #endif
04466 
04467    if (ast_adsi_end_download(chan)) {
04468       bytes = 0;
04469       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04470       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04471       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04472       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04473       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04474       return 0;
04475    }
04476    bytes = 0;
04477    bytes += ast_adsi_download_disconnect(buf + bytes);
04478    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04479    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04480 
04481    if (option_debug)
04482       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
04483 
04484 #ifdef DISPLAY
04485    /* Add last dot */
04486    bytes = 0;
04487    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04488    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04489 #endif
04490    if (option_debug)
04491       ast_log(LOG_DEBUG, "Restarting session...\n");
04492 
04493    bytes = 0;
04494    /* Load the session now */
04495    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04496       *useadsi = 1;
04497       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04498    } else
04499       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04500 
04501    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04502    return 0;
04503 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 4522 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_input_control(), ast_adsi_input_format(), ast_adsi_load_soft_key(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), and keys.

Referenced by vm_authenticate().

04523 {
04524    unsigned char buf[256];
04525    int bytes=0;
04526    unsigned char keys[8];
04527    int x;
04528    if (!ast_adsi_available(chan))
04529       return;
04530 
04531    for (x=0;x<8;x++)
04532       keys[x] = 0;
04533    /* Set one key for next */
04534    keys[3] = ADSI_KEY_APPS + 3;
04535 
04536    bytes += adsi_logo(buf + bytes);
04537    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04538    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04539    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04540    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04541    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
04542    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
04543    bytes += ast_adsi_set_keys(buf + bytes, keys);
04544    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04545    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04546 }

static int adsi_logo ( unsigned char *  buf  )  [static]

Definition at line 4366 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().

Referenced by adsi_goodbye(), adsi_load_vmail(), adsi_login(), vm_newuser(), vm_options(), and vm_tempgreeting().

04367 {
04368    int bytes = 0;
04369    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04370    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04371    return bytes;
04372 }

static void adsi_message ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 4599 of file app_voicemail.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), ast_copy_string(), ast_strlen_zero(), vm_state::curmsg, vm_state::fn, keys, and name.

Referenced by play_message(), and vm_execmain().

04600 {
04601    int bytes=0;
04602    unsigned char buf[256]; 
04603    char buf1[256], buf2[256];
04604    char fn2[PATH_MAX];
04605 
04606    char cid[256]="";
04607    char *val;
04608    char *name, *num;
04609    char datetime[21]="";
04610    FILE *f;
04611 
04612    unsigned char keys[8];
04613 
04614    int x;
04615 
04616    if (!ast_adsi_available(chan))
04617       return;
04618 
04619    /* Retrieve important info */
04620    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
04621    f = fopen(fn2, "r");
04622    if (f) {
04623       while (!feof(f)) {   
04624          if (!fgets((char *)buf, sizeof(buf), f)) {
04625             continue;
04626          }
04627          if (!feof(f)) {
04628             char *stringp=NULL;
04629             stringp = (char *)buf;
04630             strsep(&stringp, "=");
04631             val = strsep(&stringp, "=");
04632             if (!ast_strlen_zero(val)) {
04633                if (!strcmp((char *)buf, "callerid"))
04634                   ast_copy_string(cid, val, sizeof(cid));
04635                if (!strcmp((char *)buf, "origdate"))
04636                   ast_copy_string(datetime, val, sizeof(datetime));
04637             }
04638          }
04639       }
04640       fclose(f);
04641    }
04642    /* New meaning for keys */
04643    for (x=0;x<5;x++)
04644       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04645    keys[6] = 0x0;
04646    keys[7] = 0x0;
04647 
04648    if (!vms->curmsg) {
04649       /* No prev key, provide "Folder" instead */
04650       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04651    }
04652    if (vms->curmsg >= vms->lastmsg) {
04653       /* If last message ... */
04654       if (vms->curmsg) {
04655          /* but not only message, provide "Folder" instead */
04656          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04657          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04658 
04659       } else {
04660          /* Otherwise if only message, leave blank */
04661          keys[3] = 1;
04662       }
04663    }
04664 
04665    if (!ast_strlen_zero(cid)) {
04666       ast_callerid_parse(cid, &name, &num);
04667       if (!name)
04668          name = num;
04669    } else
04670       name = "Unknown Caller";
04671 
04672    /* If deleted, show "undeleted" */
04673 
04674    if (vms->deleted[vms->curmsg])
04675       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04676 
04677    /* Except "Exit" */
04678    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04679    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
04680       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
04681    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
04682 
04683    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04684    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04685    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
04686    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
04687    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04688    bytes += ast_adsi_set_keys(buf + bytes, keys);
04689    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04690 
04691    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04692 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 4548 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_input_control(), ast_adsi_input_format(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), and keys.

Referenced by vm_authenticate().

04549 {
04550    unsigned char buf[256];
04551    int bytes=0;
04552    unsigned char keys[8];
04553    int x;
04554    if (!ast_adsi_available(chan))
04555       return;
04556 
04557    for (x=0;x<8;x++)
04558       keys[x] = 0;
04559    /* Set one key for next */
04560    keys[3] = ADSI_KEY_APPS + 3;
04561 
04562    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04563    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
04564    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
04565    bytes += ast_adsi_set_keys(buf + bytes, keys);
04566    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04567    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04568 }

static void adsi_status ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 4739 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), keys, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_execmain().

04740 {
04741    unsigned char buf[256] = "";
04742    char buf1[256] = "", buf2[256] = "";
04743    int bytes=0;
04744    unsigned char keys[8];
04745    int x;
04746 
04747    char *newm = (vms->newmessages == 1) ? "message" : "messages";
04748    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
04749    if (!ast_adsi_available(chan))
04750       return;
04751    if (vms->newmessages) {
04752       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
04753       if (vms->oldmessages) {
04754          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
04755          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
04756       } else {
04757          snprintf(buf2, sizeof(buf2), "%s.", newm);
04758       }
04759    } else if (vms->oldmessages) {
04760       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
04761       snprintf(buf2, sizeof(buf2), "%s.", oldm);
04762    } else {
04763       strcpy(buf1, "You have no messages.");
04764       buf2[0] = ' ';
04765       buf2[1] = '\0';
04766    }
04767    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04768    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04769    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04770 
04771    for (x=0;x<6;x++)
04772       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04773    keys[6] = 0;
04774    keys[7] = 0;
04775 
04776    /* Don't let them listen if there are none */
04777    if (vms->lastmsg < 0)
04778       keys[0] = 1;
04779    bytes += ast_adsi_set_keys(buf + bytes, keys);
04780 
04781    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04782 
04783    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04784 }

static void adsi_status2 ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 4786 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curbox, keys, and vm_state::lastmsg.

Referenced by vm_execmain().

04787 {
04788    unsigned char buf[256] = "";
04789    char buf1[256] = "", buf2[256] = "";
04790    int bytes=0;
04791    unsigned char keys[8];
04792    int x;
04793 
04794    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
04795 
04796    if (!ast_adsi_available(chan))
04797       return;
04798 
04799    /* Original command keys */
04800    for (x=0;x<6;x++)
04801       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04802 
04803    keys[6] = 0;
04804    keys[7] = 0;
04805 
04806    if ((vms->lastmsg + 1) < 1)
04807       keys[0] = 0;
04808 
04809    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
04810       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
04811 
04812    if (vms->lastmsg + 1)
04813       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
04814    else
04815       strcpy(buf2, "no messages.");
04816    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04817    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04818    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
04819    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04820    bytes += ast_adsi_set_keys(buf + bytes, keys);
04821 
04822    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04823 
04824    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04825    
04826 }

static int advanced_options ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
int  msg,
int  option,
signed char  record_gain 
) [static]

Definition at line 8813 of file app_voicemail.c.

References ast_callerid_parse(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_variable_retrieve(), ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::fn2, vm_state::heard, leave_voicemail(), make_file(), name, option_verbose, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

08814 {
08815    int res = 0;
08816    char filename[PATH_MAX];
08817    struct ast_config *msg_cfg = NULL;
08818    const char *origtime, *context;
08819    char *cid, *name, *num;
08820    int retries = 0;
08821 
08822    vms->starting = 0; 
08823    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08824 
08825    /* Retrieve info from VM attribute file */
08826    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08827    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08828    RETRIEVE(vms->curdir, vms->curmsg, vmu);
08829    msg_cfg = ast_config_load(filename);
08830    DISPOSE(vms->curdir, vms->curmsg);
08831    if (!msg_cfg) {
08832       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08833       return 0;
08834    }
08835 
08836    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08837       ast_config_destroy(msg_cfg);
08838       return 0;
08839    }
08840 
08841    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08842 
08843    context = ast_variable_retrieve(msg_cfg, "message", "context");
08844    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08845       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08846    switch (option) {
08847    case 3:
08848       if (!res)
08849          res = play_message_datetime(chan, vmu, origtime, filename);
08850       if (!res)
08851          res = play_message_callerid(chan, vms, cid, context, 0);
08852 
08853       res = 't';
08854       break;
08855 
08856    case 2:  /* Call back */
08857 
08858       if (ast_strlen_zero(cid))
08859          break;
08860 
08861       ast_callerid_parse(cid, &name, &num);
08862       while ((res > -1) && (res != 't')) {
08863          switch (res) {
08864          case '1':
08865             if (num) {
08866                /* Dial the CID number */
08867                res = dialout(chan, vmu, num, vmu->callback);
08868                if (res) {
08869                   ast_config_destroy(msg_cfg);
08870                   return 9;
08871                }
08872             } else {
08873                res = '2';
08874             }
08875             break;
08876 
08877          case '2':
08878             /* Want to enter a different number, can only do this if there's a dialout context for this user */
08879             if (!ast_strlen_zero(vmu->dialout)) {
08880                res = dialout(chan, vmu, NULL, vmu->dialout);
08881                if (res) {
08882                   ast_config_destroy(msg_cfg);
08883                   return 9;
08884                }
08885             } else {
08886                if (option_verbose > 2)
08887                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
08888                res = ast_play_and_wait(chan, "vm-sorry");
08889             }
08890             ast_config_destroy(msg_cfg);
08891             return res;
08892          case '*':
08893             res = 't';
08894             break;
08895          case '3':
08896          case '4':
08897          case '5':
08898          case '6':
08899          case '7':
08900          case '8':
08901          case '9':
08902          case '0':
08903 
08904             res = ast_play_and_wait(chan, "vm-sorry");
08905             retries++;
08906             break;
08907          default:
08908             if (num) {
08909                if (option_verbose > 2)
08910                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
08911                res = ast_play_and_wait(chan, "vm-num-i-have");
08912                if (!res)
08913                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
08914                if (!res)
08915                   res = ast_play_and_wait(chan, "vm-tocallnum");
08916                /* Only prompt for a caller-specified number if there is a dialout context specified */
08917                if (!ast_strlen_zero(vmu->dialout)) {
08918                   if (!res)
08919                      res = ast_play_and_wait(chan, "vm-calldiffnum");
08920                }
08921             } else {
08922                res = ast_play_and_wait(chan, "vm-nonumber");
08923                if (!ast_strlen_zero(vmu->dialout)) {
08924                   if (!res)
08925                      res = ast_play_and_wait(chan, "vm-toenternumber");
08926                }
08927             }
08928             if (!res)
08929                res = ast_play_and_wait(chan, "vm-star-cancel");
08930             if (!res)
08931                res = ast_waitfordigit(chan, 6000);
08932             if (!res) {
08933                retries++;
08934                if (retries > 3)
08935                   res = 't';
08936             }
08937             break; 
08938             
08939          }
08940          if (res == 't')
08941             res = 0;
08942          else if (res == '*')
08943             res = -1;
08944       }
08945       break;
08946       
08947    case 1:  /* Reply */
08948       /* Send reply directly to sender */
08949       if (ast_strlen_zero(cid))
08950          break;
08951 
08952       ast_callerid_parse(cid, &name, &num);
08953       if (!num) {
08954          if (option_verbose > 2)
08955             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
08956          if (!res)
08957             res = ast_play_and_wait(chan, "vm-nonumber");
08958          ast_config_destroy(msg_cfg);
08959          return res;
08960       } else {
08961          struct ast_vm_user vmu2;
08962          if (find_user(&vmu2, vmu->context, num)) {
08963             struct leave_vm_options leave_options;
08964             char mailbox[AST_MAX_EXTENSION * 2 + 2];
08965             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
08966 
08967             if (option_verbose > 2)
08968                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
08969             
08970             memset(&leave_options, 0, sizeof(leave_options));
08971             leave_options.record_gain = record_gain;
08972             res = leave_voicemail(chan, mailbox, &leave_options);
08973             if (!res)
08974                res = 't';
08975             ast_config_destroy(msg_cfg);
08976             return res;
08977          } else {
08978             /* Sender has no mailbox, can't reply */
08979             if (option_verbose > 2)
08980                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
08981             ast_play_and_wait(chan, "vm-nobox");
08982             res = 't';
08983             ast_config_destroy(msg_cfg);
08984             return res;
08985          }
08986       } 
08987       res = 0;
08988 
08989       break;
08990    }
08991 
08992 #ifndef IMAP_STORAGE
08993    ast_config_destroy(msg_cfg);
08994 
08995    if (!res) {
08996       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08997       vms->heard[msg] = 1;
08998       res = wait_file(chan, vms, vms->fn);
08999    }
09000 #endif
09001    return res;
09002 }

static int append_mailbox ( char *  context,
char *  mbox,
char *  data 
) [static]

Definition at line 7871 of file app_voicemail.c.

References apply_options(), ast_copy_string(), ast_strdupa, find_or_create(), populate_defaults(), and s.

Referenced by load_config().

07872 {
07873    /* Assumes lock is already held */
07874    char *tmp;
07875    char *stringp;
07876    char *s;
07877    struct ast_vm_user *vmu;
07878 
07879    tmp = ast_strdupa(data);
07880 
07881    if ((vmu = find_or_create(context, mbox))) {
07882       populate_defaults(vmu);
07883 
07884       stringp = tmp;
07885       if ((s = strsep(&stringp, ","))) 
07886          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07887       if (stringp && (s = strsep(&stringp, ","))) 
07888          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
07889       if (stringp && (s = strsep(&stringp, ","))) 
07890          ast_copy_string(vmu->email, s, sizeof(vmu->email));
07891       if (stringp && (s = strsep(&stringp, ","))) 
07892          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
07893       if (stringp && (s = strsep(&stringp, ","))) 
07894          apply_options(vmu, s);
07895    }
07896    return 0;
07897 }

static void apply_option ( struct ast_vm_user vmu,
const char *  var,
const char *  value 
) [static]

Definition at line 617 of file app_voicemail.c.

References apply_options(), ast_copy_string(), ast_log(), ast_set2_flag, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, ast_vm_user::language, LOG_WARNING, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::saydurationm, ast_vm_user::serveremail, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.

Referenced by apply_options(), and apply_options_full().

00618 {
00619    int x;
00620    if (!strcasecmp(var, "attach")) {
00621       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00622    } else if (!strcasecmp(var, "attachfmt")) {
00623       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00624    } else if (!strcasecmp(var, "serveremail")) {
00625       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00626    } else if (!strcasecmp(var, "language")) {
00627       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00628    } else if (!strcasecmp(var, "tz")) {
00629       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00630 #ifdef IMAP_STORAGE
00631    } else if (!strcasecmp(var, "imapuser")) {
00632       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00633    } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
00634       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00635    } else if (!strcasecmp(var, "imapvmshareid")) {
00636       ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
00637 #endif
00638    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00639       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00640    } else if (!strcasecmp(var, "saycid")){
00641       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00642    } else if (!strcasecmp(var,"sendvoicemail")){
00643       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00644    } else if (!strcasecmp(var, "review")){
00645       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00646    } else if (!strcasecmp(var, "tempgreetwarn")){
00647       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00648    } else if (!strcasecmp(var, "operator")){
00649       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00650    } else if (!strcasecmp(var, "envelope")){
00651       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00652    } else if (!strcasecmp(var, "sayduration")){
00653       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00654    } else if (!strcasecmp(var, "saydurationm")){
00655       if (sscanf(value, "%d", &x) == 1) {
00656          vmu->saydurationm = x;
00657       } else {
00658          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00659       }
00660    } else if (!strcasecmp(var, "forcename")){
00661       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00662    } else if (!strcasecmp(var, "forcegreetings")){
00663       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00664    } else if (!strcasecmp(var, "callback")) {
00665       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00666    } else if (!strcasecmp(var, "dialout")) {
00667       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00668    } else if (!strcasecmp(var, "exitcontext")) {
00669       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00670    } else if (!strcasecmp(var, "maxmsg")) {
00671       vmu->maxmsg = atoi(value);
00672       if (vmu->maxmsg <= 0) {
00673          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00674          vmu->maxmsg = MAXMSG;
00675       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00676          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00677          vmu->maxmsg = MAXMSGLIMIT;
00678       }
00679    } else if (!strcasecmp(var, "volgain")) {
00680       sscanf(value, "%lf", &vmu->volgain);
00681    } else if (!strcasecmp(var, "options")) {
00682       apply_options(vmu, value);
00683    }
00684 }

static void apply_options ( struct ast_vm_user vmu,
const char *  options 
) [static]

Definition at line 702 of file app_voicemail.c.

References apply_option(), ast_strdupa, s, and var.

Referenced by append_mailbox(), and apply_option().

00703 {  /* Destructively Parse options and apply */
00704    char *stringp;
00705    char *s;
00706    char *var, *value;
00707    stringp = ast_strdupa(options);
00708    while ((s = strsep(&stringp, "|"))) {
00709       value = s;
00710       if ((var = strsep(&value, "=")) && value) {
00711          apply_option(vmu, var, value);
00712       }
00713    }  
00714 }

static void apply_options_full ( struct ast_vm_user retval,
struct ast_variable var 
) [static]

Definition at line 716 of file app_voicemail.c.

References apply_option(), ast_copy_string(), ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::fullname, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::uniqueid, ast_variable::value, and var.

Referenced by find_user_realtime(), and load_config().

00717 {
00718    struct ast_variable *tmp;
00719    tmp = var;
00720    while (tmp) {
00721       if (!strcasecmp(tmp->name, "vmsecret")) {
00722          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00723       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00724          if (ast_strlen_zero(retval->password))
00725             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00726       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00727          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00728       } else if (!strcasecmp(tmp->name, "pager")) {
00729          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00730       } else if (!strcasecmp(tmp->name, "email")) {
00731          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00732       } else if (!strcasecmp(tmp->name, "fullname")) {
00733          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00734       } else if (!strcasecmp(tmp->name, "context")) {
00735          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00736 #ifdef IMAP_STORAGE
00737       } else if (!strcasecmp(tmp->name, "imapuser")) {
00738          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00739       } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) {
00740          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00741       } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
00742          ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
00743 #endif
00744       } else
00745          apply_option(retval, tmp->name, tmp->value);
00746       tmp = tmp->next;
00747    } 
00748 }

static int base_encode ( char *  filename,
FILE *  so 
) [static]

Definition at line 2924 of file app_voicemail.c.

References ast_log(), BASEMAXINLINE, eol, errno, inchar(), and ochar().

Referenced by make_email_file().

02925 {
02926    unsigned char dtable[BASEMAXINLINE];
02927    int i,hiteof= 0;
02928    FILE *fi;
02929    struct baseio bio;
02930 
02931    memset(&bio, 0, sizeof(bio));
02932    bio.iocp = BASEMAXINLINE;
02933 
02934    if (!(fi = fopen(filename, "rb"))) {
02935       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
02936       return -1;
02937    }
02938 
02939    for (i= 0;i<9;i++) {
02940       dtable[i]= 'A'+i;
02941       dtable[i+9]= 'J'+i;
02942       dtable[26+i]= 'a'+i;
02943       dtable[26+i+9]= 'j'+i;
02944    }
02945    for (i= 0;i<8;i++) {
02946       dtable[i+18]= 'S'+i;
02947       dtable[26+i+18]= 's'+i;
02948    }
02949    for (i= 0;i<10;i++) {
02950       dtable[52+i]= '0'+i;
02951    }
02952    dtable[62]= '+';
02953    dtable[63]= '/';
02954 
02955    while (!hiteof){
02956       unsigned char igroup[3],ogroup[4];
02957       int c,n;
02958 
02959       igroup[0]= igroup[1]= igroup[2]= 0;
02960 
02961       for (n= 0;n<3;n++) {
02962          if ((c = inchar(&bio, fi)) == EOF) {
02963             hiteof= 1;
02964             break;
02965          }
02966 
02967          igroup[n]= (unsigned char)c;
02968       }
02969 
02970       if (n> 0) {
02971          ogroup[0]= dtable[igroup[0]>>2];
02972          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
02973          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
02974          ogroup[3]= dtable[igroup[2]&0x3F];
02975 
02976          if (n<3) {
02977             ogroup[3]= '=';
02978 
02979             if (n<2)
02980                ogroup[2]= '=';
02981          }
02982 
02983          for (i= 0;i<4;i++)
02984             ochar(&bio, ogroup[i], so);
02985       }
02986    }
02987 
02988    fclose(fi);
02989    
02990    if (fputs(eol,so)==EOF)
02991       return 0;
02992 
02993    return 1;
02994 }

static int change_password_realtime ( struct ast_vm_user vmu,
const char *  password 
) [static]

Definition at line 686 of file app_voicemail.c.

References ast_copy_string(), ast_strlen_zero(), ast_update_realtime(), ast_vm_user::password, and ast_vm_user::uniqueid.

Referenced by vm_change_password().

00687 {
00688    int res;
00689    if (!ast_strlen_zero(vmu->uniqueid)) {
00690       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00691       if (res > 0) {
00692          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00693          res = 0;
00694       } else if (!res) {
00695          res = -1;
00696       }
00697       return res;
00698    }
00699    return -1;
00700 }

static int check_mime ( const char *  str  )  [static]

Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.

Definition at line 3057 of file app_voicemail.c.

Referenced by make_email_file().

03058 {
03059    for (; *str; str++) {
03060       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03061          return 1;
03062       }
03063    }
03064    return 0;
03065 }

static int close_mailbox ( struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 5671 of file app_voicemail.c.

References ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, vm_state::deleted, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::fn2, vm_state::heard, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, RENAME, and vm_lock_path().

Referenced by vm_execmain().

05672 {
05673    int x = 0;
05674 #ifndef IMAP_STORAGE
05675    int res = 0, nummsg;
05676 #endif
05677 
05678    if (vms->lastmsg <= -1)
05679       goto done;
05680 
05681    vms->curmsg = -1; 
05682 #ifndef IMAP_STORAGE
05683    /* Get the deleted messages fixed */ 
05684    if (vm_lock_path(vms->curdir))
05685       return ERROR_LOCK_PATH;
05686     
05687    for (x = 0; x < vmu->maxmsg; x++) { 
05688       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
05689          /* Save this message.  It's not in INBOX or hasn't been heard */ 
05690          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
05691          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
05692             break;
05693          vms->curmsg++; 
05694          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
05695          if (strcmp(vms->fn, vms->fn2)) { 
05696             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
05697          } 
05698       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
05699          /* Move to old folder before deleting */ 
05700          res = save_to_folder(vmu, vms, x, 1);
05701          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
05702             /* If save failed do not delete the message */
05703             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
05704             vms->deleted[x] = 0;
05705             vms->heard[x] = 0;
05706             --x;
05707          } 
05708       } 
05709    } 
05710 
05711    /* Delete ALL remaining messages */
05712    nummsg = x - 1;
05713    for (x = vms->curmsg + 1; x <= nummsg; x++) {
05714       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
05715       if (EXISTS(vms->curdir, x, vms->fn, NULL))
05716          DELETE(vms->curdir, x, vms->fn, vmu);
05717    }
05718    ast_unlock_path(vms->curdir);
05719 #else
05720    if (vms->deleted) {
05721       for (x=0;x < vmu->maxmsg;x++) { 
05722          if (vms->deleted[x]) { 
05723             if (option_debug > 2)
05724                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
05725             DELETE(vms->curdir, x, vms->fn, vmu);
05726          }
05727       }
05728    }
05729 #endif
05730 
05731 done:
05732    if (vms->deleted)
05733       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
05734    if (vms->heard)
05735       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
05736 
05737    return 0;
05738 }

static char* complete_voicemail_show_users ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 8060 of file app_voicemail.c.

References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.

08061 {
08062    int which = 0;
08063    int wordlen;
08064    struct ast_vm_user *vmu;
08065    const char *context = "";
08066 
08067    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08068    if (pos > 4)
08069       return NULL;
08070    if (pos == 3)
08071       return (state == 0) ? ast_strdup("for") : NULL;
08072    wordlen = strlen(word);
08073    AST_LIST_TRAVERSE(&users, vmu, list) {
08074       if (!strncasecmp(word, vmu->context, wordlen)) {
08075          if (context && strcmp(context, vmu->context) && ++which > state)
08076             return ast_strdup(vmu->context);
08077          /* ignore repeated contexts ? */
08078          context = vmu->context;
08079       }
08080    }
08081    return NULL;
08082 }

static int copy ( char *  infile,
char *  outfile 
) [static]

Definition at line 2802 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

02803 {
02804    int ifd;
02805    int ofd;
02806    int res;
02807    int len;
02808    char buf[4096];
02809 
02810 #ifdef HARDLINK_WHEN_POSSIBLE
02811    /* Hard link if possible; saves disk space & is faster */
02812    if (link(infile, outfile)) {
02813 #endif
02814       if ((ifd = open(infile, O_RDONLY)) < 0) {
02815          ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
02816          return -1;
02817       }
02818       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
02819          ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
02820          close(ifd);
02821          return -1;
02822       }
02823       do {
02824          len = read(ifd, buf, sizeof(buf));
02825          if (len < 0) {
02826             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
02827             close(ifd);
02828             close(ofd);
02829             unlink(outfile);
02830          }
02831          if (len) {
02832             res = write(ofd, buf, len);
02833             if (errno == ENOMEM || errno == ENOSPC || res != len) {
02834                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
02835                close(ifd);
02836                close(ofd);
02837                unlink(outfile);
02838             }
02839          }
02840       } while (len);
02841       close(ifd);
02842       close(ofd);
02843       return 0;
02844 #ifdef HARDLINK_WHEN_POSSIBLE
02845    } else {
02846       /* Hard link succeeded */
02847       return 0;
02848    }
02849 #endif
02850 }

static int copy_message ( struct ast_channel chan,
struct ast_vm_user vmu,
int  imbox,
int  msgnum,
long  duration,
struct ast_vm_user recip,
char *  fmt,
char *  dir 
) [static]

Definition at line 3693 of file app_voicemail.c.

References ast_copy_string(), ast_log(), ast_unlock_path(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_channel::language, LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_dir(), make_file(), mbox(), notify_new_message(), S_OR, STORE, vm_delete(), and vm_lock_path().

Referenced by forward_message(), and leave_voicemail().

03694 {
03695    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
03696    const char *frombox = mbox(imbox);
03697    int recipmsgnum;
03698 
03699    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
03700 
03701    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
03702    
03703    if (!dir)
03704       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
03705    else
03706       ast_copy_string(fromdir, dir, sizeof(fromdir));
03707 
03708    make_file(frompath, sizeof(frompath), fromdir, msgnum);
03709 
03710    if (vm_lock_path(todir))
03711       return ERROR_LOCK_PATH;
03712 
03713    recipmsgnum = 0;
03714    do {
03715       make_file(topath, sizeof(topath), todir, recipmsgnum);
03716       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
03717          break;
03718       recipmsgnum++;
03719    } while (recipmsgnum < recip->maxmsg);
03720    if (recipmsgnum < recip->maxmsg) {
03721       if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
03722          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
03723       } else {
03724          /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL
03725           * copy will fail. Instead, we need to create a local copy, store it, and delete the local
03726           * copy. We don't have to #ifdef this because if file storage reaches this point, there's a
03727           * much worse problem happening and IMAP storage doesn't call this function
03728           */
03729          copy_plain_file(frompath, topath);
03730          STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL);
03731          vm_delete(topath);
03732       }
03733    } else {
03734       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
03735    }
03736    ast_unlock_path(todir);
03737    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03738    
03739    return 0;
03740 }

static void copy_plain_file ( char *  frompath,
char *  topath 
) [static]

Definition at line 2852 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message(), and forward_message().

02853 {
02854    char frompath2[PATH_MAX], topath2[PATH_MAX];
02855    ast_filecopy(frompath, topath, NULL);
02856    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
02857    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
02858    copy(frompath2, topath2);
02859 }

static int count_messages ( struct ast_vm_user vmu,
char *  dir 
) [static]

Definition at line 2718 of file app_voicemail.c.

References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().

Referenced by leave_voicemail(), and open_mailbox().

02719 {
02720    /* Find all .txt files - even if they are not in sequence from 0000 */
02721 
02722    int vmcount = 0;
02723    DIR *vmdir = NULL;
02724    struct dirent *vment = NULL;
02725 
02726    if (vm_lock_path(dir))
02727       return ERROR_LOCK_PATH;
02728 
02729    if ((vmdir = opendir(dir))) {
02730       while ((vment = readdir(vmdir))) {
02731          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02732             vmcount++;
02733       }
02734       closedir(vmdir);
02735    }
02736    ast_unlock_path(dir);
02737    
02738    return vmcount;
02739 }

static int create_dirpath ( char *  dest,
int  len,
const char *  context,
const char *  ext,
const char *  folder 
) [static]

basically mkdir -p $dest/$context/$ext/$folder

Parameters:
dest String. base directory.
len Length of dest.
context String. Ignored if is null or empty string.
ext String. Ignored if is null or empty string.
folder String. Ignored if is null or empty string.
Returns:
-1 on failure, 0 on success.

Definition at line 946 of file app_voicemail.c.

References ast_log(), ast_strlen_zero(), errno, LOG_WARNING, make_dir(), and VOICEMAIL_DIR_MODE.

Referenced by copy_message(), forward_message(), invent_message(), leave_voicemail(), make_email_file(), open_mailbox(), save_to_folder(), vm_execmain(), and vm_tempgreeting().

00947 {
00948    mode_t   mode = VOICEMAIL_DIR_MODE;
00949 
00950    if (!ast_strlen_zero(context)) {
00951       make_dir(dest, len, context, "", "");
00952       if (mkdir(dest, mode) && errno != EEXIST) {
00953          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00954          return -1;
00955       }
00956    }
00957    if (!ast_strlen_zero(ext)) {
00958       make_dir(dest, len, context, ext, "");
00959       if (mkdir(dest, mode) && errno != EEXIST) {
00960          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00961          return -1;
00962       }
00963    }
00964    if (!ast_strlen_zero(folder)) {
00965       make_dir(dest, len, context, ext, folder);
00966       if (mkdir(dest, mode) && errno != EEXIST) {
00967          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00968          return -1;
00969       }
00970    }
00971    return 0;
00972 }

static int dialout ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  num,
char *  outgoing_context 
) [static]

Definition at line 8752 of file app_voicemail.c.

References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verbose(), ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.

Referenced by advanced_options(), and vm_execmain().

08753 {
08754    int cmd = 0;
08755    char destination[80] = "";
08756    int retries = 0;
08757 
08758    if (!num) {
08759       if (option_verbose > 2)
08760          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
08761       while (retries < 3 && cmd != 't') {
08762          destination[1] = '\0';
08763          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
08764          if (!cmd)
08765             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
08766          if (!cmd)
08767             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
08768          if (!cmd) {
08769             cmd = ast_waitfordigit(chan, 6000);
08770             if (cmd)
08771                destination[0] = cmd;
08772          }
08773          if (!cmd) {
08774             retries++;
08775          } else {
08776 
08777             if (cmd < 0)
08778                return 0;
08779             if (cmd == '*') {
08780                if (option_verbose > 2)
08781                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
08782                return 0;
08783             }
08784             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08785                retries++;
08786             else
08787                cmd = 't';
08788          }
08789       }
08790       if (retries >= 3) {
08791          return 0;
08792       }
08793       
08794    } else {
08795       if (option_verbose > 2)
08796          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08797       ast_copy_string(destination, num, sizeof(destination));
08798    }
08799 
08800    if (!ast_strlen_zero(destination)) {
08801       if (destination[strlen(destination) -1 ] == '*')
08802          return 0; 
08803       if (option_verbose > 2)
08804          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08805       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08806       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08807       chan->priority = 0;
08808       return 9;
08809    }
08810    return 0;
08811 }

static char* encode_mime_str ( const char *  start,
char *  end,
size_t  endsize,
size_t  preamble,
size_t  postamble 
) [static]

Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.

Additionally, if the encoded string would exceed the MIME limit of 76 characters per line, then the encoding will be broken up into multiple sections, separated by a space character, in order to facilitate breaking up the associated header across multiple lines.

Parameters:
start A string to be encoded
end An expandable buffer for holding the result
preamble The length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars.
postamble the length of any additional characters appended to the line, used to ensure proper field wrapping.
Return values:
The encoded string.

Definition at line 3083 of file app_voicemail.c.

Referenced by make_email_file().

03084 {
03085    char tmp[80];
03086    int first_section = 1;
03087    size_t endlen = 0, tmplen = 0;
03088    *end = '\0';
03089 
03090    tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03091    for (; *start; start++) {
03092       int need_encoding = 0;
03093       if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
03094          need_encoding = 1;
03095       }
03096       if ((first_section && need_encoding && preamble + tmplen > 70) ||
03097          (first_section && !need_encoding && preamble + tmplen > 72) ||
03098          (!first_section && need_encoding && tmplen > 70) ||
03099          (!first_section && !need_encoding && tmplen > 72)) {
03100          /* Start new line */
03101          endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp);
03102          tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03103          first_section = 0;
03104       }
03105       if (need_encoding && *start == ' ') {
03106          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
03107       } else if (need_encoding) {
03108          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start);
03109       } else {
03110          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start);
03111       }
03112    }
03113    snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
03114    return end;
03115 }

static struct ast_vm_user* find_or_create ( char *  context,
char *  mbox 
) [static]

Definition at line 7843 of file app_voicemail.c.

References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::list, ast_vm_user::mailbox, and VM_SEARCH.

Referenced by append_mailbox(), and load_config().

07844 {
07845    struct ast_vm_user *vmu;
07846    AST_LIST_TRAVERSE(&users, vmu, list) {
07847       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
07848          if (strcasecmp(vmu->context, context)) {
07849             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
07850                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
07851                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
07852                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
07853          }
07854          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
07855          return NULL;
07856       }
07857       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
07858          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
07859          return NULL;
07860       }
07861    }
07862    
07863    if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07864       ast_copy_string(vmu->context, context, sizeof(vmu->context));
07865       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07866       AST_LIST_INSERT_TAIL(&users, vmu, list);
07867    }
07868    return vmu;
07869 }

static struct ast_vm_user* find_user ( struct ast_vm_user ivm,
const char *  context,
const char *  mailbox 
) [static]

Definition at line 779 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_test_flag, find_user_realtime(), globalflags, ast_vm_user::list, VM_ALLOCED, and VM_SEARCH.

00780 {
00781    /* This function could be made to generate one from a database, too */
00782    struct ast_vm_user *vmu=NULL, *cur;
00783    AST_LIST_LOCK(&users);
00784 
00785    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00786       context = "default";
00787 
00788    AST_LIST_TRAVERSE(&users, cur, list) {
00789       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00790          break;
00791       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00792          break;
00793    }
00794    if (cur) {
00795       /* Make a copy, so that on a reload, we have no race */
00796       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00797          memcpy(vmu, cur, sizeof(*vmu));
00798          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00799          AST_LIST_NEXT(vmu, list) = NULL;
00800       }
00801    } else
00802       vmu = find_user_realtime(ivm, context, mailbox);
00803    AST_LIST_UNLOCK(&users);
00804    return vmu;
00805 }

static struct ast_vm_user* find_user_realtime ( struct ast_vm_user ivm,
const char *  context,
const char *  mailbox 
) [static]

Definition at line 750 of file app_voicemail.c.

References apply_options_full(), ast_calloc, ast_copy_string(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free, globalflags, populate_defaults(), var, VM_ALLOCED, and VM_SEARCH.

Referenced by find_user().

00751 {
00752    struct ast_variable *var;
00753    struct ast_vm_user *retval;
00754 
00755    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00756       if (!ivm)
00757          ast_set_flag(retval, VM_ALLOCED);   
00758       else
00759          memset(retval, 0, sizeof(*retval));
00760       if (mailbox) 
00761          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00762       populate_defaults(retval);
00763       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00764          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00765       else
00766          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00767       if (var) {
00768          apply_options_full(retval, var);
00769          ast_variables_destroy(var);
00770       } else { 
00771          if (!ivm) 
00772             free(retval);
00773          retval = NULL;
00774       }  
00775    } 
00776    return retval;
00777 }

static int forward_message ( struct ast_channel chan,
char *  context,
struct vm_state vms,
struct ast_vm_user sender,
char *  fmt,
int  flag,
signed char  record_gain 
) [static]

Definition at line 5064 of file app_voicemail.c.

References app, ast_clear_flag, ast_copy_string(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), copy_plain_file(), create_dirpath(), vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_channel::language, leave_voicemail(), ast_app::list, LOG_ERROR, ast_vm_user::mailbox, make_file(), pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, username, VM_ATTACH, vm_delete(), VM_DIRECFORWARD, and vm_forwardoptions().

Referenced by vm_execmain().

05065 {
05066 #ifdef IMAP_STORAGE
05067    int todircount=0;
05068    struct vm_state *dstvms;
05069 #endif
05070    char username[70]="";
05071    int res = 0, cmd = 0;
05072    struct ast_vm_user *receiver = NULL, *vmtmp;
05073    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
05074    char *stringp;
05075    const char *s;
05076    int saved_messages = 0, found = 0;
05077    int valid_extensions = 0;
05078    char *dir;
05079    int curmsg;
05080 
05081    if (vms == NULL) return -1;
05082    dir = vms->curdir;
05083    curmsg = vms->curmsg;
05084    
05085    while (!res && !valid_extensions) {
05086       int use_directory = 0;
05087       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
05088          int done = 0;
05089          int retries = 0;
05090          cmd=0;
05091          while ((cmd >= 0) && !done ){
05092             if (cmd)
05093                retries = 0;
05094             switch (cmd) {
05095             case '1': 
05096                use_directory = 0;
05097                done = 1;
05098                break;
05099             case '2': 
05100                use_directory = 1;
05101                done=1;
05102                break;
05103             case '*': 
05104                cmd = 't';
05105                done = 1;
05106                break;
05107             default: 
05108                /* Press 1 to enter an extension press 2 to use the directory */
05109                cmd = ast_play_and_wait(chan,"vm-forward");
05110                if (!cmd)
05111                   cmd = ast_waitfordigit(chan,3000);
05112                if (!cmd)
05113                   retries++;
05114                if (retries > 3)
05115                {
05116                   cmd = 't';
05117                   done = 1;
05118                }
05119                
05120             }
05121          }
05122          if (cmd < 0 || cmd == 't')
05123             break;
05124       }
05125       
05126       if (use_directory) {
05127          /* use app_directory */
05128          
05129          char old_context[sizeof(chan->context)];
05130          char old_exten[sizeof(chan->exten)];
05131          int old_priority;
05132          struct ast_app* app;
05133 
05134          
05135          app = pbx_findapp("Directory");
05136          if (app) {
05137             char vmcontext[256];
05138             /* make backup copies */
05139             memcpy(old_context, chan->context, sizeof(chan->context));
05140             memcpy(old_exten, chan->exten, sizeof(chan->exten));
05141             old_priority = chan->priority;
05142             
05143             /* call the the Directory, changes the channel */
05144             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
05145             res = pbx_exec(chan, app, vmcontext);
05146             
05147             ast_copy_string(username, chan->exten, sizeof(username));
05148             
05149             /* restore the old context, exten, and priority */
05150             memcpy(chan->context, old_context, sizeof(chan->context));
05151             memcpy(chan->exten, old_exten, sizeof(chan->exten));
05152             chan->priority = old_priority;
05153             
05154          } else {
05155             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
05156             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
05157          }
05158       } else {
05159          /* Ask for an extension */
05160          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
05161          if (res)
05162             break;
05163          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
05164             break;
05165       }
05166       
05167       /* start all over if no username */
05168       if (ast_strlen_zero(username))
05169          continue;
05170       stringp = username;
05171       s = strsep(&stringp, "*");
05172       /* start optimistic */
05173       valid_extensions = 1;
05174       while (s) {
05175          /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1).  find_user is going to malloc since we have a NULL as first argument */
05176          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
05177             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
05178             found++;
05179          } else {
05180             valid_extensions = 0;
05181             break;
05182          }
05183          s = strsep(&stringp, "*");
05184       }
05185       /* break from the loop of reading the extensions */
05186       if (valid_extensions)
05187          break;
05188       /* "I am sorry, that's not a valid extension.  Please try again." */
05189       res = ast_play_and_wait(chan, "pbx-invalid");
05190    }
05191    /* check if we're clear to proceed */
05192    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
05193       return res;
05194    if (flag==1) {
05195       struct leave_vm_options leave_options;
05196       char mailbox[AST_MAX_EXTENSION * 2 + 2];
05197       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
05198       if (context)
05199          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
05200       else
05201          ast_copy_string(mailbox, username, sizeof(mailbox));
05202 
05203       /* Send VoiceMail */
05204       memset(&leave_options, 0, sizeof(leave_options));
05205       leave_options.record_gain = record_gain;
05206       cmd = leave_voicemail(chan, mailbox, &leave_options);
05207    } else {
05208       /* Forward VoiceMail */
05209       long duration = 0;
05210       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
05211       struct vm_state vmstmp;
05212 
05213       memcpy(&vmstmp, vms, sizeof(vmstmp));
05214 
05215       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
05216       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
05217       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
05218 
05219       RETRIEVE(dir, curmsg, sender);
05220 
05221       /* Alter a surrogate file, only */
05222       copy_plain_file(origmsgfile, msgfile);
05223 
05224       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05225       if (!cmd) {
05226          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05227 #ifdef IMAP_STORAGE
05228             char *myserveremail;
05229             int attach_user_voicemail;
05230             /* get destination mailbox */
05231             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
05232             if (!dstvms) {
05233                dstvms = create_vm_state_from_user(vmtmp);
05234             }
05235             if (dstvms) {
05236                init_mailstream(dstvms, 0);
05237                if (!dstvms->mailstream) {
05238                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
05239                } else {
05240                   STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05241                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
05242                }
05243             } else {
05244                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
05245             }
05246             myserveremail = serveremail;
05247             if (!ast_strlen_zero(vmtmp->serveremail))
05248                myserveremail = vmtmp->serveremail;
05249             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05250             /* NULL category for IMAP storage */
05251             sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
05252 #else
05253             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
05254 #endif
05255             saved_messages++;
05256             AST_LIST_REMOVE_CURRENT(&extensions, list);
05257             free_user(vmtmp);
05258             if (res)
05259                break;
05260          }
05261          AST_LIST_TRAVERSE_SAFE_END;
05262          if (saved_messages > 0) {
05263             /* give confirmation that the message was saved */
05264             /* commented out since we can't forward batches yet
05265             if (saved_messages == 1)
05266                res = ast_play_and_wait(chan, "vm-message");
05267             else
05268                res = ast_play_and_wait(chan, "vm-messages");
05269             if (!res)
05270                res = ast_play_and_wait(chan, "vm-saved"); */
05271             res = ast_play_and_wait(chan, "vm-msgsaved");
05272          }  
05273       }
05274 
05275       /* Remove surrogate file */
05276       vm_delete(msgfile);
05277       DISPOSE(dir, curmsg);
05278    }
05279 
05280    /* If anything failed above, we still have this list to free */
05281    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
05282       free_user(vmtmp);
05283    return res ? res : cmd;
05284 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 991 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

Referenced by forward_message(), free_vm_users(), leave_voicemail(), and vm_execmain().

00992 {
00993    if (ast_test_flag(vmu, VM_ALLOCED))
00994       free(vmu);
00995 }

static void free_vm_users ( void   )  [static]

Definition at line 8104 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), free_zone(), vm_zone::list, and VM_ALLOCED.

Referenced by load_config().

08105 {
08106    struct ast_vm_user *cur;
08107    struct vm_zone *zcur;
08108 
08109    AST_LIST_LOCK(&users);
08110    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
08111       ast_set_flag(cur, VM_ALLOCED);
08112       free_user(cur);
08113    }
08114    AST_LIST_UNLOCK(&users);
08115 
08116    AST_LIST_LOCK(&zones);
08117    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
08118       free_zone(zcur);
08119    }
08120    AST_LIST_UNLOCK(&zones);
08121 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3536 of file app_voicemail.c.

References free.

03537 {
03538    free(z);
03539 }

static int get_date ( char *  s,
int  len 
) [static]

Definition at line 3469 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03470 {
03471    struct tm tm;
03472    time_t t;
03473 
03474    time(&t);
03475 
03476    ast_localtime(&t, &tm, NULL);
03477 
03478    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03479 }

static int get_folder ( struct ast_channel chan,
int  start 
) [static]

Definition at line 4862 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().

Referenced by get_folder2().

04863 {
04864    int x;
04865    int d;
04866    char fn[PATH_MAX];
04867    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
04868    if (d)
04869       return d;
04870    for (x = start; x< 5; x++) {  /* For all folders */
04871       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
04872          return d;
04873       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
04874       if (d)
04875          return d;
04876       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
04877       d = vm_play_folder_name(chan, fn);
04878       if (d)
04879          return d;
04880       d = ast_waitfordigit(chan, 500);
04881       if (d)
04882          return d;
04883    }
04884    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
04885    if (d)
04886       return d;
04887    d = ast_waitfordigit(chan, 4000);
04888    return d;
04889 }

static int get_folder2 ( struct ast_channel chan,
char *  fn,
int  start 
) [static]

Definition at line 4891 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

04892 {
04893    int res = 0;
04894    res = ast_play_and_wait(chan, fn);  /* Folder name */
04895    while (((res < '0') || (res > '9')) &&
04896          (res != '#') && (res >= 0)) {
04897       res = get_folder(chan, 0);
04898    }
04899    return res;
04900 }

static int handle_voicemail_show_users ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 7990 of file app_voicemail.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::fullname, inboxcount(), ast_vm_user::list, ast_vm_user::mailbox, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_vm_user::zonetag.

07991 {
07992    struct ast_vm_user *vmu;
07993    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
07994 
07995    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
07996    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
07997 
07998    AST_LIST_LOCK(&users);
07999    if (!AST_LIST_EMPTY(&users)) {
08000       if (argc == 3)
08001          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08002       else {
08003          int count = 0;
08004          AST_LIST_TRAVERSE(&users, vmu, list) {
08005             if (!strcmp(argv[4],vmu->context))
08006                count++;
08007          }
08008          if (count) {
08009             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08010          } else {
08011             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
08012             AST_LIST_UNLOCK(&users);
08013             return RESULT_FAILURE;
08014          }
08015       }
08016       AST_LIST_TRAVERSE(&users, vmu, list) {
08017          int newmsgs = 0, oldmsgs = 0;
08018          char count[12], tmp[256] = "";
08019 
08020          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
08021             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08022             inboxcount(tmp, &newmsgs, &oldmsgs);
08023             snprintf(count,sizeof(count),"%d",newmsgs);
08024             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08025          }
08026       }
08027    } else {
08028       ast_cli(fd, "There are no voicemail users currently defined\n");
08029       AST_LIST_UNLOCK(&users);
08030       return RESULT_FAILURE;
08031    }
08032    AST_LIST_UNLOCK(&users);
08033    return RESULT_SUCCESS;
08034 }

static int handle_voicemail_show_zones ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 8036 of file app_voicemail.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, vm_zone::list, vm_zone::msg_format, vm_zone::name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and vm_zone::timezone.

08037 {
08038    struct vm_zone *zone;
08039    char *output_format = "%-15s %-20s %-45s\n";
08040    int res = RESULT_SUCCESS;
08041 
08042    if (argc != 3)
08043       return RESULT_SHOWUSAGE;
08044 
08045    AST_LIST_LOCK(&zones);
08046    if (!AST_LIST_EMPTY(&zones)) {
08047       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
08048       AST_LIST_TRAVERSE(&zones, zone, list) {
08049          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
08050       }
08051    } else {
08052       ast_cli(fd, "There are no voicemail zones currently defined\n");
08053       res = RESULT_FAILURE;
08054    }
08055    AST_LIST_UNLOCK(&zones);
08056 
08057    return res;
08058 }

static int has_voicemail ( const char *  mailbox,
const char *  folder 
) [static]

Definition at line 3780 of file app_voicemail.c.

References __has_voicemail(), and ast_copy_string().

03781 {
03782    char tmp[256], *tmp2 = tmp, *mbox, *context;
03783    ast_copy_string(tmp, mailbox, sizeof(tmp));
03784    while ((mbox = strsep(&tmp2, ","))) {
03785       if ((context = strchr(mbox, '@')))
03786          *context++ = '\0';
03787       else
03788          context = "default";
03789       if (__has_voicemail(context, mbox, folder, 1))
03790          return 1;
03791    }
03792    return 0;
03793 }

static int inboxcount ( const char *  mailbox,
int *  newmsgs,
int *  oldmsgs 
) [static]

Definition at line 3796 of file app_voicemail.c.

References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().

Referenced by handle_voicemail_show_users(), leave_voicemail(), load_module(), and run_externnotify().

03797 {
03798    char tmp[256];
03799    char *context;
03800 
03801    if (newmsgs)
03802       *newmsgs = 0;
03803    if (oldmsgs)
03804       *oldmsgs = 0;
03805    /* If no mailbox, return immediately */
03806    if (ast_strlen_zero(mailbox))
03807       return 0;
03808    if (strchr(mailbox, ',')) {
03809       int tmpnew, tmpold;
03810       char *mb, *cur;
03811 
03812       ast_copy_string(tmp, mailbox, sizeof(tmp));
03813       mb = tmp;
03814       while ((cur = strsep(&mb, ", "))) {
03815          if (!ast_strlen_zero(cur)) {
03816             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
03817                return -1;
03818             else {
03819                if (newmsgs)
03820                   *newmsgs += tmpnew; 
03821                if (oldmsgs)
03822                   *oldmsgs += tmpold;
03823             }
03824          }
03825       }
03826       return 0;
03827    }
03828    ast_copy_string(tmp, mailbox, sizeof(tmp));
03829    context = strchr(tmp, '@');
03830    if (context) {
03831       *context = '\0';
03832       context++;
03833    } else
03834       context = "default";
03835    if (newmsgs)
03836       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
03837    if (oldmsgs)
03838       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
03839    return 0;
03840 }

static int inbuf ( struct baseio bio,
FILE *  fi 
) [static]

Definition at line 2876 of file app_voicemail.c.

References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.

Referenced by inchar(), and sip_addheader().

02877 {
02878    int l;
02879 
02880    if (bio->ateof)
02881       return 0;
02882 
02883    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
02884       if (ferror(fi))
02885          return -1;
02886 
02887       bio->ateof = 1;
02888       return 0;
02889    }
02890 
02891    bio->iolen= l;
02892    bio->iocp= 0;
02893 
02894    return 1;
02895 }

static int inchar ( struct baseio bio,
FILE *  fi 
) [static]

Definition at line 2897 of file app_voicemail.c.

References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.

Referenced by base_encode().

02898 {
02899    if (bio->iocp>=bio->iolen) {
02900       if (!inbuf(bio, fi))
02901          return EOF;
02902    }
02903 
02904    return bio->iobuf[bio->iocp++];
02905 }

static int invent_message ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  ext,
int  busy,
char *  ecodes 
) [static]

Definition at line 3507 of file app_voicemail.c.

References ast_log(), ast_say_digit_str(), ast_stream_and_wait(), ast_vm_user::context, create_dirpath(), ast_channel::language, and play_greeting().

Referenced by leave_voicemail().

03508 {
03509    int res;
03510    char fn[PATH_MAX];
03511    char dest[PATH_MAX];
03512 
03513    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
03514 
03515    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
03516       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
03517       return -1;
03518    }
03519 
03520    res = play_greeting(chan, vmu, fn, ecodes);
03521    if (res == -2) {
03522       /* File did not exist */
03523       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
03524       if (res)
03525          return res;
03526       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
03527    }
03528 
03529    if (res)
03530       return res;
03531 
03532    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
03533    return res;
03534 }

static int last_message_index ( struct ast_vm_user vmu,
char *  dir 
) [static]

Definition at line 2756 of file app_voicemail.c.

References ast_fileexists(), ast_unlock_path(), ERROR_LOCK_PATH, make_file(), ast_vm_user::maxmsg, and vm_lock_path().

Referenced by open_mailbox().

02757 {
02758    int x;
02759    char fn[PATH_MAX];
02760 
02761    if (vm_lock_path(dir))
02762       return ERROR_LOCK_PATH;
02763 
02764    for (x = 0; x < vmu->maxmsg; x++) {
02765       make_file(fn, sizeof(fn), dir, x);
02766       if (ast_fileexists(fn, NULL, NULL) < 1)
02767          break;
02768    }
02769    ast_unlock_path(dir);
02770 
02771    return x - 1;
02772 }

static int leave_voicemail ( struct ast_channel chan,
char *  ext,
struct leave_vm_options options 
) [static]

Definition at line 3891 of file app_voicemail.c.

References ast_callerid_merge(), ast_copy_string(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_goto_if_exists(), ast_log(), ast_opt_priority_jumping, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, EXISTS, ast_vm_user::exit, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), INTRO, invent_message(), ast_channel::language, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_channel::name, vm_state::newmessages, notify_new_message(), OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_SILENT, OPT_UNAVAIL_GREETING, option_debug, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_greeting(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, S_OR, STORE, transfer, VERBOSE_PREFIX_3, vm_lock_path(), VM_OPERATOR, and VOICEMAIL_FILE_MODE.

Referenced by advanced_options(), forward_message(), and vm_exec().

03892 {
03893 #ifdef IMAP_STORAGE
03894    int newmsgs, oldmsgs;
03895 #endif
03896    struct vm_state *vms = NULL;
03897    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
03898    char callerid[256];
03899    FILE *txt;
03900    char date[256];
03901    int txtdes;
03902    int res = 0;
03903    int msgnum;
03904    int duration = 0;
03905    int ausemacro = 0;
03906    int ousemacro = 0;
03907    int ouseexten = 0;
03908    char dir[PATH_MAX], tmpdir[PATH_MAX];
03909    char dest[PATH_MAX];
03910    char fn[PATH_MAX];
03911    char prefile[PATH_MAX] = "";
03912    char tempfile[PATH_MAX] = "";
03913    char ext_context[256] = "";
03914    char fmt[80];
03915    char *context;
03916    char ecodes[16] = "#";
03917    char tmp[1024] = "", *tmpptr;
03918    struct ast_vm_user *vmu;
03919    struct ast_vm_user svm;
03920    const char *category = NULL;
03921 
03922    ast_copy_string(tmp, ext, sizeof(tmp));
03923    ext = tmp;
03924    context = strchr(tmp, '@');
03925    if (context) {
03926       *context++ = '\0';
03927       tmpptr = strchr(context, '&');
03928    } else {
03929       tmpptr = strchr(ext, '&');
03930    }
03931 
03932    if (tmpptr)
03933       *tmpptr++ = '\0';
03934 
03935    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
03936 
03937    if (option_debug > 2)
03938       ast_log(LOG_DEBUG, "Before find_user\n");
03939    if (!(vmu = find_user(&svm, context, ext))) {
03940       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
03941       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
03942          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
03943       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03944       return res;
03945    }
03946    /* Setup pre-file if appropriate */
03947    if (strcmp(vmu->context, "default"))
03948       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
03949    else
03950       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
03951    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
03952       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
03953       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
03954    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
03955       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
03956       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
03957    }
03958    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
03959    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
03960       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
03961       return -1;
03962    }
03963    RETRIEVE(tempfile, -1, vmu);
03964    if (ast_fileexists(tempfile, NULL, NULL) > 0)
03965       ast_copy_string(prefile, tempfile, sizeof(prefile));
03966    DISPOSE(tempfile, -1);
03967    /* It's easier just to try to make it than to check for its existence */
03968    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
03969    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
03970 
03971    /* Check current or macro-calling context for special extensions */
03972    if (ast_test_flag(vmu, VM_OPERATOR)) {
03973       if (!ast_strlen_zero(vmu->exit)) {
03974          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
03975             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
03976             ouseexten = 1;
03977          }
03978       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
03979          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
03980          ouseexten = 1;
03981       }
03982       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
03983       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
03984       ousemacro = 1;
03985       }
03986    }
03987 
03988    if (!ast_strlen_zero(vmu->exit)) {
03989       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
03990          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
03991    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
03992       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
03993    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
03994       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
03995       ausemacro = 1;
03996    }
03997 
03998    /* Play the beginning intro if desired */
03999    if (!ast_strlen_zero(prefile)) {
04000       res = play_greeting(chan, vmu, prefile, ecodes);
04001       if (res == -2) {
04002          /* The file did not exist */
04003          if (option_debug)
04004             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
04005          res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
04006       }
04007       if (res < 0) {
04008          if (option_debug)
04009             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
04010          free_user(vmu);
04011          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04012          return -1;
04013       }
04014    }
04015    if (res == '#') {
04016       /* On a '#' we skip the instructions */
04017       ast_set_flag(options, OPT_SILENT);
04018       res = 0;
04019    }
04020    if (!res && !ast_test_flag(options, OPT_SILENT)) {
04021       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
04022       if (res == '#') {
04023          ast_set_flag(options, OPT_SILENT);
04024          res = 0;
04025       }
04026    }
04027    if (res > 0)
04028       ast_stopstream(chan);
04029    /* Check for a '*' here in case the caller wants to escape from voicemail to something
04030     other than the operator -- an automated attendant or mailbox login for example */
04031    if (res == '*') {
04032       chan->exten[0] = 'a';
04033       chan->exten[1] = '\0';
04034       if (!ast_strlen_zero(vmu->exit)) {
04035          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04036       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
04037          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04038       }
04039       chan->priority = 0;
04040       free_user(vmu);
04041       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04042       return 0;
04043    }
04044 
04045    /* Check for a '0' here */
04046    if (res == '0') {
04047    transfer:
04048       if (ouseexten || ousemacro) {
04049          chan->exten[0] = 'o';
04050          chan->exten[1] = '\0';
04051          if (!ast_strlen_zero(vmu->exit)) {
04052             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04053          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
04054             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04055          }
04056          ast_play_and_wait(chan, "transfer");
04057          chan->priority = 0;
04058          free_user(vmu);
04059          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04060       }
04061       return 0;
04062    }
04063    if (res < 0) {
04064       free_user(vmu);
04065       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04066       return -1;
04067    }
04068    /* The meat of recording the message...  All the announcements and beeps have been played*/
04069    ast_copy_string(fmt, vmfmts, sizeof(fmt));
04070    if (!ast_strlen_zero(fmt)) {
04071       msgnum = 0;
04072 
04073 #ifdef IMAP_STORAGE
04074       /* Is ext a mailbox? */
04075       /* must open stream for this user to get info! */
04076       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
04077       if (res < 0) {
04078          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
04079          return -1;
04080       }
04081       if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) {
04082       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
04083        * rarely be used*/
04084          if (!(vms = create_vm_state_from_user(vmu))) {
04085             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
04086             return -1;
04087          }
04088       }
04089       vms->newmessages++;
04090       /* here is a big difference! We add one to it later */
04091       msgnum = newmsgs + oldmsgs;
04092       if (option_debug > 2)
04093          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
04094       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
04095       /* set variable for compatability */
04096       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04097 
04098       /* Check if mailbox is full */
04099       check_quota(vms, imapfolder);
04100       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
04101          if (option_debug)
04102             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
04103          ast_play_and_wait(chan, "vm-mailboxfull");
04104          return -1;
04105       }
04106       if (option_debug > 2)
04107          ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
04108       if (msgnum >= vmu->maxmsg) {
04109          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04110          if (!res)
04111             res = ast_waitstream(chan, "");
04112          ast_log(LOG_WARNING, "No more messages possible\n");
04113          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04114          goto leave_vm_out;
04115       }
04116 
04117       /* Check if we have exceeded maxmsg */
04118       if (msgnum >= vmu->maxmsg) {
04119          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
04120          ast_play_and_wait(chan, "vm-mailboxfull");
04121          return -1;
04122       }
04123 #else
04124       if (count_messages(vmu, dir) >= vmu->maxmsg) {
04125          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04126          if (!res)
04127             res = ast_waitstream(chan, "");
04128          ast_log(LOG_WARNING, "No more messages possible\n");
04129          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04130          goto leave_vm_out;
04131       }
04132 
04133 #endif
04134       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
04135       txtdes = mkstemp(tmptxtfile);
04136       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
04137       if (txtdes < 0) {
04138          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04139          if (!res)
04140             res = ast_waitstream(chan, "");
04141          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
04142          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04143          goto leave_vm_out;
04144       }
04145 
04146       /* Now play the beep once we have the message number for our next message. */
04147       if (res >= 0) {
04148          /* Unless we're *really* silent, try to send the beep */
04149          res = ast_stream_and_wait(chan, "beep", chan->language, "");
04150       }
04151             
04152       /* Store information */
04153       txt = fdopen(txtdes, "w+");
04154       if (txt) {
04155          get_date(date, sizeof(date));
04156          fprintf(txt, 
04157             ";\n"
04158             "; Message Information file\n"
04159             ";\n"
04160             "[message]\n"
04161             "origmailbox=%s\n"
04162             "context=%s\n"
04163             "macrocontext=%s\n"
04164             "exten=%s\n"
04165             "priority=%d\n"
04166             "callerchan=%s\n"
04167             "callerid=%s\n"
04168             "origdate=%s\n"
04169             "origtime=%ld\n"
04170             "category=%s\n",
04171             ext,
04172             chan->context,
04173             chan->macrocontext, 
04174             chan->exten,
04175             chan->priority,
04176             chan->name,
04177             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
04178             date, (long)time(NULL),
04179             category ? category : ""); 
04180       } else
04181          ast_log(LOG_WARNING, "Error opening text file for output\n");
04182       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
04183 
04184       if (txt) {
04185          if (duration < vmminmessage) {
04186             fclose(txt);
04187             if (option_verbose > 2) 
04188                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
04189             ast_filedelete(tmptxtfile, NULL);
04190             unlink(tmptxtfile);
04191          } else {
04192             fprintf(txt, "duration=%d\n", duration);
04193             fclose(txt);
04194             if (vm_lock_path(dir)) {
04195                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
04196                /* Delete files */
04197                ast_filedelete(tmptxtfile, NULL);
04198                unlink(tmptxtfile);
04199             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
04200                if (option_debug) 
04201                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
04202                unlink(tmptxtfile);
04203                ast_unlock_path(dir);
04204             } else {
04205                for (;;) {
04206                   make_file(fn, sizeof(fn), dir, msgnum);
04207                   if (!EXISTS(dir, msgnum, fn, NULL))
04208                      break;
04209                   msgnum++;
04210                }
04211 
04212                /* assign a variable with the name of the voicemail file */ 
04213 #ifndef IMAP_STORAGE
04214                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
04215 #else
04216                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04217 #endif
04218 
04219                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
04220                ast_filerename(tmptxtfile, fn, NULL);
04221                rename(tmptxtfile, txtfile);
04222 
04223                ast_unlock_path(dir);
04224                /* We must store the file first, before copying the message, because
04225                 * ODBC storage does the entire copy with SQL.
04226                 */
04227                if (ast_fileexists(fn, NULL, NULL) > 0) {
04228                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
04229                }
04230 
04231                /* Are there to be more recipients of this message? */
04232                while (tmpptr) {
04233                   struct ast_vm_user recipu, *recip;
04234                   char *exten, *context;
04235                
04236                   exten = strsep(&tmpptr, "&");
04237                   context = strchr(exten, '@');
04238                   if (context) {
04239                      *context = '\0';
04240                      context++;
04241                   }
04242                   if ((recip = find_user(&recipu, context, exten))) {
04243                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
04244                      free_user(recip);
04245                   }
04246                }
04247                /* Notification and disposal needs to happen after the copy, though. */
04248                if (ast_fileexists(fn, NULL, NULL)) {
04249                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04250                   DISPOSE(dir, msgnum);
04251                }
04252             }
04253          }
04254       }
04255       if (res == '0') {
04256          goto transfer;
04257       } else if (res > 0)
04258          res = 0;
04259 
04260       if (duration < vmminmessage)
04261          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
04262          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04263       else
04264          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
04265    } else
04266       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
04267 leave_vm_out:
04268    free_user(vmu);
04269    
04270    return res;
04271 }

static int load_config ( void   )  [static]

Definition at line 8123 of file app_voicemail.c.

References append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_config_option(), ast_copy_string(), ast_false(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_malloc, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, find_or_create(), free, free_vm_users(), globalflags, vm_zone::list, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, vm_zone::msg_format, option_debug, populate_defaults(), s, SENDMAIL, smdi_iface, vm_zone::timezone, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.

08124 {
08125    struct ast_vm_user *cur;
08126    struct ast_config *cfg, *ucfg;
08127    char *cat;
08128    struct ast_variable *var;
08129    const char *notifystr = NULL;
08130    const char *smdistr = NULL;
08131    const char *astattach;
08132    const char *astsearch;
08133    const char *astsaycid;
08134    const char *send_voicemail;
08135 #ifdef IMAP_STORAGE
08136    const char *imap_server;
08137    const char *imap_port;
08138    const char *imap_flags;
08139    const char *imap_folder;
08140    const char *auth_user;
08141    const char *auth_password;
08142    const char *expunge_on_hangup;
08143    const char *imap_timeout;
08144 #endif
08145    const char *astcallop;
08146    const char *astreview;
08147    const char *asttempgreetwarn;
08148    const char *astskipcmd;
08149    const char *asthearenv;
08150    const char *astsaydurationinfo;
08151    const char *astsaydurationminfo;
08152    const char *silencestr;
08153    const char *maxmsgstr;
08154    const char *astdirfwd;
08155    const char *thresholdstr;
08156    const char *fmt;
08157    const char *astemail;
08158    const char *ucontext;
08159    const char *astmailcmd = SENDMAIL;
08160    const char *astforcename;
08161    const char *astforcegreet;
08162    const char *s;
08163    char *q,*stringp;
08164    const char *dialoutcxt = NULL;
08165    const char *callbackcxt = NULL;  
08166    const char *exitcxt = NULL;   
08167    const char *extpc;
08168    const char *emaildateformatstr;
08169    const char *volgainstr;
08170    int x;
08171    int tmpadsi[4];
08172 
08173    cfg = ast_config_load(VOICEMAIL_CONFIG);
08174 
08175    free_vm_users();
08176 
08177    AST_LIST_LOCK(&users);
08178 
08179    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
08180 
08181    if (cfg) {
08182       /* General settings */
08183 
08184       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
08185          ucontext = "default";
08186       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
08187       /* Attach voice message to mail message ? */
08188       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
08189          astattach = "yes";
08190       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
08191 
08192       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
08193          astsearch = "no";
08194       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
08195 
08196       volgain = 0.0;
08197       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
08198          sscanf(volgainstr, "%lf", &volgain);
08199 
08200 #ifdef ODBC_STORAGE
08201       strcpy(odbc_database, "asterisk");
08202       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
08203          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
08204       }
08205       strcpy(odbc_table, "voicemessages");
08206       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
08207          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
08208       }
08209 #endif      
08210       /* Mail command */
08211       strcpy(mailcmd, SENDMAIL);
08212       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
08213          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
08214 
08215       maxsilence = 0;
08216       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
08217          maxsilence = atoi(silencestr);
08218          if (maxsilence > 0)
08219             maxsilence *= 1000;
08220       }
08221       
08222       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
08223          maxmsg = MAXMSG;
08224       } else {
08225          maxmsg = atoi(maxmsgstr);
08226          if (maxmsg <= 0) {
08227             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
08228             maxmsg = MAXMSG;
08229          } else if (maxmsg > MAXMSGLIMIT) {
08230             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
08231             maxmsg = MAXMSGLIMIT;
08232          }
08233       }
08234 
08235       /* Load date format config for voicemail mail */
08236       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
08237          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
08238       }
08239 
08240       /* External password changing command */
08241       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
08242          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
08243       }
08244 #ifdef IMAP_STORAGE
08245       /* IMAP server address */
08246       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
08247          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
08248       } else {
08249          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
08250       }
08251       /* IMAP server port */
08252       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
08253          ast_copy_string(imapport, imap_port, sizeof(imapport));
08254       } else {
08255          ast_copy_string(imapport,"143", sizeof(imapport));
08256       }
08257       /* IMAP server flags */
08258       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
08259          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
08260       }
08261       /* IMAP server master username */
08262       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
08263          ast_copy_string(authuser, auth_user, sizeof(authuser));
08264       }
08265       /* IMAP server master password */
08266       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
08267          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
08268       }
08269       /* Expunge on exit */
08270       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
08271          if (ast_false(expunge_on_hangup))
08272             expungeonhangup = 0;
08273          else
08274             expungeonhangup = 1;
08275       } else {
08276          expungeonhangup = 1;
08277       }
08278       /* IMAP voicemail folder */
08279       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
08280          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
08281       } else {
08282          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
08283       }
08284 
08285       /* There is some very unorthodox casting done here. This is due
08286        * to the way c-client handles the argument passed in. It expects a 
08287        * void pointer and casts the pointer directly to a long without
08288        * first dereferencing it. */
08289 
08290       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
08291          mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(imap_timeout)));
08292       } else {
08293          mail_parameters(NIL, SET_READTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08294       }
08295 
08296       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
08297          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(imap_timeout)));
08298       } else {
08299          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08300       }
08301 
08302       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
08303          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(imap_timeout)));
08304       } else {
08305          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08306       }
08307 
08308       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
08309          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(imap_timeout)));
08310       } else {
08311          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08312       }
08313 
08314 #endif
08315       /* External voicemail notify application */
08316       
08317       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
08318          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
08319          if (option_debug > 2)
08320             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
08321          if (!strcasecmp(externnotify, "smdi")) {
08322             if (option_debug)
08323                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
08324             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
08325                smdi_iface = ast_smdi_interface_find(smdistr);
08326             } else {
08327                if (option_debug)
08328                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
08329                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
08330             }
08331 
08332             if (!smdi_iface) {
08333                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
08334                externnotify[0] = '\0';
08335             }
08336          }
08337       } else {
08338          externnotify[0] = '\0';
08339       }
08340 
08341       /* Silence treshold */
08342       silencethreshold = 256;
08343       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
08344          silencethreshold = atoi(thresholdstr);
08345       
08346       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
08347          astemail = ASTERISK_USERNAME;
08348       ast_copy_string(serveremail, astemail, sizeof(serveremail));
08349       
08350       vmmaxmessage = 0;
08351       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
08352          if (sscanf(s, "%d", &x) == 1) {
08353             vmmaxmessage = x;
08354          } else {
08355             ast_log(LOG_WARNING, "Invalid max message time length\n");
08356          }
08357       }
08358 
08359       vmminmessage = 0;
08360       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
08361          if (sscanf(s, "%d", &x) == 1) {
08362             vmminmessage = x;
08363             if (maxsilence <= vmminmessage)
08364                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
08365          } else {
08366             ast_log(LOG_WARNING, "Invalid min message time length\n");
08367          }
08368       }
08369       fmt = ast_variable_retrieve(cfg, "general", "format");
08370       if (!fmt)
08371          fmt = "wav";   
08372       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
08373 
08374       skipms = 3000;
08375       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
08376          if (sscanf(s, "%d", &x) == 1) {
08377             maxgreet = x;
08378          } else {
08379             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
08380          }
08381       }
08382 
08383       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
08384          if (sscanf(s, "%d", &x) == 1) {
08385             skipms = x;
08386          } else {
08387             ast_log(LOG_WARNING, "Invalid skipms value\n");
08388          }
08389       }
08390 
08391       maxlogins = 3;
08392       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
08393          if (sscanf(s, "%d", &x) == 1) {
08394             maxlogins = x;
08395          } else {
08396             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
08397          }
08398       }
08399 
08400       /* Force new user to record name ? */
08401       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
08402          astforcename = "no";
08403       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
08404 
08405       /* Force new user to record greetings ? */
08406       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
08407          astforcegreet = "no";
08408       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
08409 
08410       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
08411          if (option_debug > 2)
08412             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
08413          stringp = ast_strdupa(s);
08414          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
08415             if (!ast_strlen_zero(stringp)) {
08416                q = strsep(&stringp,",");
08417                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
08418                   q++;
08419                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
08420                if (option_debug > 2)
08421                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
08422             } else {
08423                cidinternalcontexts[x][0] = '\0';
08424             }
08425          }
08426       }
08427       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
08428          if (option_debug)
08429             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
08430          astreview = "no";
08431       }
08432       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
08433 
08434       /*Temperary greeting reminder */
08435       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
08436          if (option_debug)
08437             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
08438          asttempgreetwarn = "no";
08439       } else {
08440          if (option_debug)
08441             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
08442       }
08443       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
08444 
08445       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
08446          if (option_debug)
08447             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
08448          astcallop = "no";
08449       }
08450       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
08451 
08452       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
08453          if (option_debug)
08454             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
08455          astsaycid = "no";
08456       } 
08457       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
08458 
08459       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
08460          if (option_debug)
08461             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
08462          send_voicemail = "no";
08463       }
08464       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
08465    
08466       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
08467          if (option_debug)
08468             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
08469          asthearenv = "yes";
08470       }
08471       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
08472 
08473       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
08474          if (option_debug)
08475             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
08476          astsaydurationinfo = "yes";
08477       }
08478       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
08479 
08480       saydurationminfo = 2;
08481       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
08482          if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
08483             saydurationminfo = x;
08484          } else {
08485             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
08486          }
08487       }
08488 
08489       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
08490          if (option_debug)
08491             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
08492          astskipcmd = "no";
08493       }
08494       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
08495 
08496       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
08497          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
08498          if (option_debug)
08499             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
08500       } else {
08501          dialcontext[0] = '\0';  
08502       }
08503       
08504       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
08505          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
08506          if (option_debug)
08507             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
08508       } else {
08509          callcontext[0] = '\0';
08510       }
08511 
08512       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
08513          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
08514          if (option_debug)
08515             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
08516       } else {
08517          exitcontext[0] = '\0';
08518       }
08519 
08520       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
08521          astdirfwd = "no";
08522       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
08523       if ((ucfg = ast_config_load("users.conf"))) {   
08524          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
08525             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
08526                continue;
08527             if ((cur = find_or_create(userscontext, cat))) {
08528                populate_defaults(cur);
08529                apply_options_full(cur, ast_variable_browse(ucfg, cat));
08530                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
08531             }
08532          }
08533          ast_config_destroy(ucfg);
08534       }
08535       cat = ast_category_browse(cfg, NULL);
08536       while (cat) {
08537          if (strcasecmp(cat, "general")) {
08538             var = ast_variable_browse(cfg, cat);
08539             if (strcasecmp(cat, "zonemessages")) {
08540                /* Process mailboxes in this context */
08541                while (var) {
08542                   append_mailbox(cat, var->name, var->value);
08543                   var = var->next;
08544                }
08545             } else {
08546                /* Timezones in this context */
08547                while (var) {
08548                   struct vm_zone *z;
08549                   if ((z = ast_malloc(sizeof(*z)))) {
08550                      char *msg_format, *timezone;
08551                      msg_format = ast_strdupa(var->value);
08552                      timezone = strsep(&msg_format, "|");
08553                      if (msg_format) {
08554                         ast_copy_string(z->name, var->name, sizeof(z->name));
08555                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
08556                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
08557                         AST_LIST_LOCK(&zones);
08558                         AST_LIST_INSERT_HEAD(&zones, z, list);
08559                         AST_LIST_UNLOCK(&zones);
08560                      } else {
08561                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
08562                         free(z);
08563                      }
08564                   } else {
08565                      free(z);
08566                      AST_LIST_UNLOCK(&users);
08567                      ast_config_destroy(cfg);
08568                      return -1;
08569                   }
08570                   var = var->next;
08571                }
08572             }
08573          }
08574          cat = ast_category_browse(cfg, cat);
08575       }
08576       memset(fromstring,0,sizeof(fromstring));
08577       memset(pagerfromstring,0,sizeof(pagerfromstring));
08578       memset(emailtitle,0,sizeof(emailtitle));
08579       strcpy(charset, "ISO-8859-1");
08580       if (emailbody) {
08581          free(emailbody);
08582          emailbody = NULL;
08583       }
08584       if (emailsubject) {
08585          free(emailsubject);
08586          emailsubject = NULL;
08587       }
08588       if (pagerbody) {
08589          free(pagerbody);
08590          pagerbody = NULL;
08591       }
08592       if (pagersubject) {
08593          free(pagersubject);
08594          pagersubject = NULL;
08595       }
08596       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
08597          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
08598       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
08599          ast_copy_string(fromstring,s,sizeof(fromstring));
08600       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
08601          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
08602       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
08603          ast_copy_string(charset,s,sizeof(charset));
08604       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
08605          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08606          for (x = 0; x < 4; x++) {
08607             memcpy(&adsifdn[x], &tmpadsi[x], 1);
08608          }
08609       }
08610       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
08611          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08612          for (x = 0; x < 4; x++) {
08613             memcpy(&adsisec[x], &tmpadsi[x], 1);
08614          }
08615       }
08616       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
08617          if (atoi(s)) {
08618             adsiver = atoi(s);
08619          }
08620       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
08621          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
08622          ast_copy_string(emailtitle,s,sizeof(emailtitle));
08623       }
08624       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
08625          emailsubject = ast_strdup(s);
08626       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
08627          char *tmpread, *tmpwrite;
08628          emailbody = ast_strdup(s);
08629 
08630          /* substitute strings \t and \n into the appropriate characters */
08631          tmpread = tmpwrite = emailbody;
08632          while ((tmpwrite = strchr(tmpread,'\\'))) {
08633             switch (tmpwrite[1]) {
08634             case 'r':
08635                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08636                *tmpwrite = '\r';
08637                break;
08638             case 'n':
08639                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08640                *tmpwrite = '\n';
08641                break;
08642             case 't':
08643                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08644                *tmpwrite = '\t';
08645                break;
08646             default:
08647                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08648             }
08649             tmpread = tmpwrite + 1;
08650          }
08651       }
08652       if ((s = ast_variable_retrieve(cfg, "general", "tz"))) {
08653          ast_copy_string(zonetag, s, sizeof(zonetag));
08654       }
08655       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
08656          pagersubject = ast_strdup(s);
08657       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
08658          char *tmpread, *tmpwrite;
08659          pagerbody = ast_strdup(s);
08660 
08661          /* substitute strings \t and \n into the appropriate characters */
08662          tmpread = tmpwrite = pagerbody;
08663          while ((tmpwrite = strchr(tmpread, '\\'))) {
08664             switch (tmpwrite[1]) {
08665             case 'r':
08666                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08667                *tmpwrite = '\r';
08668                break;
08669             case 'n':
08670                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08671                *tmpwrite = '\n';
08672                break;
08673             case 't':
08674                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08675                *tmpwrite = '\t';
08676                break;
08677             default:
08678                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08679             }
08680             tmpread = tmpwrite + 1;
08681          }
08682       }
08683       AST_LIST_UNLOCK(&users);
08684       ast_config_destroy(cfg);
08685       return 0;
08686    } else {
08687       AST_LIST_UNLOCK(&users);
08688       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
08689       return 0;
08690    }
08691 }

static int load_module ( void   )  [static]

Definition at line 8714 of file app_voicemail.c.

References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_free, ast_install_vm_functions(), ast_log(), ast_module_helper(), AST_MODULE_LOAD_DECLINE, ast_register_application(), cli_voicemail, free, has_voicemail(), inboxcount(), load_config(), LOG_ERROR, messagecount(), vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().

08715 {
08716    int res;
08717    char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
08718    free(adsi_loaded);
08719    if (!adsi_loaded) {
08720       /* If embedded, res_adsi may be known as "res_adsi" not "res_adsi.so" */
08721       adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
08722       ast_free(adsi_loaded);
08723       if (!adsi_loaded) {
08724          ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
08725          return AST_MODULE_LOAD_DECLINE;
08726       }
08727    }
08728 
08729    my_umask = umask(0);
08730    umask(my_umask);
08731    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
08732    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
08733    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
08734    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
08735    if (res)
08736       return(res);
08737 
08738    if ((res=load_config())) {
08739       return(res);
08740    }
08741 
08742    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08743 
08744    /* compute the location of the voicemail spool directory */
08745    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
08746 
08747    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
08748 
08749    return res;
08750 }

static int make_dir ( char *  dest,
int  len,
const char *  context,
const char *  ext,
const char *  folder 
) [static]

Definition at line 912 of file app_voicemail.c.

Referenced by copy_message(), create_dirpath(), and notify_new_message().

00913 {
00914    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00915 }

static void make_email_file ( FILE *  p,
char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
char *  attach,
char *  format,
int  duration,
int  attach_user_voicemail,
struct ast_channel chan,
const char *  category,
int  imap 
) [static]

Definition at line 3117 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_copy_string(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strlen_zero(), ast_test_flag, base_encode(), check_mime(), ast_vm_user::context, create_dirpath(), ast_vm_user::email, encode_mime_str(), ENDL, ast_vm_user::fullname, globalflags, LOG_DEBUG, ast_vm_user::mailbox, ast_channel::name, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), strip_control(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

03118 {
03119    char date[256];
03120    char host[MAXHOSTNAMELEN] = "";
03121    char who[256];
03122    char bound[256];
03123    char fname[256];
03124    char dur[256];
03125    char tmpcmd[256];
03126    char enc_cidnum[256] = "", enc_cidname[256] = "";
03127    struct tm tm;
03128    char *passdata = NULL, *passdata2;
03129    size_t len_passdata = 0, len_passdata2, tmplen;
03130 #ifdef IMAP_STORAGE
03131 #define ENDL "\r\n"
03132 #else
03133 #define ENDL "\n"
03134 #endif
03135 
03136    /* One alloca for multiple fields */
03137    len_passdata2 = strlen(vmu->fullname);
03138    if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) {
03139       len_passdata2 = tmplen;
03140    }
03141    if ((tmplen = strlen(emailtitle)) > len_passdata2) {
03142       len_passdata2 = tmplen;
03143    }
03144    if ((tmplen = strlen(fromstring)) > len_passdata2) {
03145       len_passdata2 = tmplen;
03146    }
03147    len_passdata2 = len_passdata2 * 3 + 200;
03148    passdata2 = alloca(len_passdata2);
03149 
03150    if (cidnum) {
03151       strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum));
03152    }
03153    if (cidname) {
03154       strip_control(cidname, enc_cidname, sizeof(enc_cidname));
03155    }
03156    gethostname(host, sizeof(host) - 1);
03157    if (strchr(srcemail, '@'))
03158       ast_copy_string(who, srcemail, sizeof(who));
03159    else {
03160       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03161    }
03162    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03163    strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03164    fprintf(p, "Date: %s" ENDL, date);
03165 
03166    /* Set date format for voicemail mail */
03167    strftime(date, sizeof(date), emaildateformat, &tm);
03168 
03169    if (*fromstring) {
03170       struct ast_channel *ast;
03171       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03172          char *ptr;
03173          memset(passdata2, 0, len_passdata2);
03174          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category);
03175          pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2);
03176          len_passdata = strlen(passdata2) * 3 + 300;
03177          passdata = alloca(len_passdata);
03178          if (check_mime(passdata2)) {
03179             int first_line = 1;
03180             encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3);
03181             while ((ptr = strchr(passdata, ' '))) {
03182                *ptr = '\0';
03183                fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata);
03184                first_line = 0;
03185                passdata = ptr + 1;
03186             }
03187             fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who);
03188          } else {
03189             fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who);
03190          }
03191          ast_channel_free(ast);
03192       } else
03193          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03194    } else
03195       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
03196 
03197    if (check_mime(vmu->fullname)) {
03198       int first_line = 1;
03199       char *ptr;
03200       encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3);
03201       while ((ptr = strchr(passdata2, ' '))) {
03202          *ptr = '\0';
03203          fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2);
03204          first_line = 0;
03205          passdata2 = ptr + 1;
03206       }
03207       fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email);
03208    } else {
03209       fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email);
03210    }
03211    if (emailsubject) {
03212       struct ast_channel *ast;
03213       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03214          int vmlen = strlen(emailsubject) * 3 + 200;
03215          /* Only allocate more space if the previous was not large enough */
03216          if (vmlen > len_passdata) {
03217             passdata = alloca(vmlen);
03218             len_passdata = vmlen;
03219          }
03220 
03221          memset(passdata, 0, len_passdata);
03222          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, len_passdata, category);
03223          pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata);
03224          if (check_mime(passdata)) {
03225             int first_line = 1;
03226             char *ptr;
03227             encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0);
03228             while ((ptr = strchr(passdata2, ' '))) {
03229                *ptr = '\0';
03230                fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03231                first_line = 0;
03232                passdata2 = ptr + 1;
03233             }
03234             fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03235          } else {
03236             fprintf(p, "Subject: %s" ENDL, passdata);
03237          }
03238          ast_channel_free(ast);
03239       } else {
03240          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03241       }
03242    } else   if (*emailtitle) {
03243       fprintf(p, emailtitle, msgnum + 1, mailbox) ;
03244       fprintf(p, ENDL) ;
03245    } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
03246       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03247    } else {
03248       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03249    }
03250    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
03251    if (imap) {
03252       /* additional information needed for IMAP searching */
03253       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
03254       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
03255       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
03256       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
03257 #ifdef IMAP_STORAGE
03258       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
03259 #else
03260       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
03261 #endif
03262       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
03263       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
03264       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
03265       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
03266       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
03267       if (!ast_strlen_zero(category)) {
03268          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
03269       }
03270       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
03271       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
03272    }
03273    if (!ast_strlen_zero(cidnum)) {
03274       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
03275    }
03276    if (!ast_strlen_zero(cidname)) {
03277       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
03278    }
03279    fprintf(p, "MIME-Version: 1.0" ENDL);
03280    if (attach_user_voicemail) {
03281       /* Something unique. */
03282       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
03283 
03284       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
03285       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
03286       fprintf(p, "--%s" ENDL, bound);
03287    }
03288    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
03289    if (emailbody) {
03290       struct ast_channel *ast;
03291       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03292          char *passdata;
03293          int vmlen = strlen(emailbody)*3 + 200;
03294          if ((passdata = alloca(vmlen))) {
03295             memset(passdata, 0, vmlen);
03296             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03297             pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
03298             fprintf(p, "%s" ENDL, passdata);
03299          } else
03300             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03301          ast_channel_free(ast);
03302       } else
03303          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03304    } else {
03305       fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a %s long message (number %d)" ENDL
03306 
03307       "in mailbox %s from %s, on %s so you might" ENDL
03308       "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, 
03309       dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
03310    }
03311    if (attach_user_voicemail) {
03312       /* Eww. We want formats to tell us their own MIME type */
03313       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
03314       char tmpdir[256], newtmp[256];
03315       int tmpfd = -1;
03316    
03317       if (vmu->volgain < -.001 || vmu->volgain > .001) {
03318          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
03319          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
03320          tmpfd = mkstemp(newtmp);
03321          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
03322          if (option_debug > 2)
03323             ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
03324          if (tmpfd > -1) {
03325             int soxstatus;
03326             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
03327             if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
03328                attach = newtmp;
03329                if (option_debug > 2) {
03330                   ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
03331                }
03332             } else {
03333                ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
03334                   soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
03335                ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
03336             }
03337          }
03338       }
03339       fprintf(p, "--%s" ENDL, bound);
03340       fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
03341       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
03342       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
03343       fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
03344       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
03345       base_encode(fname, p);
03346       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
03347       if (tmpfd > -1) {
03348          unlink(fname);
03349          close(tmpfd);
03350          unlink(newtmp);
03351       }
03352    }
03353 #undef ENDL
03354 }

static int make_file ( char *  dest,
const int  len,
const char *  dir,
const int  num 
) [static]

Definition at line 917 of file app_voicemail.c.

Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), last_message_index(), leave_voicemail(), notify_new_message(), play_message(), resequence_mailbox(), save_to_folder(), vm_execmain(), and vm_forwardoptions().

00918 {
00919    return snprintf(dest, len, "%s/msg%04d", dir, num);
00920 }

static char* mbox ( int  id  )  [static]

Definition at line 974 of file app_voicemail.c.

Referenced by adsi_load_vmail(), copy_message(), get_folder(), and save_to_folder().

00975 {
00976    static char *msgs[] = {
00977       "INBOX",
00978       "Old",
00979       "Work",
00980       "Family",
00981       "Friends",
00982       "Cust1",
00983       "Cust2",
00984       "Cust3",
00985       "Cust4",
00986       "Cust5",
00987    };
00988    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
00989 }

static int messagecount ( const char *  context,
const char *  mailbox,
const char *  folder 
) [static]

Definition at line 3743 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

03744 {
03745    return __has_voicemail(context, mailbox, folder, 0);
03746 }

static int notify_new_message ( struct ast_channel chan,
struct ast_vm_user vmu,
int  msgnum,
long  duration,
char *  fmt,
char *  cidnum,
char *  cidname 
) [static]

Definition at line 5004 of file app_voicemail.c.

References ast_app_has_voicemail(), ast_app_inboxcount(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), manager_event(), ast_vm_user::pager, pbx_builtin_getvar_helper(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, VM_ATTACH, and VM_DELETE.

Referenced by copy_message(), and leave_voicemail().

05005 {
05006    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
05007    int newmsgs = 0, oldmsgs = 0;
05008    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
05009 
05010    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
05011    make_file(fn, sizeof(fn), todir, msgnum);
05012    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
05013 
05014    if (!ast_strlen_zero(vmu->attachfmt)) {
05015       if (strstr(fmt, vmu->attachfmt)) {
05016          fmt = vmu->attachfmt;
05017       } else {
05018          ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'.  Falling back to default format for '%s@%s'.\n", vmu->attachfmt, fmt, vmu->mailbox, vmu->context);
05019       }
05020    }
05021 
05022    /* Attach only the first format */
05023    fmt = ast_strdupa(fmt);
05024    stringp = fmt;
05025    strsep(&stringp, "|");
05026 
05027    if (!ast_strlen_zero(vmu->email)) {
05028       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
05029       char *myserveremail = serveremail;
05030       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
05031       if (!ast_strlen_zero(vmu->serveremail))
05032          myserveremail = vmu->serveremail;
05033       
05034       if (attach_user_voicemail)
05035          RETRIEVE(todir, msgnum, vmu);
05036 
05037       /*XXX possible imap issue, should category be NULL XXX*/
05038       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
05039 
05040       if (attach_user_voicemail)
05041          DISPOSE(todir, msgnum);
05042    }
05043 
05044    if (!ast_strlen_zero(vmu->pager)) {
05045       char *myserveremail = serveremail;
05046       if (!ast_strlen_zero(vmu->serveremail))
05047          myserveremail = vmu->serveremail;
05048       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
05049    }
05050 
05051    if (ast_test_flag(vmu, VM_DELETE)) {
05052       DELETE(todir, msgnum, fn, vmu);
05053    }
05054 
05055    /* Leave voicemail for someone */
05056    if (ast_app_has_voicemail(ext_context, NULL)) {
05057       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
05058    }
05059    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);
05060    run_externnotify(vmu->context, vmu->mailbox);
05061    return 0;
05062 }

static int ochar ( struct baseio bio,
int  c,
FILE *  so 
) [static]

Definition at line 2907 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

02908 {
02909    if (bio->linelength>=BASELINELEN) {
02910       if (fputs(eol,so)==EOF)
02911          return -1;
02912 
02913       bio->linelength= 0;
02914    }
02915 
02916    if (putc(((unsigned char)c),so)==EOF)
02917       return -1;
02918 
02919    bio->linelength++;
02920 
02921    return 1;
02922 }

static int open_mailbox ( struct vm_state vms,
struct ast_vm_user vmu,
int  box 
) [static]

Definition at line 5628 of file app_voicemail.c.

References ast_copy_string(), ast_log(), ast_vm_user::context, count_messages(), create_dirpath(), vm_state::curbox, vm_state::curdir, last_message_index(), vm_state::lastmsg, LOG_NOTICE, resequence_mailbox(), vm_state::username, and vm_state::vmbox.

Referenced by vm_execmain().

05629 {
05630    int res = 0;
05631    int count_msg, last_msg;
05632 
05633    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
05634    
05635    /* Rename the member vmbox HERE so that we don't try to return before
05636     * we know what's going on.
05637     */
05638    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
05639    
05640    /* Faster to make the directory than to check if it exists. */
05641    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
05642 
05643    count_msg = count_messages(vmu, vms->curdir);
05644    if (count_msg < 0)
05645       return count_msg;
05646    else
05647       vms->lastmsg = count_msg - 1;
05648 
05649    /*
05650    The following test is needed in case sequencing gets messed up.
05651    There appears to be more than one way to mess up sequence, so
05652    we will not try to find all of the root causes--just fix it when
05653    detected.
05654    */
05655 
05656    last_msg = last_message_index(vmu, vms->curdir);
05657    if (last_msg < 0)
05658       return last_msg;
05659    else if (vms->lastmsg != last_msg)
05660    {
05661       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
05662       res = resequence_mailbox(vmu, vms->curdir);
05663       if (res)
05664          return res;
05665    }
05666 
05667    return 0;
05668 }

static int play_greeting ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  filename,
char *  ecodes 
) [static]

Definition at line 3481 of file app_voicemail.c.

References ast_fileexists(), ast_log(), ast_streamfile(), ast_waitstream(), ast_vm_user::context, DISPOSE, ast_channel::language, LOG_DEBUG, ast_vm_user::mailbox, option_debug, and RETRIEVE.

Referenced by invent_message(), and leave_voicemail().

03482 {
03483    int res = -2;
03484 
03485 #ifdef ODBC_STORAGE
03486    int success = 
03487 #endif
03488    RETRIEVE(filename, -1, vmu);
03489    if (ast_fileexists(filename, NULL, NULL) > 0) {
03490       res = ast_streamfile(chan, filename, chan->language);
03491       if (res > -1) 
03492          res = ast_waitstream(chan, ecodes);
03493 #ifdef ODBC_STORAGE
03494       if (success == -1) {
03495          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03496          if (option_debug)
03497             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03498          store_file(filename, vmu->mailbox, vmu->context, -1);
03499       }
03500 #endif
03501    }
03502    DISPOSE(filename, -1);
03503 
03504    return res;
03505 }

static int play_message ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
) [static]

Definition at line 5504 of file app_voicemail.c.

References adsi_message(), ast_config_destroy(), ast_config_load(), AST_DIGIT_ANY, ast_log(), ast_say_number(), ast_strdupa, ast_test_flag, ast_variable_retrieve(), vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::fn2, vm_state::heard, ast_channel::language, vm_state::lastmsg, LOG_DEBUG, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().

Referenced by vm_browse_messages_en(), vm_browse_messages_he(), vm_browse_messages_latin(), and vm_execmain().

05505 {
05506    int res = 0;
05507    char filename[256], *cid;
05508    const char *origtime, *context, *category, *duration;
05509    struct ast_config *msg_cfg;
05510 
05511    vms->starting = 0; 
05512    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05513    adsi_message(chan, vms);
05514    if (!strcasecmp(chan->language, "he")) {  /* HEBREW FORMAT */
05515       /*
05516        * The syntax in hebrew for counting the number of message is up side down
05517        * in comparison to english.
05518        */
05519       if (!vms->curmsg) {
05520          res = wait_file2(chan, vms, "vm-message");
05521          res = wait_file2(chan, vms, "vm-first");    /* "First" */
05522       } else if (vms->curmsg == vms->lastmsg) {
05523          res = wait_file2(chan, vms, "vm-message");
05524          res = wait_file2(chan, vms, "vm-last");     /* "last" */
05525       } else {
05526          res = wait_file2(chan, vms, "vm-message");  /* "message" */
05527          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05528             ast_log(LOG_DEBUG, "curmsg: %d\n", vms->curmsg);
05529             ast_log(LOG_DEBUG, "lagmsg: %d\n", vms->lastmsg);
05530             if (!res) {
05531                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
05532             }
05533          }
05534       }
05535    } else {
05536       if (!vms->curmsg)
05537          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05538       else if (vms->curmsg == vms->lastmsg)
05539          res = wait_file2(chan, vms, "vm-last");      /* "last" */
05540    }
05541    if (!res) {
05542       /* POLISH syntax */
05543       if (!strncasecmp(chan->language, "pl",2)) { 
05544          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05545             int ten, one;
05546             char nextmsg[256];
05547             ten = (vms->curmsg + 1) / 10;
05548             one = (vms->curmsg + 1) % 10;
05549             
05550             if (vms->curmsg < 20) {
05551                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
05552                res = wait_file2(chan, vms, nextmsg);
05553             } else {
05554                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
05555                res = wait_file2(chan, vms, nextmsg);
05556                if (one > 0) {
05557                   if (!res) {
05558                      snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
05559                      res = wait_file2(chan, vms, nextmsg);
05560                   }
05561                }
05562             }
05563          }
05564          if (!res)
05565             res = wait_file2(chan, vms, "vm-message");
05566       } else {
05567          if (!strncasecmp(chan->language,"se",2)) /* SWEDISH syntax */
05568             res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
05569          else /* DEFAULT syntax */
05570             res = wait_file2(chan, vms, "vm-message");
05571          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05572             if (!res)
05573                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05574          }
05575       }
05576    }
05577 
05578    /* Retrieve info from VM attribute file */
05579    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
05580    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
05581    RETRIEVE(vms->curdir, vms->curmsg, vmu);
05582    msg_cfg = ast_config_load(filename);
05583    if (!msg_cfg) {
05584       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
05585       return 0;
05586    }
05587 
05588    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
05589       ast_log(LOG_WARNING, "No origtime?!\n");
05590       DISPOSE(vms->curdir, vms->curmsg);
05591       ast_config_destroy(msg_cfg);
05592       return 0;
05593    }
05594 
05595    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
05596    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
05597    category = ast_variable_retrieve(msg_cfg, "message", "category");
05598 
05599    context = ast_variable_retrieve(msg_cfg, "message", "context");
05600    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
05601       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
05602    if (!res)
05603       res = play_message_category(chan, category);
05604    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
05605       res = play_message_datetime(chan, vmu, origtime, filename);
05606    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
05607       res = play_message_callerid(chan, vms, cid, context, 0);
05608    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
05609       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
05610    /* Allow pressing '1' to skip envelope / callerid */
05611    if (res == '1')
05612       res = 0;
05613    ast_config_destroy(msg_cfg);
05614 
05615    if (!res) {
05616       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05617       vms->heard[vms->curmsg] = 1;
05618       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
05619          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
05620          res = 0;
05621       }
05622    }
05623    DISPOSE(vms->curdir, vms->curmsg);
05624    return res;
05625 }

static int play_message_callerid ( struct ast_channel chan,
struct vm_state vms,
char *  cid,
const char *  context,
int  callback 
) [static]

Definition at line 5386 of file app_voicemail.c.

References ast_callerid_parse(), AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verbose(), ast_channel::language, LOG_DEBUG, MAX_NUM_CID_CONTEXTS, name, option_debug, option_verbose, VERBOSE_PREFIX_3, and wait_file2().

Referenced by advanced_options(), and play_message().

05387 {
05388    int res = 0;
05389    int i;
05390    char *callerid, *name;
05391    char prefile[PATH_MAX] = "";
05392    
05393 
05394    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
05395    /* BB: Still need to change this so that if this function is called by the message envelope (and someone is explicitly requesting to hear the CID), it does not check to see if CID is enabled in the config file */
05396    if ((cid == NULL)||(context == NULL))
05397       return res;
05398 
05399    /* Strip off caller ID number from name */
05400    if (option_debug > 2)
05401       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05402    ast_callerid_parse(cid, &name, &callerid);
05403    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05404       /* Check for internal contexts and only */
05405       /* say extension when the call didn't come from an internal context in the list */
05406       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
05407          if (option_debug > 2)
05408             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05409          if ((strcmp(cidinternalcontexts[i], context) == 0))
05410             break;
05411       }
05412       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
05413          if (!res) {
05414             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05415             if (!ast_strlen_zero(prefile)) {
05416             /* See if we can find a recorded name for this person instead of their extension number */
05417                if (ast_fileexists(prefile, NULL, NULL) > 0) {
05418                   if (option_verbose > 2)
05419                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05420                   if (!callback)
05421                      res = wait_file2(chan, vms, "vm-from");
05422                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
05423                } else {
05424                   if (option_verbose > 2)
05425                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
05426                   /* BB: Say "from extension" as one saying to sound smoother */
05427                   if (!callback)
05428                      res = wait_file2(chan, vms, "vm-from-extension");
05429                   res = ast_say_digit_str(chan, callerid, "", chan->language);
05430                }
05431             }
05432          }
05433       }
05434 
05435       else if (!res){
05436          if (option_debug > 2)
05437             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
05438          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
05439          if (!callback)
05440             res = wait_file2(chan, vms, "vm-from-phonenumber");
05441          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05442       }
05443    } else {
05444       /* Number unknown */
05445       if (option_debug)
05446          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
05447       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05448       res = wait_file2(chan, vms, "vm-unknown-caller");
05449    }
05450    return res;
05451 }

static int play_message_category ( struct ast_channel chan,
const char *  category 
) [static]

Definition at line 5299 of file app_voicemail.c.

References ast_log(), ast_play_and_wait(), and ast_strlen_zero().

Referenced by play_message().

05300 {
05301    int res = 0;
05302 
05303    if (!ast_strlen_zero(category))
05304       res = ast_play_and_wait(chan, category);
05305 
05306    if (res) {
05307       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05308       res = 0;
05309    }
05310 
05311    return res;
05312 }

static int play_message_datetime ( struct ast_channel chan,
struct ast_vm_user vmu,
const char *  origtime,
const char *  filename 
) [static]

Definition at line 5314 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, vm_zone::list, vm_zone::msg_format, vm_zone::name, pbx_builtin_setvar_helper(), vm_zone::timezone, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

05315 {
05316    int res = 0;
05317    struct vm_zone *the_zone = NULL;
05318    time_t t;
05319 
05320    if (ast_get_time_t(origtime, &t, 0, NULL)) {
05321       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05322       return 0;
05323    }
05324 
05325    /* Does this user have a timezone specified? */
05326    if (!ast_strlen_zero(vmu->zonetag)) {
05327       /* Find the zone in the list */
05328       struct vm_zone *z;
05329       AST_LIST_LOCK(&zones);
05330       AST_LIST_TRAVERSE(&zones, z, list) {
05331          if (!strcmp(z->name, vmu->zonetag)) {
05332             the_zone = z;
05333             break;
05334          }
05335       }
05336       AST_LIST_UNLOCK(&zones);
05337    }
05338 
05339 /* No internal variable parsing for now, so we'll comment it out for the time being */
05340 #if 0
05341    /* Set the DIFF_* variables */
05342    ast_localtime(&t, &time_now, NULL);
05343    tv_now = ast_tvnow();
05344    tnow = tv_now.tv_sec;
05345    ast_localtime(&tnow, &time_then, NULL);
05346 
05347    /* Day difference */
05348    if (time_now.tm_year == time_then.tm_year)
05349       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
05350    else
05351       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05352    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05353 
05354    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05355 #endif
05356    if (the_zone)
05357       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05358    else if (!strncasecmp(chan->language,"pl",2))       /* POLISH syntax */
05359       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05360    else if (!strncasecmp(chan->language,"se",2))       /* SWEDISH syntax */
05361       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05362    else if (!strncasecmp(chan->language,"no",2))       /* NORWEGIAN syntax */
05363       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05364    else if (!strncasecmp(chan->language,"de",2))       /* GERMAN syntax */
05365       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05366    else if (!strncasecmp(chan->language,"nl",2))      /* DUTCH syntax */
05367       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05368    else if (!strncasecmp(chan->language,"it",2))      /* ITALIAN syntax */
05369       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
05370    else if (!strncasecmp(chan->language,"gr",2))
05371       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05372    else if (!strcasecmp(chan->language,"pt_BR"))
05373       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);      
05374    else if (!strcasecmp(chan->language,"he"))
05375       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'at2' kM", NULL);
05376    else
05377       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05378 #if 0
05379    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05380 #endif
05381    return res;
05382 }

static int play_message_duration ( struct ast_channel chan,
struct vm_state vms,
const char *  duration,
int  minduration 
) [static]

Definition at line 5453 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_play_and_wait(), ast_say_number(), ast_channel::language, LOG_DEBUG, option_debug, say_and_wait(), and wait_file2().

Referenced by play_message().

05454 {
05455    int res = 0;
05456    int durationm;
05457    int durations;
05458    /* Verify that we have a duration for the message */
05459    if (duration == NULL)
05460       return res;
05461 
05462    /* Convert from seconds to minutes */
05463    durations=atoi(duration);
05464    durationm=(durations / 60);
05465 
05466    if (option_debug > 2)
05467       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05468 
05469    if ((!res) && (durationm >= minduration)) {
05470       res = wait_file2(chan, vms, "vm-duration");
05471 
05472       /* POLISH syntax */
05473       if (!strncasecmp(chan->language, "pl",2)) {
05474          div_t num = div(durationm, 10);
05475 
05476          if (durationm == 1) {
05477             res = ast_play_and_wait(chan, "digits/1z");
05478             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05479          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05480             if (num.rem == 2) {
05481                if (!num.quot) {
05482                   res = ast_play_and_wait(chan, "digits/2-ie");
05483                } else {
05484                   res = say_and_wait(chan, durationm - 2 , chan->language);
05485                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05486                }
05487             } else {
05488                res = say_and_wait(chan, durationm, chan->language);
05489             }
05490             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05491          } else {
05492             res = say_and_wait(chan, durationm, chan->language);
05493             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05494          }
05495       /* DEFAULT syntax */
05496       } else {
05497          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05498          res = wait_file2(chan, vms, "vm-minutes");
05499       }
05500    }
05501    return res;
05502 }

static int play_record_review ( struct ast_channel chan,
char *  playfile,
char *  recordfile,
int  maxtime,
char *  fmt,
int  outsidecaller,
struct ast_vm_user vmu,
int *  duration,
const char *  unlockdir,
signed char  record_gain,
struct vm_state vms 
) [static]

Definition at line 9004 of file app_voicemail.c.

References ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_channel::language, ast_vm_user::mailbox, option_verbose, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.

Referenced by leave_voicemail(), vm_newuser(), vm_options(), and vm_tempgreeting().

09007 {
09008    /* Record message & let caller review or re-record it, or set options if applicable */
09009    int res = 0;
09010    int cmd = 0;
09011    int max_attempts = 3;
09012    int attempts = 0;
09013    int recorded = 0;
09014    int message_exists = 0;
09015    signed char zero_gain = 0;
09016    char tempfile[PATH_MAX];
09017    char *acceptdtmf = "#";
09018    char *canceldtmf = "";
09019 
09020    /* Note that urgent and private are for flagging messages as such in the future */
09021 
09022    /* barf if no pointer passed to store duration in */
09023    if (duration == NULL) {
09024       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
09025       return -1;
09026    }
09027 
09028    if (!outsidecaller)
09029       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
09030    else
09031       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
09032 
09033    cmd = '3';  /* Want to start by recording */
09034 
09035    while ((cmd >= 0) && (cmd != 't')) {
09036       switch (cmd) {
09037       case '1':
09038          if (!message_exists) {
09039             /* In this case, 1 is to record a message */
09040             cmd = '3';
09041             break;
09042          } else {
09043             /* Otherwise 1 is to save the existing message */
09044             if (option_verbose > 2)
09045                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
09046             if (!outsidecaller)
09047                ast_filerename(tempfile, recordfile, NULL);
09048             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
09049             if (!outsidecaller) {
09050                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
09051                DISPOSE(recordfile, -1);
09052             }
09053             cmd = 't';
09054             return res;
09055          }
09056       case '2':
09057          /* Review */
09058          if (option_verbose > 2)
09059             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
09060          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
09061          break;
09062       case '3':
09063          message_exists = 0;
09064          /* Record */
09065          if (recorded == 1) {
09066             if (option_verbose > 2)
09067                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
09068          } else { 
09069             if (option_verbose > 2)
09070                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
09071          }
09072          if (recorded && outsidecaller) {
09073             cmd = ast_play_and_wait(chan, INTRO);
09074             cmd = ast_play_and_wait(chan, "beep");
09075          }
09076          recorded = 1;
09077          /* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */
09078          if (record_gain)
09079             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
09080          if (ast_test_flag(vmu, VM_OPERATOR))
09081             canceldtmf = "0";
09082          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
09083          if (record_gain)
09084             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
09085          if (cmd == -1) {
09086             /* User has hung up, no options to give */
09087             if (!outsidecaller) {
09088                /* user was recording a greeting and they hung up, so let's delete the recording. */
09089                ast_filedelete(tempfile, NULL);
09090             }
09091             return cmd;
09092          }
09093          if (cmd == '0') {
09094             break;
09095          } else if (cmd == '*') {
09096             break;
09097          } 
09098 #if 0       
09099          else if (vmu->review && (*duration < 5)) {
09100             /* Message is too short */
09101             if (option_verbose > 2)
09102                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
09103             cmd = ast_play_and_wait(chan, "vm-tooshort");
09104             cmd = ast_filedelete(tempfile, NULL);
09105             break;
09106          }
09107          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
09108             /* Message is all silence */
09109             if (option_verbose > 2)
09110                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
09111             cmd = ast_filedelete(tempfile, NULL);
09112             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
09113             if (!cmd)
09114                cmd = ast_play_and_wait(chan, "vm-speakup");
09115             break;
09116          }
09117 #endif
09118          else {
09119             /* If all is well, a message exists */
09120             message_exists = 1;
09121             cmd = 0;
09122          }
09123          break;
09124       case '4':
09125       case '5':
09126       case '6':
09127       case '7':
09128       case '8':
09129       case '9':
09130       case '*':
09131       case '#':
09132          cmd = ast_play_and_wait(chan, "vm-sorry");
09133          break;
09134 #if 0 
09135 /*  XXX Commented out for the moment because of the dangers of deleting
09136     a message while recording (can put the message numbers out of sync) */
09137       case '*':
09138          /* Cancel recording, delete message, offer to take another message*/
09139          cmd = ast_play_and_wait(chan, "vm-deleted");
09140          cmd = ast_filedelete(tempfile, NULL);
09141          if (outsidecaller) {
09142             res = vm_exec(chan, NULL);
09143             return res;
09144          }
09145          else
09146             return 1;
09147 #endif
09148       case '0':
09149          if (!ast_test_flag(vmu, VM_OPERATOR)) {
09150             cmd = ast_play_and_wait(chan, "vm-sorry");
09151             break;
09152          }
09153          if (message_exists || recorded) {
09154             cmd = ast_play_and_wait(chan, "vm-saveoper");
09155             if (!cmd)
09156                cmd = ast_waitfordigit(chan, 3000);
09157             if (cmd == '1') {
09158                ast_play_and_wait(chan, "vm-msgsaved");
09159                cmd = '0';
09160             } else {
09161                ast_play_and_wait(chan, "vm-deleted");
09162                DELETE(recordfile, -1, recordfile, vmu);
09163                cmd = '0';
09164             }
09165          }
09166          return cmd;
09167       default:
09168          /* If the caller is an ouside caller, and the review option is enabled,
09169             allow them to review the message, but let the owner of the box review
09170             their OGM's */
09171          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
09172             return cmd;
09173          if (message_exists) {
09174             cmd = ast_play_and_wait(chan, "vm-review");
09175          }
09176          else {
09177             cmd = ast_play_and_wait(chan, "vm-torerecord");
09178             if (!cmd)
09179                cmd = ast_waitfordigit(chan, 600);
09180          }
09181          
09182          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
09183             cmd = ast_play_and_wait(chan, "vm-reachoper");
09184             if (!cmd)
09185                cmd = ast_waitfordigit(chan, 600);
09186          }
09187 #if 0
09188          if (!cmd)
09189             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
09190 #endif
09191          if (!cmd)
09192             cmd = ast_waitfordigit(chan, 6000);
09193          if (!cmd) {
09194             attempts++;
09195          }
09196          if (attempts > max_attempts) {
09197             cmd = 't';
09198          }
09199       }
09200    }
09201    if (outsidecaller)
09202       ast_play_and_wait(chan, "vm-goodbye");
09203    if (cmd == 't')
09204       cmd = 0;
09205    return cmd;
09206 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 603 of file app_voicemail.c.

References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, globalflags, ast_vm_user::maxmsg, ast_vm_user::saydurationm, ast_vm_user::volgain, and ast_vm_user::zonetag.

Referenced by append_mailbox(), find_user_realtime(), and load_config().

00604 {
00605    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00606    if (saydurationminfo)
00607       vmu->saydurationm = saydurationminfo;
00608    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00609    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00610    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00611    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00612    if (maxmsg)
00613       vmu->maxmsg = maxmsg;
00614    vmu->volgain = volgain;
00615 }

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]

Definition at line 2996 of file app_voicemail.c.

References ast_callerid_merge(), ast_strdupa, ast_strlen_zero(), ast_vm_user::fullname, and pbx_builtin_setvar_helper().

Referenced by make_email_file(), and sendpage().

02997 {
02998    char callerid[256];
02999    /* Prepare variables for substition in email body and subject */
03000    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
03001    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
03002    snprintf(passdata, passdatasize, "%d", msgnum);
03003    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
03004    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
03005    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
03006    pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
03007       ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
03008    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
03009    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
03010    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
03011    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
03012 }

static char* quote ( const char *  from,
char *  to,
size_t  len 
) [static]

Definition at line 3014 of file app_voicemail.c.

03015 {
03016    char *ptr = to;
03017    *ptr++ = '"';
03018    for (; ptr < to + len - 1; from++) {
03019       if (*from == '"')
03020          *ptr++ = '\\';
03021       else if (*from == '\0')
03022          break;
03023       *ptr++ = *from;
03024    }
03025    if (ptr < to + len - 1)
03026       *ptr++ = '"';
03027    *ptr = '\0';
03028    return to;
03029 }

static int reload ( void   )  [static]

Definition at line 8693 of file app_voicemail.c.

References load_config().

08694 {
08695    return(load_config());
08696 }

static void rename_file ( char *  sfn,
char *  dfn 
) [static]

Definition at line 2741 of file app_voicemail.c.

References ast_filerename().

02742 {
02743    char stxt[PATH_MAX];
02744    char dtxt[PATH_MAX];
02745    ast_filerename(sfn,dfn,NULL);
02746    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02747    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02748    rename(stxt, dtxt);
02749 }

static int resequence_mailbox ( struct ast_vm_user vmu,
char *  dir 
) [static]

Definition at line 4274 of file app_voicemail.c.

References ast_unlock_path(), ast_vm_user::context, ERROR_LOCK_PATH, EXISTS, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, RENAME, and vm_lock_path().

Referenced by open_mailbox().

04275 {
04276    /* we know max messages, so stop process when number is hit */
04277 
04278    int x,dest;
04279    char sfn[PATH_MAX];
04280    char dfn[PATH_MAX];
04281 
04282    if (vm_lock_path(dir))
04283       return ERROR_LOCK_PATH;
04284 
04285    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
04286       make_file(sfn, sizeof(sfn), dir, x);
04287       if (EXISTS(dir, x, sfn, NULL)) {
04288          
04289          if (x != dest) {
04290             make_file(dfn, sizeof(dfn), dir, dest);
04291             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04292          }
04293          
04294          dest++;
04295       }
04296    }
04297    ast_unlock_path(dir);
04298 
04299    return 0;
04300 }

static int reset_user_pw ( const char *  context,
const char *  mailbox,
const char *  newpass 
) [static]

Definition at line 807 of file app_voicemail.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, ast_vm_user::list, ast_vm_user::mailbox, and ast_vm_user::password.

Referenced by vm_change_password(), and vm_change_password_shell().

00808 {
00809    /* This function could be made to generate one from a database, too */
00810    struct ast_vm_user *cur;
00811    int res = -1;
00812    AST_LIST_LOCK(&users);
00813    AST_LIST_TRAVERSE(&users, cur, list) {
00814       if ((!context || !strcasecmp(context, cur->context)) &&
00815          (!strcasecmp(mailbox, cur->mailbox)))
00816             break;
00817    }
00818    if (cur) {
00819       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00820       res = 0;
00821    }
00822    AST_LIST_UNLOCK(&users);
00823    return res;
00824 }

static void run_externnotify ( char *  context,
char *  extension 
) [static]

Definition at line 3844 of file app_voicemail.c.

References ast_app_has_voicemail(), ast_copy_string(), ast_log(), ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait_station(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, ast_smdi_mwi_message::fwd_st, inboxcount(), LOG_DEBUG, LOG_ERROR, option_debug, smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.

Referenced by forward_message(), notify_new_message(), and vm_execmain().

03845 {
03846    char arguments[255];
03847    char ext_context[256] = "";
03848    int newvoicemails = 0, oldvoicemails = 0;
03849    struct ast_smdi_mwi_message *mwi_msg;
03850 
03851    if (!ast_strlen_zero(context))
03852       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
03853    else
03854       ast_copy_string(ext_context, extension, sizeof(ext_context));
03855 
03856    if (!strcasecmp(externnotify, "smdi")) {
03857       if (ast_app_has_voicemail(ext_context, NULL)) 
03858          ast_smdi_mwi_set(smdi_iface, extension);
03859       else
03860          ast_smdi_mwi_unset(smdi_iface, extension);
03861 
03862       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
03863          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
03864          if (!strncmp(mwi_msg->cause, "INV", 3))
03865             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
03866          else if (!strncmp(mwi_msg->cause, "BLK", 3))
03867             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
03868          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
03869          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
03870       } else {
03871          if (option_debug)
03872             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
03873       }
03874    } else if (!ast_strlen_zero(externnotify)) {
03875       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
03876          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
03877       } else {
03878          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
03879          if (option_debug)
03880             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
03881          ast_safe_system(arguments);
03882       }
03883    }
03884 }

static int save_to_folder ( struct ast_vm_user vmu,
struct vm_state vms,
int  msg,
int  box 
) [static]

Definition at line 4310 of file app_voicemail.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_unlock_path(), ast_vm_user::context, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, ERROR_MAILBOX_FULL, EXISTS, LOG_DEBUG, make_file(), ast_vm_user::maxmsg, mbox(), option_debug, vm_state::username, username, and vm_lock_path().

Referenced by vm_execmain().

04311 {
04312 #ifdef IMAP_STORAGE
04313    /* we must use mbox(x) folder names, and copy the message there */
04314    /* simple. huh? */
04315    char sequence[10];
04316    /* get the real IMAP message number for this message */
04317    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04318    if (option_debug > 2)
04319       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
04320    ast_mutex_lock(&vms->lock);
04321    if (box == 1) {
04322       mail_setflag(vms->mailstream, sequence, "\\Seen");
04323    } else if (box == 0) {
04324       mail_clearflag(vms->mailstream, sequence, "\\Seen");
04325    }
04326    if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
04327       ast_mutex_unlock(&vms->lock);
04328       return 0;
04329    } else {
04330       int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
04331       ast_mutex_unlock(&vms->lock);
04332       return res;
04333    }
04334 #else
04335    char *dir = vms->curdir;
04336    char *username = vms->username;
04337    char *context = vmu->context;
04338    char sfn[PATH_MAX];
04339    char dfn[PATH_MAX];
04340    char ddir[PATH_MAX];
04341    const char *dbox = mbox(box);
04342    int x;
04343    make_file(sfn, sizeof(sfn), dir, msg);
04344    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04345 
04346    if (vm_lock_path(ddir))
04347       return ERROR_LOCK_PATH;
04348 
04349    for (x = 0; x < vmu->maxmsg; x++) {
04350       make_file(dfn, sizeof(dfn), ddir, x);
04351       if (!EXISTS(ddir, x, dfn, NULL))
04352          break;
04353    }
04354    if (x >= vmu->maxmsg) {
04355       ast_unlock_path(ddir);
04356       return ERROR_MAILBOX_FULL;
04357    }
04358    if (strcmp(sfn, dfn)) {
04359       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04360    }
04361    ast_unlock_path(ddir);
04362 #endif
04363    return 0;
04364 }

static int say_and_wait ( struct ast_channel chan,
int  num,
const char *  language 
) [static]

Definition at line 4303 of file app_voicemail.c.

References AST_DIGIT_ANY, and ast_say_number().

Referenced by play_message_duration(), vm_execmain(), vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), and vm_intro_se().

04304 {
04305    int d;
04306    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04307    return d;
04308 }

static int sendmail ( char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
char *  attach,
char *  format,
int  duration,
int  attach_user_voicemail,
struct ast_channel chan,
const char *  category 
) [static]

Definition at line 3355 of file app_voicemail.c.

References ast_log(), ast_safe_system(), ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, LOG_DEBUG, ast_vm_user::mailbox, make_email_file(), option_debug, VM_ATTACH, and vm_mkftemp().

Referenced by forward_message(), and notify_new_message().

03356 {
03357    FILE *p=NULL;
03358    char tmp[80] = "/tmp/astmail-XXXXXX";
03359    char tmp2[256];
03360 
03361    if (vmu && ast_strlen_zero(vmu->email)) {
03362       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03363       return(0);
03364    }
03365    if (!strcmp(format, "wav49"))
03366       format = "WAV";
03367    if (option_debug > 2)
03368       ast_log(LOG_DEBUG, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
03369    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03370       command hangs */
03371    if ((p = vm_mkftemp(tmp)) == NULL) {
03372       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03373       return -1;
03374    } else {
03375       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03376       fclose(p);
03377       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03378       ast_safe_system(tmp2);
03379       if (option_debug > 2)
03380          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03381    }
03382    return 0;
03383 }

static int sendpage ( char *  srcemail,
char *  pager,
int  msgnum,
char *  context,
char *  mailbox,
char *  cidnum,
char *  cidname,
int  duration,
struct ast_vm_user vmu,
const char *  category 
) [static]

Definition at line 3385 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_copy_string(), ast_log(), ast_safe_system(), AST_STATE_DOWN, LOG_DEBUG, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().

Referenced by notify_new_message().

03386 {
03387    char date[256];
03388    char host[MAXHOSTNAMELEN] = "";
03389    char who[256];
03390    char dur[PATH_MAX];
03391    char tmp[80] = "/tmp/astmail-XXXXXX";
03392    char tmp2[PATH_MAX];
03393    struct tm tm;
03394    FILE *p;
03395 
03396    if ((p = vm_mkftemp(tmp)) == NULL) {
03397       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03398       return -1;
03399    } else {
03400       gethostname(host, sizeof(host)-1);
03401       if (strchr(srcemail, '@'))
03402          ast_copy_string(who, srcemail, sizeof(who));
03403       else {
03404          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03405       }
03406       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03407       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03408       fprintf(p, "Date: %s\n", date);
03409 
03410       if (*pagerfromstring) {
03411          struct ast_channel *ast;
03412          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03413             char *passdata;
03414             int vmlen = strlen(fromstring)*3 + 200;
03415             if ((passdata = alloca(vmlen))) {
03416                memset(passdata, 0, vmlen);
03417                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03418                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
03419                fprintf(p, "From: %s <%s>\n", passdata, who);
03420             } else 
03421                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03422             ast_channel_free(ast);
03423          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03424       } else
03425          fprintf(p, "From: Asterisk PBX <%s>\n", who);
03426       fprintf(p, "To: %s\n", pager);
03427       if (pagersubject) {
03428          struct ast_channel *ast;
03429          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03430             char *passdata;
03431             int vmlen = strlen(pagersubject) * 3 + 200;
03432             if ((passdata = alloca(vmlen))) {
03433                memset(passdata, 0, vmlen);
03434                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03435                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
03436                fprintf(p, "Subject: %s\n\n", passdata);
03437             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03438             ast_channel_free(ast);
03439          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03440       } else
03441          fprintf(p, "Subject: New VM\n\n");
03442       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
03443       if (pagerbody) {
03444          struct ast_channel *ast;
03445          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03446             char *passdata;
03447             int vmlen = strlen(pagerbody)*3 + 200;
03448             if ((passdata = alloca(vmlen))) {
03449                memset(passdata, 0, vmlen);
03450                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03451                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
03452                fprintf(p, "%s\n", passdata);
03453             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03454          ast_channel_free(ast);
03455          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03456       } else {
03457          fprintf(p, "New %s long msg in box %s\n"
03458                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
03459       }
03460       fclose(p);
03461       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03462       ast_safe_system(tmp2);
03463       if (option_debug > 2)
03464          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
03465    }
03466    return 0;
03467 }

static char* strip_control ( const char *  input,
char *  buf,
size_t  buflen 
) [static]

Definition at line 587 of file app_voicemail.c.

Referenced by make_email_file().

00588 {
00589    char *bufptr = buf;
00590    for (; *input; input++) {
00591       if (*input < 32) {
00592          continue;
00593       }
00594       *bufptr++ = *input;
00595       if (bufptr == buf + buflen - 1) {
00596          break;
00597       }
00598    }
00599    *bufptr = '\0';
00600    return buf;
00601 }

static int unload_module ( void   )  [static]

Definition at line 8698 of file app_voicemail.c.

References ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_uninstall_vm_functions(), ast_unregister_application(), and cli_voicemail.

08699 {
08700    int res;
08701    
08702    res = ast_unregister_application(app);
08703    res |= ast_unregister_application(app2);
08704    res |= ast_unregister_application(app3);
08705    res |= ast_unregister_application(app4);
08706    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08707    ast_uninstall_vm_functions();
08708    
08709    ast_module_user_hangup_all();
08710 
08711    return res;
08712 }

static int vm_authenticate ( struct ast_channel chan,
char *  mailbox,
int  mailbox_size,
struct ast_vm_user res_vmu,
const char *  context,
const char *  prefix,
int  skipuser,
int  maxlogins,
int  silent 
) [static]

Definition at line 7067 of file app_voicemail.c.

References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verbose(), ast_waitstream(), find_user(), LOG_DEBUG, option_debug, option_verbose, ast_vm_user::password, password, and VERBOSE_PREFIX_3.

Referenced by vm_execmain(), and vmauthenticate().

07070 {
07071    int useadsi=0, valid=0, logretries=0;
07072    char password[AST_MAX_EXTENSION]="", *passptr;
07073    struct ast_vm_user vmus, *vmu = NULL;
07074 
07075    /* If ADSI is supported, setup login screen */
07076    adsi_begin(chan, &useadsi);
07077    if (!skipuser && useadsi)
07078       adsi_login(chan);
07079    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
07080       ast_log(LOG_WARNING, "Couldn't stream login file\n");
07081       return -1;
07082    }
07083    
07084    /* Authenticate them and get their mailbox/password */
07085    
07086    while (!valid && (logretries < maxlogins)) {
07087       /* Prompt for, and read in the username */
07088       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
07089          ast_log(LOG_WARNING, "Couldn't read username\n");
07090          return -1;
07091       }
07092       if (ast_strlen_zero(mailbox)) {
07093          if (chan->cid.cid_num) {
07094             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
07095          } else {
07096             if (option_verbose > 2)
07097                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
07098             return -1;
07099          }
07100       }
07101       if (useadsi)
07102          adsi_password(chan);
07103 
07104       if (!ast_strlen_zero(prefix)) {
07105          char fullusername[80] = "";
07106          ast_copy_string(fullusername, prefix, sizeof(fullusername));
07107          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
07108          ast_copy_string(mailbox, fullusername, mailbox_size);
07109       }
07110 
07111       if (option_debug)
07112          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
07113       vmu = find_user(&vmus, context, mailbox);
07114       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
07115          /* saved password is blank, so don't bother asking */
07116          password[0] = '\0';
07117       } else {
07118          if (ast_streamfile(chan, "vm-password", chan->language)) {
07119             ast_log(LOG_WARNING, "Unable to stream password file\n");
07120             return -1;
07121          }
07122          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
07123             ast_log(LOG_WARNING, "Unable to read password\n");
07124             return -1;
07125          }
07126       }
07127 
07128       if (vmu) {
07129          passptr = vmu->password;
07130          if (passptr[0] == '-') passptr++;
07131       }
07132       if (vmu && !strcmp(passptr, password))
07133          valid++;
07134       else {
07135          if (option_verbose > 2)
07136             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
07137          if (!ast_strlen_zero(prefix))
07138             mailbox[0] = '\0';
07139       }
07140       logretries++;
07141       if (!valid) {
07142          if (skipuser || logretries >= maxlogins) {
07143             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
07144                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
07145                return -1;
07146             }
07147          } else {
07148             if (useadsi)
07149                adsi_login(chan);
07150             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
07151                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
07152                return -1;
07153             }
07154          }
07155          if (ast_waitstream(chan, "")) /* Channel is hung up */
07156             return -1;
07157       }
07158    }
07159    if (!valid && (logretries >= maxlogins)) {
07160       ast_stopstream(chan);
07161       ast_play_and_wait(chan, "vm-goodbye");
07162       return -1;
07163    }
07164    if (vmu && !skipuser) {
07165       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
07166    }
07167    return 0;
07168 }

static int vm_box_exists ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 7899 of file app_voicemail.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_module_user_add, ast_module_user_remove, ast_opt_priority_jumping, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::context, find_user(), LOG_ERROR, and pbx_builtin_setvar_helper().

Referenced by load_module().

07900 {
07901    struct ast_module_user *u;
07902    struct ast_vm_user svm;
07903    char *context, *box;
07904    int priority_jump = 0;
07905    AST_DECLARE_APP_ARGS(args,
07906       AST_APP_ARG(mbox);
07907       AST_APP_ARG(options);
07908    );
07909 
07910    if (ast_strlen_zero(data)) {
07911       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
07912       return -1;
07913    }
07914 
07915    u = ast_module_user_add(chan);
07916 
07917    box = ast_strdupa(data);
07918 
07919    AST_STANDARD_APP_ARGS(args, box);
07920 
07921    if (args.options) {
07922       if (strchr(args.options, 'j'))
07923          priority_jump = 1;
07924    }
07925 
07926    if ((context = strchr(args.mbox, '@'))) {
07927       *context = '\0';
07928       context++;
07929    }
07930 
07931    if (find_user(&svm, context, args.mbox)) {
07932       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
07933       if (priority_jump || ast_opt_priority_jumping)
07934          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
07935             ast_log(LOG_WARNING, "VM box %s@%s exists, but extension %s, priority %d doesn't exist\n", box, context, chan->exten, chan->priority + 101);
07936    } else
07937       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
07938    ast_module_user_remove(u);
07939    return 0;
07940 }

static int vm_browse_messages ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 7053 of file app_voicemail.c.

References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_he(), and vm_browse_messages_latin().

Referenced by vm_execmain().

07054 {
07055    if (!strncasecmp(chan->language, "es", 2) ||
07056          !strncasecmp(chan->language, "it", 2) ||
07057          !strncasecmp(chan->language, "pt", 2) ||
07058          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
07059       return vm_browse_messages_latin(chan, vms, vmu);
07060    } else if (!strcasecmp(chan->language, "he")) {
07061       return vm_browse_messages_he(chan, vms, vmu); /* HEBREW */ 
07062    } else { /* Default to English syntax */
07063       return vm_browse_messages_en(chan, vms, vmu);
07064    }
07065 }

static int vm_browse_messages_en ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 6987 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

06988 {
06989    int cmd=0;
06990 
06991    if (vms->lastmsg > -1) {
06992       cmd = play_message(chan, vmu, vms);
06993    } else {
06994       cmd = ast_play_and_wait(chan, "vm-youhave");
06995       if (!cmd) 
06996          cmd = ast_play_and_wait(chan, "vm-no");
06997       if (!cmd) {
06998          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06999          cmd = ast_play_and_wait(chan, vms->fn);
07000       }
07001       if (!cmd)
07002          cmd = ast_play_and_wait(chan, "vm-messages");
07003    }
07004    return cmd;
07005 }

static int vm_browse_messages_he ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 7008 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

07009 {
07010    int cmd = 0;
07011 
07012    if (vms->lastmsg > -1) {
07013       cmd = play_message(chan, vmu, vms);
07014    } else {
07015       if (!strcasecmp(vms->fn, "INBOX")) {
07016          cmd = ast_play_and_wait(chan, "vm-nonewmessages");
07017       } else {
07018          cmd = ast_play_and_wait(chan, "vm-nomessages");
07019       }
07020    }
07021    return cmd;
07022 }

static int vm_browse_messages_latin ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
) [static]

Definition at line 7026 of file app_voicemail.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, play_message(), and vm_state::vmbox.

Referenced by vm_browse_messages().

07027 {
07028    int cmd=0;
07029 
07030    if (vms->lastmsg > -1) {
07031       cmd = play_message(chan, vmu, vms);
07032    } else {
07033       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07034       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
07035          if (!cmd) {
07036             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07037             cmd = ast_play_and_wait(chan, vms->fn);
07038          }
07039          if (!cmd)
07040             cmd = ast_play_and_wait(chan, "vm-messages");
07041       } else {
07042          if (!cmd)
07043             cmd = ast_play_and_wait(chan, "vm-messages");
07044          if (!cmd) {
07045             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07046             cmd = ast_play_and_wait(chan, vms->fn);
07047          }
07048       }
07049    }
07050    return cmd;
07051 }

static void vm_change_password ( struct ast_vm_user vmu,
const char *  newpassword 
) [static]

Definition at line 826 of file app_voicemail.c.

References ast_category_browse(), ast_category_get(), ast_config_load_with_comments(), ast_copy_string(), ast_log(), ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), change_password_realtime(), config_text_file_save(), ast_vm_user::context, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, option_debug, ast_vm_user::password, reset_user_pw(), var, and VOICEMAIL_CONFIG.

Referenced by vm_newuser(), and vm_options().

00827 {
00828    struct ast_config   *cfg=NULL;
00829    struct ast_variable *var=NULL;
00830    struct ast_category *cat=NULL;
00831    char *category=NULL, *value=NULL, *new=NULL;
00832    const char *tmp=NULL;
00833                
00834    if (!change_password_realtime(vmu, newpassword))
00835       return;
00836 
00837    /* check voicemail.conf */
00838    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00839       while ((category = ast_category_browse(cfg, category))) {
00840          if (!strcasecmp(category, vmu->context)) {
00841             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00842             if (!tmp) {
00843                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00844                break;
00845             }
00846             value = strstr(tmp,",");
00847             if (!value) {
00848                ast_log(LOG_WARNING, "variable has bad format.\n");
00849                break;
00850             }
00851             new = alloca((strlen(value)+strlen(newpassword)+1));
00852             sprintf(new,"%s%s", newpassword, value);
00853             if (!(cat = ast_category_get(cfg, category))) {
00854                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00855                break;
00856             }
00857             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00858          }
00859       }
00860       /* save the results */
00861       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00862       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00863       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00864    }
00865    category = NULL;
00866    var = NULL;
00867    /* check users.conf and update the password stored for the mailbox*/
00868    /* if no vmsecret entry exists create one. */
00869    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00870       if (option_debug > 3)
00871          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00872       while ((category = ast_category_browse(cfg, category))) {
00873          if (option_debug > 3)
00874             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00875          if (!strcasecmp(category, vmu->mailbox)) {
00876             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00877                if (option_debug > 3)
00878                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00879                var = ast_variable_new("vmsecret", newpassword);
00880             } 
00881             new = alloca(strlen(newpassword)+1);
00882             sprintf(new, "%s", newpassword);
00883             if (!(cat = ast_category_get(cfg, category))) {
00884                if (option_debug > 3)
00885                   ast_log(LOG_DEBUG, "failed to get category!\n");
00886                break;
00887             }
00888             if (!var)      
00889                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00890             else
00891                ast_variable_append(cat, var);
00892          }
00893       }
00894       /* save the results and clean things up */
00895       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00896       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00897       config_text_file_save("users.conf", cfg, "AppVoicemail");
00898    }
00899 }

static void vm_change_password_shell ( struct ast_vm_user vmu,
char *  newpassword 
) [static]

Definition at line 901 of file app_voicemail.c.

References ast_copy_string(), ast_safe_system(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().

Referenced by vm_newuser(), and vm_options().

00902 {
00903    char buf[255];
00904    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00905    if (!ast_safe_system(buf)) {
00906       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00907       /* Reset the password in memory, too */
00908       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00909    }
00910 }

static int vm_delete ( char *  file  )  [static]

Definition at line 2861 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message(), and forward_message().

02862 {
02863    char *txt;
02864    int txtsize = 0;
02865 
02866    txtsize = (strlen(file) + 5)*sizeof(char);
02867    txt = alloca(txtsize);
02868    /* Sprintf here would safe because we alloca'd exactly the right length,
02869     * but trying to eliminate all sprintf's anyhow
02870     */
02871    snprintf(txt, txtsize, "%s.txt", file);
02872    unlink(txt);
02873    return ast_filedelete(file, NULL);
02874 }

static int vm_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 7744 of file app_voicemail.c.

References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_copy_flags, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_module_user_add, ast_module_user_remove, ast_opt_priority_jumping, ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, ast_flags::flags, leave_voicemail(), LOG_ERROR, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and vm_app_options.

Referenced by load_module(), and play_record_review().

07745 {
07746    int res = 0;
07747    struct ast_module_user *u;
07748    char *tmp;
07749    struct leave_vm_options leave_options;
07750    struct ast_flags flags = { 0 };
07751    static int deprecate_warning = 0;
07752    char *opts[OPT_ARG_ARRAY_SIZE];
07753    AST_DECLARE_APP_ARGS(args,
07754       AST_APP_ARG(argv0);
07755       AST_APP_ARG(argv1);
07756    );
07757 
07758    u = ast_module_user_add(chan);
07759    
07760    memset(&leave_options, 0, sizeof(leave_options));
07761 
07762    if (chan->_state != AST_STATE_UP)
07763       ast_answer(chan);
07764 
07765    if (!ast_strlen_zero(data)) {
07766       tmp = ast_strdupa(data);
07767       AST_STANDARD_APP_ARGS(args, tmp);
07768       if (args.argc == 2) {
07769          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07770             ast_module_user_remove(u);
07771             return -1;
07772          }
07773          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07774          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07775             int gain;
07776 
07777             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
07778                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07779                ast_module_user_remove(u);
07780                return -1;
07781             } else {
07782                leave_options.record_gain = (signed char) gain;
07783             }
07784          }
07785       } else {
07786          /* old style options parsing */
07787          int old = 0;
07788          char *orig_argv0 = args.argv0;
07789          while (*(args.argv0)) {
07790             if (*(args.argv0) == 's') {
07791                old = 1;
07792                ast_set_flag(&leave_options, OPT_SILENT);
07793             } else if (*(args.argv0) == 'b') {
07794                old = 1;
07795                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07796             } else if (*(args.argv0) == 'u') {
07797                old = 1;
07798                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07799             } else if (*(args.argv0) == 'j') {
07800                old = 1;
07801                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07802             } else
07803                break;
07804             (args.argv0)++;
07805          }
07806          if (!deprecate_warning && old) {
07807             deprecate_warning = 1;
07808             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07809             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07810          }
07811       }
07812    } else {
07813       char tmp[256];
07814       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07815       if (res < 0) {
07816          ast_module_user_remove(u);
07817          return res;
07818       }
07819       if (ast_strlen_zero(tmp)) {
07820          ast_module_user_remove(u);
07821          return 0;
07822       }
07823       args.argv0 = ast_strdupa(tmp);
07824    }
07825 
07826    res = leave_voicemail(chan, args.argv0, &leave_options);
07827 
07828    if (res == ERROR_LOCK_PATH) {
07829       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07830       /*Send the call to n+101 priority, where n is the current priority*/
07831       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07832          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07833             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07834       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07835       res = 0;
07836    }
07837    
07838    ast_module_user_remove(u);
07839 
07840    return res;
07841 }

static int vm_execmain ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 7170 of file app_voicemail.c.

References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_calloc, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_module_user_add, ast_module_user_remove, ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, create_dirpath(), dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free, free_user(), get_folder2(), globalflags, has_voicemail(), language, ast_vm_user::language, LOG_DEBUG, ast_vm_user::mailbox, make_file(), manager_event(), ast_vm_user::maxmsg, open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, option_debug, option_verbose, parse(), ast_vm_user::password, play_message(), run_externnotify(), save_to_folder(), say_and_wait(), VERBOSE_PREFIX_3, vm_app_options, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, and VM_SVMAIL.

Referenced by load_module().

07171 {
07172    /* XXX This is, admittedly, some pretty horrendus code.  For some
07173       reason it just seemed a lot easier to do with GOTO's.  I feel
07174       like I'm back in my GWBASIC days. XXX */
07175    int res=-1;
07176    int cmd=0;
07177    int valid = 0;
07178    struct ast_module_user *u;
07179    char prefixstr[80] ="";
07180    char ext_context[256]="";
07181    int box;
07182    int useadsi = 0;
07183    int skipuser = 0;
07184    struct vm_state vms;
07185    struct ast_vm_user *vmu = NULL, vmus;
07186    char *context=NULL;
07187    int silentexit = 0;
07188    struct ast_flags flags = { 0 };
07189    signed char record_gain = 0;
07190    int play_auto = 0;
07191    int play_folder = 0;
07192 #ifdef IMAP_STORAGE
07193    int deleted = 0;
07194 #endif
07195    u = ast_module_user_add(chan);
07196 
07197    /* Add the vm_state to the active list and keep it active */
07198    memset(&vms, 0, sizeof(vms));
07199    vms.lastmsg = -1;
07200 
07201    memset(&vmus, 0, sizeof(vmus));
07202 
07203    if (chan->_state != AST_STATE_UP) {
07204       if (option_debug)
07205          ast_log(LOG_DEBUG, "Before ast_answer\n");
07206       ast_answer(chan);
07207    }
07208 
07209    if (!ast_strlen_zero(data)) {
07210       char *opts[OPT_ARG_ARRAY_SIZE];
07211       char *parse;
07212       AST_DECLARE_APP_ARGS(args,
07213          AST_APP_ARG(argv0);
07214          AST_APP_ARG(argv1);
07215       );
07216 
07217       parse = ast_strdupa(data);
07218 
07219       AST_STANDARD_APP_ARGS(args, parse);
07220 
07221       if (args.argc == 2) {
07222          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07223             ast_module_user_remove(u);
07224             return -1;
07225          }
07226          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07227             int gain;
07228             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
07229                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
07230                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07231                   ast_module_user_remove(u);
07232                   return -1;
07233                } else {
07234                   record_gain = (signed char) gain;
07235                }
07236             } else {
07237                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
07238             }
07239          }
07240          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
07241             play_auto = 1;
07242             if (opts[OPT_ARG_PLAYFOLDER]) {
07243                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
07244                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
07245                }
07246             } else {
07247                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
07248             }  
07249             if ( play_folder > 9 || play_folder < 0) {
07250                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
07251                play_folder = 0;
07252             }
07253          }
07254       } else {
07255          /* old style options parsing */
07256          while (*(args.argv0)) {
07257             if (*(args.argv0) == 's')
07258                ast_set_flag(&flags, OPT_SILENT);
07259             else if (*(args.argv0) == 'p')
07260                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
07261             else 
07262                break;
07263             (args.argv0)++;
07264          }
07265 
07266       }
07267 
07268       valid = ast_test_flag(&flags, OPT_SILENT);
07269 
07270       if ((context = strchr(args.argv0, '@')))
07271          *context++ = '\0';
07272 
07273       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
07274          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
07275       else
07276          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
07277 
07278       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
07279          skipuser++;
07280       else
07281          valid = 0;
07282    }
07283 
07284    if (!valid)
07285       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
07286 
07287    if (option_debug)
07288       ast_log(LOG_DEBUG, "After vm_authenticate\n");
07289    if (!res) {
07290       valid = 1;
07291       if (!skipuser)
07292          vmu = &vmus;
07293    } else {
07294       res = 0;
07295    }
07296 
07297    /* If ADSI is supported, setup login screen */
07298    adsi_begin(chan, &useadsi);
07299 
07300 #ifdef IMAP_STORAGE
07301    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
07302    pthread_setspecific(ts_vmstate.key, &vms);
07303 
07304    vms.interactive = 1;
07305    vms.updated = 1;
07306    if (vmu)
07307       ast_copy_string(vms.context, vmu->context, sizeof(vms.context));
07308    vmstate_insert(&vms);
07309    init_vm_state(&vms);
07310 #endif
07311    if (!valid)
07312       goto out;
07313 
07314    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07315       /* TODO: Handle memory allocation failure */
07316    }
07317    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07318       /* TODO: Handle memory allocation failure */
07319    }
07320    
07321    /* Set language from config to override channel language */
07322    if (!ast_strlen_zero(vmu->language))
07323       ast_string_field_set(chan, language, vmu->language);
07324    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
07325    /* Retrieve old and new message counts */
07326    if (option_debug)
07327       ast_log(LOG_DEBUG, "Before open_mailbox\n");
07328    res = open_mailbox(&vms, vmu, 1);
07329    if (res == ERROR_LOCK_PATH)
07330       goto out;
07331    vms.oldmessages = vms.lastmsg + 1;
07332    if (option_debug > 2)
07333       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
07334    /* Start in INBOX */
07335    res = open_mailbox(&vms, vmu, 0);
07336    if (res == ERROR_LOCK_PATH)
07337       goto out;
07338    vms.newmessages = vms.lastmsg + 1;
07339    if (option_debug > 2)
07340       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
07341       
07342    /* Select proper mailbox FIRST!! */
07343    if (play_auto) {
07344       res = open_mailbox(&vms, vmu, play_folder);
07345       if (res == ERROR_LOCK_PATH)
07346          goto out;
07347 
07348       /* If there are no new messages, inform the user and hangup */
07349       if (vms.lastmsg == -1) {
07350          cmd = vm_browse_messages(chan, &vms, vmu);
07351          res = 0;
07352          goto out;
07353       }
07354    } else {
07355       if (!vms.newmessages && vms.oldmessages) {
07356          /* If we only have old messages start here */
07357          res = open_mailbox(&vms, vmu, 1);
07358          play_folder = 1;
07359          if (res == ERROR_LOCK_PATH)
07360             goto out;
07361       }
07362    }
07363 
07364    if (useadsi)
07365       adsi_status(chan, &vms);
07366    res = 0;
07367 
07368    /* Check to see if this is a new user */
07369    if (!strcasecmp(vmu->mailbox, vmu->password) && 
07370       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
07371       if (ast_play_and_wait(chan, "vm-newuser") == -1)
07372          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
07373       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
07374       if ((cmd == 't') || (cmd == '#')) {
07375          /* Timeout */
07376          res = 0;
07377          goto out;
07378       } else if (cmd < 0) {
07379          /* Hangup */
07380          res = -1;
07381          goto out;
07382       }
07383    }
07384 #ifdef IMAP_STORAGE
07385       if (option_debug > 2)
07386          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
07387       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
07388          if (option_debug)
07389             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
07390          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07391       }
07392       if (option_debug > 2)
07393          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07394       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
07395          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07396          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07397       }
07398 #endif
07399    if (play_auto) {
07400       cmd = '1';
07401    } else {
07402       cmd = vm_intro(chan, vmu, &vms);
07403    }
07404 
07405    vms.repeats = 0;
07406    vms.starting = 1;
07407    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07408       /* Run main menu */
07409       switch (cmd) {
07410       case '1':
07411          vms.curmsg = 0;
07412          /* Fall through */
07413       case '5':
07414          cmd = vm_browse_messages(chan, &vms, vmu);
07415          break;
07416       case '2': /* Change folders */
07417          if (useadsi)
07418             adsi_folders(chan, 0, "Change to folder...");
07419          cmd = get_folder2(chan, "vm-changeto", 0);
07420          if (cmd == '#') {
07421             cmd = 0;
07422          } else if (cmd > 0) {
07423             cmd = cmd - '0';
07424             res = close_mailbox(&vms, vmu);
07425             if (res == ERROR_LOCK_PATH)
07426                goto out;
07427             res = open_mailbox(&vms, vmu, cmd);
07428             if (res == ERROR_LOCK_PATH)
07429                goto out;
07430             play_folder = cmd;
07431             cmd = 0;
07432          }
07433          if (useadsi)
07434             adsi_status2(chan, &vms);
07435             
07436          if (!cmd)
07437             cmd = vm_play_folder_name(chan, vms.vmbox);
07438 
07439          vms.starting = 1;
07440          break;
07441       case '3': /* Advanced options */
07442          cmd = 0;
07443          vms.repeats = 0;
07444          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07445             switch (cmd) {
07446             case '1': /* Reply */
07447                if (vms.lastmsg > -1 && !vms.starting) {
07448                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
07449                   if (cmd == ERROR_LOCK_PATH) {
07450                      res = cmd;
07451                      goto out;
07452                   }
07453                } else
07454                   cmd = ast_play_and_wait(chan, "vm-sorry");
07455                cmd = 't';
07456                break;
07457             case '2': /* Callback */
07458                if (option_verbose > 2 && !vms.starting)
07459                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
07460                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
07461                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
07462                   if (cmd == 9) {
07463                      silentexit = 1;
07464                      goto out;
07465                   } else if (cmd == ERROR_LOCK_PATH) {
07466                      res = cmd;
07467                      goto out;
07468                   }
07469                }
07470                else 
07471                   cmd = ast_play_and_wait(chan, "vm-sorry");
07472                cmd = 't';
07473                break;
07474             case '3': /* Envelope */
07475                if (vms.lastmsg > -1 && !vms.starting) {
07476                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
07477                   if (cmd == ERROR_LOCK_PATH) {
07478                      res = cmd;
07479                      goto out;
07480                   }
07481                } else
07482                   cmd = ast_play_and_wait(chan, "vm-sorry");
07483                cmd = 't';
07484                break;
07485             case '4': /* Dialout */
07486                if (!ast_strlen_zero(vmu->dialout)) {
07487                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
07488                   if (cmd == 9) {
07489                      silentexit = 1;
07490                      goto out;
07491                   }
07492                }
07493                else 
07494                   cmd = ast_play_and_wait(chan, "vm-sorry");
07495                cmd = 't';
07496                break;
07497 
07498             case '5': /* Leave VoiceMail */
07499                if (ast_test_flag(vmu, VM_SVMAIL)) {
07500                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
07501                   if (cmd == ERROR_LOCK_PATH) {
07502                      res = cmd;
07503                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
07504                      goto out;
07505                   }
07506                } else
07507                   cmd = ast_play_and_wait(chan,"vm-sorry");
07508                cmd='t';
07509                break;
07510                
07511             case '*': /* Return to main menu */
07512                cmd = 't';
07513                break;
07514 
07515             default:
07516                cmd = 0;
07517                if (!vms.starting) {
07518                   cmd = ast_play_and_wait(chan, "vm-toreply");
07519                }
07520                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
07521                   cmd = ast_play_and_wait(chan, "vm-tocallback");
07522                }
07523                if (!cmd && !vms.starting) {
07524                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
07525                }
07526                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
07527                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
07528                }
07529                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
07530                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
07531                if (!cmd)
07532                   cmd = ast_play_and_wait(chan, "vm-starmain");
07533                if (!cmd)
07534                   cmd = ast_waitfordigit(chan,6000);
07535                if (!cmd)
07536                   vms.repeats++;
07537                if (vms.repeats > 3)
07538                   cmd = 't';
07539             }
07540          }
07541          if (cmd == 't') {
07542             cmd = 0;
07543             vms.repeats = 0;
07544          }
07545          break;
07546       case '4':
07547          if (vms.curmsg > 0) {
07548             vms.curmsg--;
07549             cmd = play_message(chan, vmu, &vms);
07550          } else {
07551             cmd = ast_play_and_wait(chan, "vm-nomore");
07552          }
07553          break;
07554       case '6':
07555          if (vms.curmsg < vms.lastmsg) {
07556             vms.curmsg++;
07557             cmd = play_message(chan, vmu, &vms);
07558          } else {
07559             cmd = ast_play_and_wait(chan, "vm-nomore");
07560          }
07561          break;
07562       case '7':
07563          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
07564             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
07565             if (useadsi)
07566                adsi_delete(chan, &vms);
07567             if (vms.deleted[vms.curmsg]) {
07568                if (play_folder == 0)
07569                   vms.newmessages--;
07570                else if (play_folder == 1)
07571                   vms.oldmessages--;
07572                cmd = ast_play_and_wait(chan, "vm-deleted");
07573             }
07574             else {
07575                if (play_folder == 0)
07576                   vms.newmessages++;
07577                else if (play_folder == 1)
07578                   vms.oldmessages++;
07579                cmd = ast_play_and_wait(chan, "vm-undeleted");
07580             }
07581             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07582                if (vms.curmsg < vms.lastmsg) {
07583                   vms.curmsg++;
07584                   cmd = play_message(chan, vmu, &vms);
07585                } else {
07586                   cmd = ast_play_and_wait(chan, "vm-nomore");
07587                }
07588             }
07589          } else /* Delete not valid if we haven't selected a message */
07590             cmd = 0;
07591 #ifdef IMAP_STORAGE
07592          deleted = 1;
07593 #endif
07594          break;
07595    
07596       case '8':
07597          if (vms.lastmsg > -1) {
07598             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
07599             if (cmd == ERROR_LOCK_PATH) {
07600                res = cmd;
07601                goto out;
07602             }
07603          } else
07604             cmd = ast_play_and_wait(chan, "vm-nomore");
07605          break;
07606       case '9':
07607          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
07608             /* No message selected */
07609             cmd = 0;
07610             break;
07611          }
07612          if (useadsi)
07613             adsi_folders(chan, 1, "Save to folder...");
07614          cmd = get_folder2(chan, "vm-savefolder", 1);
07615          box = 0; /* Shut up compiler */
07616          if (cmd == '#') {
07617             cmd = 0;
07618             break;
07619          } else if (cmd > 0) {
07620             box = cmd = cmd - '0';
07621             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
07622             if (cmd == ERROR_LOCK_PATH) {
07623                res = cmd;
07624                goto out;
07625 #ifndef IMAP_STORAGE
07626             } else if (!cmd) {
07627                vms.deleted[vms.curmsg] = 1;
07628 #endif
07629             } else {
07630                vms.deleted[vms.curmsg] = 0;
07631                vms.heard[vms.curmsg] = 0;
07632             }
07633          }
07634          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
07635          if (useadsi)
07636             adsi_message(chan, &vms);
07637          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
07638          if (!cmd) {
07639             cmd = ast_play_and_wait(chan, "vm-message");
07640             if (!cmd)
07641                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
07642             if (!cmd)
07643                cmd = ast_play_and_wait(chan, "vm-savedto");
07644             if (!cmd)
07645                cmd = vm_play_folder_name(chan, vms.fn);
07646          } else {
07647             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07648          }
07649          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07650             if (vms.curmsg < vms.lastmsg) {
07651                vms.curmsg++;
07652                cmd = play_message(chan, vmu, &vms);
07653             } else {
07654                cmd = ast_play_and_wait(chan, "vm-nomore");
07655             }
07656          }
07657          break;
07658       case '*':
07659          if (!vms.starting) {
07660             cmd = ast_play_and_wait(chan, "vm-onefor");
07661             if (!strcasecmp(chan->language, "he")) 
07662                cmd = ast_play_and_wait(chan, "vm-for");
07663             if (!cmd)
07664                cmd = vm_play_folder_name(chan, vms.vmbox);
07665             if (!cmd)
07666                cmd = ast_play_and_wait(chan, "vm-opts");
07667             if (!cmd)
07668                cmd = vm_instructions(chan, &vms, 1);
07669          } else
07670             cmd = 0;
07671          break;
07672       case '0':
07673          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
07674          if (useadsi)
07675             adsi_status(chan, &vms);
07676          break;
07677       default: /* Nothing */
07678          cmd = vm_instructions(chan, &vms, 0);
07679          break;
07680       }
07681    }
07682    if ((cmd == 't') || (cmd == '#')) {
07683       /* Timeout */
07684       res = 0;
07685    } else {
07686       /* Hangup */
07687       res = -1;
07688    }
07689 
07690 out:
07691    if (res > -1) {
07692       ast_stopstream(chan);
07693       adsi_goodbye(chan);
07694       if (valid) {
07695          if (silentexit)
07696             res = ast_play_and_wait(chan, "vm-dialout");
07697          else 
07698             res = ast_play_and_wait(chan, "vm-goodbye");
07699          if (res > 0)
07700             res = 0;
07701       }
07702       if (useadsi)
07703          ast_adsi_unload_session(chan);
07704    }
07705    if (vmu)
07706       close_mailbox(&vms, vmu);
07707    if (valid) {
07708       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
07709       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
07710       run_externnotify(vmu->context, vmu->mailbox);
07711    }
07712 #ifdef IMAP_STORAGE
07713    /* expunge message - use UID Expunge if supported on IMAP server*/
07714    if (option_debug > 2)
07715       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
07716    if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) {
07717       ast_mutex_lock(&vms.lock);
07718 #ifdef HAVE_IMAP_TK2006
07719       if (LEVELUIDPLUS (vms.mailstream)) {
07720          mail_expunge_full(vms.mailstream,NIL,EX_UID);
07721       } else 
07722 #endif
07723          mail_expunge(vms.mailstream);
07724       ast_mutex_unlock(&vms.lock);
07725    }
07726    /*  before we delete the state, we should copy pertinent info
07727     *  back to the persistent model */
07728    vmstate_delete(&vms);
07729 #endif
07730    if (vmu)
07731       free_user(vmu);
07732    if (vms.deleted)
07733       free(vms.deleted);
07734    if (vms.heard)
07735       free(vms.heard);
07736 
07737 #ifdef IMAP_STORAGE
07738    pthread_setspecific(ts_vmstate.key, NULL);
07739 #endif
07740    ast_module_user_remove(u);
07741    return res;
07742 }

static int vm_forwardoptions ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  curdir,
int  curmsg,
char *  vmfmts,
char *  context,
signed char  record_gain,
long *  duration,
struct vm_state vms 
) [static]

Definition at line 4902 of file app_voicemail.c.

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), ast_filecopy(), ast_filedelete(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), config_text_file_save(), and make_file().

Referenced by forward_message().

04904 {
04905    int cmd = 0;
04906    int retries = 0, prepend_duration = 0, already_recorded = 0;
04907    signed char zero_gain = 0;
04908    struct ast_config *msg_cfg;
04909    const char *duration_str;
04910    char msgfile[PATH_MAX], backup[PATH_MAX];
04911    char textfile[PATH_MAX];
04912 
04913    /* Must always populate duration correctly */
04914    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
04915    strcpy(textfile, msgfile);
04916    strcpy(backup, msgfile);
04917    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
04918    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
04919 
04920    if (!(msg_cfg = ast_config_load(textfile))) {
04921       return -1;
04922    }
04923 
04924    *duration = 0;
04925    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
04926       *duration = atoi(duration_str);
04927 
04928    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
04929       if (cmd)
04930          retries = 0;
04931       switch (cmd) {
04932       case '1': 
04933          /* prepend a message to the current message, update the metadata and return */
04934       {
04935          prepend_duration = 0;
04936 
04937          /* if we can't read the message metadata, stop now */
04938          if (!msg_cfg) {
04939             cmd = 0;
04940             break;
04941          }
04942 
04943          /* Back up the original file, so we can retry the prepend */
04944          if (already_recorded)
04945             ast_filecopy(backup, msgfile, NULL);
04946          else
04947             ast_filecopy(msgfile, backup, NULL);
04948          already_recorded = 1;
04949 
04950          if (record_gain)
04951             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
04952 
04953          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
04954          if (record_gain)
04955             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
04956 
04957          if (prepend_duration) {
04958             struct ast_category *msg_cat;
04959             /* need enough space for a maximum-length message duration */
04960             char duration_str[12];
04961 
04962             prepend_duration += *duration;
04963             msg_cat = ast_category_get(msg_cfg, "message");
04964             snprintf(duration_str, 11, "%d", prepend_duration);
04965             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
04966                config_text_file_save(textfile, msg_cfg, "app_voicemail");
04967             }
04968          }
04969 
04970          break;
04971       }
04972       case '2': 
04973          cmd = 't';
04974          break;
04975       case '*':
04976          cmd = '*';
04977          break;
04978       default: 
04979          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
04980             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
04981          if (!cmd)
04982             cmd = ast_play_and_wait(chan,"vm-starmain");
04983             /* "press star to return to the main menu" */
04984          if (!cmd)
04985             cmd = ast_waitfordigit(chan,6000);
04986          if (!cmd)
04987             retries++;
04988          if (retries > 3)
04989             cmd = 't';
04990       }
04991    }
04992 
04993    ast_config_destroy(msg_cfg);
04994    if (already_recorded)
04995       ast_filedelete(backup, NULL);
04996    if (prepend_duration)
04997       *duration = prepend_duration;
04998 
04999    if (cmd == 't' || cmd == 'S')
05000       cmd = 0;
05001    return cmd;
05002 }

static int vm_instructions ( struct ast_channel chan,
struct vm_state vms,
int  skipadvanced 
) [static]

Definition at line 6682 of file app_voicemail.c.

References ast_play_and_wait(), ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, ast_channel::language, vm_state::lastmsg, vm_state::repeats, vm_state::starting, vm_play_folder_name(), and vm_state::vmbox.

Referenced by vm_execmain().

06683 {
06684    int res = 0;
06685    /* Play instructions and wait for new command */
06686    while (!res) {
06687       if (vms->starting) {
06688          if (vms->lastmsg > -1) {
06689             res = ast_play_and_wait(chan, "vm-onefor");
06690             if (!strcasecmp(chan->language, "he")) 
06691                res = ast_play_and_wait(chan, "vm-for");
06692             if (!res)
06693                res = vm_play_folder_name(chan, vms->vmbox);
06694          }
06695          if (!res)
06696             res = ast_play_and_wait(chan, "vm-opts");
06697       } else {
06698          if (vms->curmsg)
06699             res = ast_play_and_wait(chan, "vm-prev");
06700          if (!res && !skipadvanced)
06701             res = ast_play_and_wait(chan, "vm-advopts");
06702          if (!res)
06703             res = ast_play_and_wait(chan, "vm-repeat");
06704          if (!res && (vms->curmsg != vms->lastmsg))
06705             res = ast_play_and_wait(chan, "vm-next");
06706          if (!res) {
06707             if (!vms->deleted[vms->curmsg])
06708                res = ast_play_and_wait(chan, "vm-delete");
06709             else
06710                res = ast_play_and_wait(chan, "vm-undelete");
06711             if (!res)
06712                res = ast_play_and_wait(chan, "vm-toforward");
06713             if (!res)
06714                res = ast_play_and_wait(chan, "vm-savemessage");
06715          }
06716       }
06717       if (!res)
06718          res = ast_play_and_wait(chan, "vm-helpexit");
06719       if (!res)
06720          res = ast_waitfordigit(chan, 6000);
06721       if (!res) {
06722          vms->repeats++;
06723          if (vms->repeats > 2) {
06724             res = 't';
06725          }
06726       }
06727    }
06728    return res;
06729 }

static int vm_intro ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
) [static]

Definition at line 6633 of file app_voicemail.c.

References ast_fileexists(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, RETRIEVE, vm_state::username, vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), and VM_TEMPGREETWARN.

Referenced by vm_execmain().

06634 {
06635    char prefile[256];
06636    
06637    /* Notify the user that the temp greeting is set and give them the option to remove it */
06638    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06639    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
06640       RETRIEVE(prefile, -1, vmu);
06641       if (ast_fileexists(prefile, NULL, NULL) > 0)
06642          ast_play_and_wait(chan, "vm-tempgreetactive");
06643       DISPOSE(prefile, -1);
06644    }
06645 
06646    /* Play voicemail intro - syntax is different for different languages */
06647    if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
06648       return vm_intro_de(chan, vms);
06649    } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */
06650       return vm_intro_es(chan, vms);
06651    } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
06652       return vm_intro_it(chan, vms);
06653    } else if (!strncasecmp(chan->language, "fr", 2)) {   /* FRENCH syntax */
06654       return vm_intro_fr(chan, vms);
06655    } else if (!strncasecmp(chan->language, "nl", 2)) {   /* DUTCH syntax */
06656       return vm_intro_nl(chan, vms);
06657    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
06658       return vm_intro_pt_BR(chan, vms);      
06659    } else if (!strncasecmp(chan->language, "pt", 2)) {   /* PORTUGUESE syntax */
06660       return vm_intro_pt(chan, vms);
06661    } else if (!strncasecmp(chan->language, "cz", 2)) {   /* CZECH syntax */
06662       return vm_intro_cz(chan, vms);
06663    } else if (!strncasecmp(chan->language, "gr", 2)) {   /* GREEK syntax */
06664       return vm_intro_gr(chan, vms);
06665    } else if (!strncasecmp(chan->language, "pl", 2)) {   /* POLISH syntax */
06666       return vm_intro_pl(chan, vms);
06667    } else if (!strncasecmp(chan->language, "se", 2)) {   /* SWEDISH syntax */
06668       return vm_intro_se(chan, vms);
06669    } else if (!strncasecmp(chan->language, "no", 2)) {   /* NORWEGIAN syntax */
06670       return vm_intro_no(chan, vms);
06671    } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */
06672       return vm_intro_multilang(chan, vms, "n");
06673    } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */
06674       return vm_intro_multilang(chan, vms, "n");
06675    } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */
06676       return vm_intro_he(chan, vms);
06677    } else {             /* Default to ENGLISH */
06678       return vm_intro_en(chan, vms);
06679    }
06680 }

static int vm_intro_cz ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6573 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06574 {
06575    int res;
06576    res = ast_play_and_wait(chan, "vm-youhave");
06577    if (!res) {
06578       if (vms->newmessages) {
06579          if (vms->newmessages == 1) {
06580             res = ast_play_and_wait(chan, "digits/jednu");
06581          } else {
06582             res = say_and_wait(chan, vms->newmessages, chan->language);
06583          }
06584          if (!res) {
06585             if ((vms->newmessages == 1))
06586                res = ast_play_and_wait(chan, "vm-novou");
06587             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06588                res = ast_play_and_wait(chan, "vm-nove");
06589             if (vms->newmessages > 4)
06590                res = ast_play_and_wait(chan, "vm-novych");
06591          }
06592          if (vms->oldmessages && !res)
06593             res = ast_play_and_wait(chan, "vm-and");
06594          else if (!res) {
06595             if ((vms->newmessages == 1))
06596                res = ast_play_and_wait(chan, "vm-zpravu");
06597             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06598                res = ast_play_and_wait(chan, "vm-zpravy");
06599             if (vms->newmessages > 4)
06600                res = ast_play_and_wait(chan, "vm-zprav");
06601          }
06602       }
06603       if (!res && vms->oldmessages) {
06604          res = say_and_wait(chan, vms->oldmessages, chan->language);
06605          if (!res) {
06606             if ((vms->oldmessages == 1))
06607                res = ast_play_and_wait(chan, "vm-starou");
06608             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06609                res = ast_play_and_wait(chan, "vm-stare");
06610             if (vms->oldmessages > 4)
06611                res = ast_play_and_wait(chan, "vm-starych");
06612          }
06613          if (!res) {
06614             if ((vms->oldmessages == 1))
06615                res = ast_play_and_wait(chan, "vm-zpravu");
06616             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06617                res = ast_play_and_wait(chan, "vm-zpravy");
06618             if (vms->oldmessages > 4)
06619                res = ast_play_and_wait(chan, "vm-zprav");
06620          }
06621       }
06622       if (!res) {
06623          if (!vms->oldmessages && !vms->newmessages) {
06624             res = ast_play_and_wait(chan, "vm-no");
06625             if (!res)
06626                res = ast_play_and_wait(chan, "vm-zpravy");
06627          }
06628       }
06629    }
06630    return res;
06631 }

static int vm_intro_de ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6266 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06267 {
06268    /* Introduce messages they have */
06269    int res;
06270    res = ast_play_and_wait(chan, "vm-youhave");
06271    if (!res) {
06272       if (vms->newmessages) {
06273          if ((vms->newmessages == 1))
06274             res = ast_play_and_wait(chan, "digits/1F");
06275          else
06276             res = say_and_wait(chan, vms->newmessages, chan->language);
06277          if (!res)
06278             res = ast_play_and_wait(chan, "vm-INBOX");
06279          if (vms->oldmessages && !res)
06280             res = ast_play_and_wait(chan, "vm-and");
06281          else if (!res) {
06282             if ((vms->newmessages == 1))
06283                res = ast_play_and_wait(chan, "vm-message");
06284             else
06285                res = ast_play_and_wait(chan, "vm-messages");
06286          }
06287             
06288       }
06289       if (!res && vms->oldmessages) {
06290          if (vms->oldmessages == 1)
06291             res = ast_play_and_wait(chan, "digits/1F");
06292          else
06293             res = say_and_wait(chan, vms->oldmessages, chan->language);
06294          if (!res)
06295             res = ast_play_and_wait(chan, "vm-Old");
06296          if (!res) {
06297             if (vms->oldmessages == 1)
06298                res = ast_play_and_wait(chan, "vm-message");
06299             else
06300                res = ast_play_and_wait(chan, "vm-messages");
06301          }
06302       }
06303       if (!res) {
06304          if (!vms->oldmessages && !vms->newmessages) {
06305             res = ast_play_and_wait(chan, "vm-no");
06306             if (!res)
06307                res = ast_play_and_wait(chan, "vm-messages");
06308          }
06309       }
06310    }
06311    return res;
06312 }

static int vm_intro_en ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5865 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

05866 {
05867    int res;
05868 
05869    /* Introduce messages they have */
05870    res = ast_play_and_wait(chan, "vm-youhave");
05871    if (!res) {
05872       if (vms->newmessages) {
05873          res = say_and_wait(chan, vms->newmessages, chan->language);
05874          if (!res)
05875             res = ast_play_and_wait(chan, "vm-INBOX");
05876          if (vms->oldmessages && !res)
05877             res = ast_play_and_wait(chan, "vm-and");
05878          else if (!res) {
05879             if ((vms->newmessages == 1))
05880                res = ast_play_and_wait(chan, "vm-message");
05881             else
05882                res = ast_play_and_wait(chan, "vm-messages");
05883          }
05884             
05885       }
05886       if (!res && vms->oldmessages) {
05887          res = say_and_wait(chan, vms->oldmessages, chan->language);
05888          if (!res)
05889             res = ast_play_and_wait(chan, "vm-Old");
05890          if (!res) {
05891             if (vms->oldmessages == 1)
05892                res = ast_play_and_wait(chan, "vm-message");
05893             else
05894                res = ast_play_and_wait(chan, "vm-messages");
05895          }
05896       }
05897       if (!res) {
05898          if (!vms->oldmessages && !vms->newmessages) {
05899             res = ast_play_and_wait(chan, "vm-no");
05900             if (!res)
05901                res = ast_play_and_wait(chan, "vm-messages");
05902          }
05903       }
05904    }
05905    return res;
05906 }

static int vm_intro_es ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6315 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06316 {
06317    /* Introduce messages they have */
06318    int res;
06319    if (!vms->oldmessages && !vms->newmessages) {
06320       res = ast_play_and_wait(chan, "vm-youhaveno");
06321       if (!res)
06322          res = ast_play_and_wait(chan, "vm-messages");
06323    } else {
06324       res = ast_play_and_wait(chan, "vm-youhave");
06325    }
06326    if (!res) {
06327       if (vms->newmessages) {
06328          if (!res) {
06329             if ((vms->newmessages == 1)) {
06330                res = ast_play_and_wait(chan, "digits/1M");
06331                if (!res)
06332                   res = ast_play_and_wait(chan, "vm-message");
06333                if (!res)
06334                   res = ast_play_and_wait(chan, "vm-INBOXs");
06335             } else {
06336                res = say_and_wait(chan, vms->newmessages, chan->language);
06337                if (!res)
06338                   res = ast_play_and_wait(chan, "vm-messages");
06339                if (!res)
06340                   res = ast_play_and_wait(chan, "vm-INBOX");
06341             }
06342          }
06343          if (vms->oldmessages && !res)
06344             res = ast_play_and_wait(chan, "vm-and");
06345       }
06346       if (vms->oldmessages) {
06347          if (!res) {
06348             if (vms->oldmessages == 1) {
06349                res = ast_play_and_wait(chan, "digits/1M");
06350                if (!res)
06351                   res = ast_play_and_wait(chan, "vm-message");
06352                if (!res)
06353                   res = ast_play_and_wait(chan, "vm-Olds");
06354             } else {
06355                res = say_and_wait(chan, vms->oldmessages, chan->language);
06356                if (!res)
06357                   res = ast_play_and_wait(chan, "vm-messages");
06358                if (!res)
06359                   res = ast_play_and_wait(chan, "vm-Old");
06360             }
06361          }
06362       }
06363    }
06364 return res;
06365 }

static int vm_intro_fr ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6416 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06417 {
06418    /* Introduce messages they have */
06419    int res;
06420    res = ast_play_and_wait(chan, "vm-youhave");
06421    if (!res) {
06422       if (vms->newmessages) {
06423          res = say_and_wait(chan, vms->newmessages, chan->language);
06424          if (!res)
06425             res = ast_play_and_wait(chan, "vm-INBOX");
06426          if (vms->oldmessages && !res)
06427             res = ast_play_and_wait(chan, "vm-and");
06428          else if (!res) {
06429             if ((vms->newmessages == 1))
06430                res = ast_play_and_wait(chan, "vm-message");
06431             else
06432                res = ast_play_and_wait(chan, "vm-messages");
06433          }
06434             
06435       }
06436       if (!res && vms->oldmessages) {
06437          res = say_and_wait(chan, vms->oldmessages, chan->language);
06438          if (!res)
06439             res = ast_play_and_wait(chan, "vm-Old");
06440          if (!res) {
06441             if (vms->oldmessages == 1)
06442                res = ast_play_and_wait(chan, "vm-message");
06443             else
06444                res = ast_play_and_wait(chan, "vm-messages");
06445          }
06446       }
06447       if (!res) {
06448          if (!vms->oldmessages && !vms->newmessages) {
06449             res = ast_play_and_wait(chan, "vm-no");
06450             if (!res)
06451                res = ast_play_and_wait(chan, "vm-messages");
06452          }
06453       }
06454    }
06455    return res;
06456 }

static int vm_intro_gr ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 5827 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

05828 {
05829    int res = 0;
05830 
05831    if (vms->newmessages) {
05832       res = ast_play_and_wait(chan, "vm-youhave");
05833       if (!res) 
05834          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05835       if (!res) {
05836          if ((vms->newmessages == 1)) {
05837             res = ast_play_and_wait(chan, "vm-INBOX");
05838             if (!res)
05839                res = ast_play_and_wait(chan, "vm-message");
05840          } else {
05841             res = ast_play_and_wait(chan, "vm-INBOXs");
05842             if (!res)
05843                res = ast_play_and_wait(chan, "vm-messages");
05844          }
05845       }
05846    } else if (vms->oldmessages){
05847       res = ast_play_and_wait(chan, "vm-youhave");
05848       if (!res)
05849          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05850       if ((vms->oldmessages == 1)){
05851          res = ast_play_and_wait(chan, "vm-Old");
05852          if (!res)
05853             res = ast_play_and_wait(chan, "vm-message");
05854       } else {
05855          res = ast_play_and_wait(chan, "vm-Olds");
05856          if (!res)
05857             res = ast_play_and_wait(chan, "vm-messages");
05858       }
05859    } else if (!vms->oldmessages && !vms->newmessages) 
05860       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05861    return res;
05862 }

static int vm_intro_he ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6004 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

06005 {
06006    int res=0;
06007 
06008    /* Introduce messages they have */
06009    if (!res) {
06010       if ((vms->newmessages) || (vms->oldmessages)) {
06011          res = ast_play_and_wait(chan, "vm-youhave");
06012       }
06013       /*
06014        * The word "shtei" refers to the number 2 in hebrew when performing a count
06015        * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
06016        * an element, this is one of them.
06017        */
06018       if (vms->newmessages) {
06019          if (!res) {
06020             if (vms->newmessages == 1) {
06021                res = ast_play_and_wait(chan, "vm-INBOX1");
06022             } else {
06023                if (vms->newmessages == 2) {
06024                   res = ast_play_and_wait(chan, "vm-shtei");
06025                } else {
06026                   res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06027                }
06028                res = ast_play_and_wait(chan, "vm-INBOX");
06029             }
06030          }
06031          if (vms->oldmessages && !res) {
06032             res = ast_play_and_wait(chan, "vm-and");
06033             if (vms->oldmessages == 1) {
06034                res = ast_play_and_wait(chan, "vm-Old1");
06035             } else {
06036                if (vms->oldmessages == 2) {
06037                   res = ast_play_and_wait(chan, "vm-shtei");
06038                } else {
06039                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06040                }
06041                res = ast_play_and_wait(chan, "vm-Old");
06042             }
06043          }
06044       }
06045       if (!res && vms->oldmessages && !vms->newmessages) {
06046          if (!res) {
06047             if (vms->oldmessages == 1) {
06048                res = ast_play_and_wait(chan, "vm-Old1");
06049             } else {
06050                if (vms->oldmessages == 2) {
06051                   res = ast_play_and_wait(chan, "vm-shtei");
06052                } else {
06053                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");            
06054                }
06055                res = ast_play_and_wait(chan, "vm-Old");
06056             }
06057          }
06058       }
06059       if (!res) {
06060          if (!vms->oldmessages && !vms->newmessages) {
06061             if (!res) {
06062                res = ast_play_and_wait(chan, "vm-nomessages");
06063             }
06064          }
06065       }
06066    }
06067    return res;
06068 }

static int vm_intro_it ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6072 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06073 {
06074    /* Introduce messages they have */
06075    int res;
06076    if (!vms->oldmessages && !vms->newmessages)
06077       res = ast_play_and_wait(chan, "vm-no") ||
06078          ast_play_and_wait(chan, "vm-message");
06079    else
06080       res = ast_play_and_wait(chan, "vm-youhave");
06081    if (!res && vms->newmessages) {
06082       res = (vms->newmessages == 1) ?
06083          ast_play_and_wait(chan, "digits/un") ||
06084          ast_play_and_wait(chan, "vm-nuovo") ||
06085          ast_play_and_wait(chan, "vm-message") :
06086          /* 2 or more new messages */
06087          say_and_wait(chan, vms->newmessages, chan->language) ||
06088          ast_play_and_wait(chan, "vm-nuovi") ||
06089          ast_play_and_wait(chan, "vm-messages");
06090       if (!res && vms->oldmessages)
06091          res = ast_play_and_wait(chan, "vm-and");
06092    }
06093    if (!res && vms->oldmessages) {
06094       res = (vms->oldmessages == 1) ?
06095          ast_play_and_wait(chan, "digits/un") ||
06096          ast_play_and_wait(chan, "vm-vecchio") ||
06097          ast_play_and_wait(chan, "vm-message") :
06098          /* 2 or more old messages */
06099          say_and_wait(chan, vms->oldmessages, chan->language) ||
06100          ast_play_and_wait(chan, "vm-vecchi") ||
06101          ast_play_and_wait(chan, "vm-messages");
06102    }
06103    return res;
06104 }

static int vm_intro_multilang ( struct ast_channel chan,
struct vm_state vms,
const char  message_gender[] 
) [static]

Definition at line 5965 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

05966 {
05967    int res;
05968    int lastnum = 0;
05969 
05970    res = ast_play_and_wait(chan, "vm-youhave");
05971 
05972    if (!res && vms->newmessages) {
05973       lastnum = vms->newmessages;
05974 
05975       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
05976          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
05977       }
05978 
05979       if (!res && vms->oldmessages) {
05980          res = ast_play_and_wait(chan, "vm-and");
05981       }
05982    }
05983 
05984    if (!res && vms->oldmessages) {
05985       lastnum = vms->oldmessages;
05986 
05987       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
05988          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
05989       }
05990    }
05991 
05992    if (!res) {
05993       if (lastnum == 0) {
05994          res = ast_play_and_wait(chan, "vm-no");
05995       } else {
05996          res = ast_say_counted_noun(chan, lastnum, "vm-message");
05997       }
05998    }
05999 
06000    return res;
06001 }

static int vm_intro_nl ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6459 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06460 {
06461    /* Introduce messages they have */
06462    int res;
06463    res = ast_play_and_wait(chan, "vm-youhave");
06464    if (!res) {
06465       if (vms->newmessages) {
06466          res = say_and_wait(chan, vms->newmessages, chan->language);
06467          if (!res) {
06468             if (vms->newmessages == 1)
06469                res = ast_play_and_wait(chan, "vm-INBOXs");
06470             else
06471                res = ast_play_and_wait(chan, "vm-INBOX");
06472          }
06473          if (vms->oldmessages && !res)
06474             res = ast_play_and_wait(chan, "vm-and");
06475          else if (!res) {
06476             if ((vms->newmessages == 1))
06477                res = ast_play_and_wait(chan, "vm-message");
06478             else
06479                res = ast_play_and_wait(chan, "vm-messages");
06480          }
06481             
06482       }
06483       if (!res && vms->oldmessages) {
06484          res = say_and_wait(chan, vms->oldmessages, chan->language);
06485          if (!res) {
06486             if (vms->oldmessages == 1)
06487                res = ast_play_and_wait(chan, "vm-Olds");
06488             else
06489                res = ast_play_and_wait(chan, "vm-Old");
06490          }
06491          if (!res) {
06492             if (vms->oldmessages == 1)
06493                res = ast_play_and_wait(chan, "vm-message");
06494             else
06495                res = ast_play_and_wait(chan, "vm-messages");
06496          }
06497       }
06498       if (!res) {
06499          if (!vms->oldmessages && !vms->newmessages) {
06500             res = ast_play_and_wait(chan, "vm-no");
06501             if (!res)
06502                res = ast_play_and_wait(chan, "vm-messages");
06503          }
06504       }
06505    }
06506    return res;
06507 }

static int vm_intro_no ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6222 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06223 {
06224    /* Introduce messages they have */
06225    int res;
06226 
06227    res = ast_play_and_wait(chan, "vm-youhave");
06228    if (res)
06229       return res;
06230 
06231    if (!vms->oldmessages && !vms->newmessages) {
06232       res = ast_play_and_wait(chan, "vm-no");
06233       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06234       return res;
06235    }
06236 
06237    if (vms->newmessages) {
06238       if ((vms->newmessages == 1)) {
06239          res = ast_play_and_wait(chan, "digits/1");
06240          res = res ? res : ast_play_and_wait(chan, "vm-ny");
06241          res = res ? res : ast_play_and_wait(chan, "vm-message");
06242       } else {
06243          res = say_and_wait(chan, vms->newmessages, chan->language);
06244          res = res ? res : ast_play_and_wait(chan, "vm-nye");
06245          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06246       }
06247       if (!res && vms->oldmessages)
06248          res = ast_play_and_wait(chan, "vm-and");
06249    }
06250    if (!res && vms->oldmessages) {
06251       if (vms->oldmessages == 1) {
06252          res = ast_play_and_wait(chan, "digits/1");
06253          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
06254          res = res ? res : ast_play_and_wait(chan, "vm-message");
06255       } else {
06256          res = say_and_wait(chan, vms->oldmessages, chan->language);
06257          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
06258          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06259       }
06260    }
06261 
06262    return res;
06263 }

static int vm_intro_pl ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6107 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06108 {
06109    /* Introduce messages they have */
06110    int res;
06111    div_t num;
06112 
06113    if (!vms->oldmessages && !vms->newmessages) {
06114       res = ast_play_and_wait(chan, "vm-no");
06115       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06116       return res;
06117    } else {
06118       res = ast_play_and_wait(chan, "vm-youhave");
06119    }
06120 
06121    if (vms->newmessages) {
06122       num = div(vms->newmessages, 10);
06123       if (vms->newmessages == 1) {
06124          res = ast_play_and_wait(chan, "digits/1-a");
06125          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
06126          res = res ? res : ast_play_and_wait(chan, "vm-message");
06127       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06128          if (num.rem == 2) {
06129             if (!num.quot) {
06130                res = ast_play_and_wait(chan, "digits/2-ie");
06131             } else {
06132                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
06133                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06134             }
06135          } else {
06136             res = say_and_wait(chan, vms->newmessages, chan->language);
06137          }
06138          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
06139          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06140       } else {
06141          res = say_and_wait(chan, vms->newmessages, chan->language);
06142          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
06143          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06144       }
06145       if (!res && vms->oldmessages)
06146          res = ast_play_and_wait(chan, "vm-and");
06147    }
06148    if (!res && vms->oldmessages) {
06149       num = div(vms->oldmessages, 10);
06150       if (vms->oldmessages == 1) {
06151          res = ast_play_and_wait(chan, "digits/1-a");
06152          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
06153          res = res ? res : ast_play_and_wait(chan, "vm-message");
06154       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06155          if (num.rem == 2) {
06156             if (!num.quot) {
06157                res = ast_play_and_wait(chan, "digits/2-ie");
06158             } else {
06159                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
06160                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06161             }
06162          } else {
06163             res = say_and_wait(chan, vms->oldmessages, chan->language);
06164          }
06165          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
06166          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06167       } else {
06168          res = say_and_wait(chan, vms->oldmessages, chan->language);
06169          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
06170          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06171       }
06172    }
06173 
06174    return res;
06175 }

static int vm_intro_pt ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6510 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

06511 {
06512    /* Introduce messages they have */
06513    int res;
06514    res = ast_play_and_wait(chan, "vm-youhave");
06515    if (!res) {
06516       if (vms->newmessages) {
06517          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06518          if (!res) {
06519             if ((vms->newmessages == 1)) {
06520                res = ast_play_and_wait(chan, "vm-message");
06521                if (!res)
06522                   res = ast_play_and_wait(chan, "vm-INBOXs");
06523             } else {
06524                res = ast_play_and_wait(chan, "vm-messages");
06525                if (!res)
06526                   res = ast_play_and_wait(chan, "vm-INBOX");
06527             }
06528          }
06529          if (vms->oldmessages && !res)
06530             res = ast_play_and_wait(chan, "vm-and");
06531       }
06532       if (!res && vms->oldmessages) {
06533          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06534          if (!res) {
06535             if (vms->oldmessages == 1) {
06536                res = ast_play_and_wait(chan, "vm-message");
06537                if (!res)
06538                   res = ast_play_and_wait(chan, "vm-Olds");
06539             } else {
06540                res = ast_play_and_wait(chan, "vm-messages");
06541                if (!res)
06542                   res = ast_play_and_wait(chan, "vm-Old");
06543             }
06544          }
06545       }
06546       if (!res) {
06547          if (!vms->oldmessages && !vms->newmessages) {
06548             res = ast_play_and_wait(chan, "vm-no");
06549             if (!res)
06550                res = ast_play_and_wait(chan, "vm-messages");
06551          }
06552       }
06553    }
06554    return res;
06555 }

static int vm_intro_pt_BR ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6368 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

06368                                                                          {
06369    /* Introduce messages they have */
06370    int res;
06371    if (!vms->oldmessages && !vms->newmessages) {
06372       res = ast_play_and_wait(chan, "vm-nomessages");
06373       return res;
06374    }
06375    else {
06376       res = ast_play_and_wait(chan, "vm-youhave");
06377    }
06378    if (vms->newmessages) {
06379       if (!res)
06380          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06381       if ((vms->newmessages == 1)) {
06382          if (!res)
06383             res = ast_play_and_wait(chan, "vm-message");
06384          if (!res)
06385             res = ast_play_and_wait(chan, "vm-INBOXs");
06386       }
06387       else {
06388          if (!res)
06389             res = ast_play_and_wait(chan, "vm-messages");
06390          if (!res)
06391             res = ast_play_and_wait(chan, "vm-INBOX");
06392       }
06393       if (vms->oldmessages && !res)
06394          res = ast_play_and_wait(chan, "vm-and");
06395    }
06396    if (vms->oldmessages) {
06397       if (!res)
06398          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06399       if (vms->oldmessages == 1) {
06400          if (!res)
06401             res = ast_play_and_wait(chan, "vm-message");
06402          if (!res)
06403             res = ast_play_and_wait(chan, "vm-Olds");
06404       }
06405       else {
06406          if (!res)
06407       res = ast_play_and_wait(chan, "vm-messages");
06408          if (!res)
06409             res = ast_play_and_wait(chan, "vm-Old");
06410       }
06411    }
06412    return res;
06413 }

static int vm_intro_se ( struct ast_channel chan,
struct vm_state vms 
) [static]

Definition at line 6178 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

06179 {
06180    /* Introduce messages they have */
06181    int res;
06182 
06183    res = ast_play_and_wait(chan, "vm-youhave");
06184    if (res)
06185       return res;
06186 
06187    if (!vms->oldmessages && !vms->newmessages) {
06188       res = ast_play_and_wait(chan, "vm-no");
06189       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06190       return res;
06191    }
06192 
06193    if (vms->newmessages) {
06194       if ((vms->newmessages == 1)) {
06195          res = ast_play_and_wait(chan, "digits/ett");
06196          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
06197          res = res ? res : ast_play_and_wait(chan, "vm-message");
06198       } else {
06199          res = say_and_wait(chan, vms->newmessages, chan->language);
06200          res = res ? res : ast_play_and_wait(chan, "vm-nya");
06201          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06202       }
06203       if (!res && vms->oldmessages)
06204          res = ast_play_and_wait(chan, "vm-and");
06205    }
06206    if (!res && vms->oldmessages) {
06207       if (vms->oldmessages == 1) {
06208          res = ast_play_and_wait(chan, "digits/ett");
06209          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
06210          res = res ? res : ast_play_and_wait(chan, "vm-message");
06211       } else {
06212          res = say_and_wait(chan, vms->oldmessages, chan->language);
06213          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
06214          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06215       }
06216    }
06217 
06218    return res;
06219 }

static int vm_lock_path ( const char *  path  )  [static]

Definition at line 2192 of file app_voicemail.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

Referenced by close_mailbox(), copy_message(), count_messages(), last_message_index(), leave_voicemail(), resequence_mailbox(), and save_to_folder().

02193 {
02194    switch (ast_lock_path(path)) {
02195    case AST_LOCK_TIMEOUT:
02196       return -1;
02197    default:
02198       return 0;
02199    }
02200 }

static FILE* vm_mkftemp ( char *  template  )  [static]

Definition at line 923 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

00924 {
00925    FILE *p = NULL;
00926    int pfd = mkstemp(template);
00927    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
00928    if (pfd > -1) {
00929       p = fdopen(pfd, "w+");
00930       if (!p) {
00931          close(pfd);
00932          pfd = -1;
00933       }
00934    }
00935    return p;
00936 }

static int vm_newuser ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
) [static]

Definition at line 6731 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, LOG_DEBUG, LOG_NOTICE, option_debug, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, and VM_FORCENAME.

Referenced by vm_execmain().

06732 {
06733    int cmd = 0;
06734    int duration = 0;
06735    int tries = 0;
06736    char newpassword[80] = "";
06737    char newpassword2[80] = "";
06738    char prefile[PATH_MAX] = "";
06739    unsigned char buf[256];
06740    int bytes=0;
06741 
06742    if (ast_adsi_available(chan)) {
06743       bytes += adsi_logo(buf + bytes);
06744       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
06745       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06746       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06747       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06748       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06749    }
06750 
06751    /* First, have the user change their password 
06752       so they won't get here again */
06753    for (;;) {
06754       newpassword[1] = '\0';
06755       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06756       if (cmd == '#')
06757          newpassword[0] = '\0';
06758       if (cmd < 0 || cmd == 't' || cmd == '#')
06759          return cmd;
06760       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
06761       if (cmd < 0 || cmd == 't' || cmd == '#')
06762          return cmd;
06763       newpassword2[1] = '\0';
06764       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06765       if (cmd == '#')
06766          newpassword2[0] = '\0';
06767       if (cmd < 0 || cmd == 't' || cmd == '#')
06768          return cmd;
06769       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
06770       if (cmd < 0 || cmd == 't' || cmd == '#')
06771          return cmd;
06772       if (!strcmp(newpassword, newpassword2))
06773          break;
06774       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06775       cmd = ast_play_and_wait(chan, "vm-mismatch");
06776       if (++tries == 3)
06777          return -1;
06778    }
06779    if (ast_strlen_zero(ext_pass_cmd)) 
06780       vm_change_password(vmu,newpassword);
06781    else 
06782       vm_change_password_shell(vmu,newpassword);
06783    if (option_debug > 2)
06784       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06785    cmd = ast_play_and_wait(chan,"vm-passchanged");
06786 
06787    /* If forcename is set, have the user record their name */  
06788    if (ast_test_flag(vmu, VM_FORCENAME)) {
06789       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06790       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06791          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06792          if (cmd < 0 || cmd == 't' || cmd == '#')
06793             return cmd;
06794       }
06795    }
06796 
06797    /* If forcegreetings is set, have the user record their greetings */
06798    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06799       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06800       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06801          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06802          if (cmd < 0 || cmd == 't' || cmd == '#')
06803             return cmd;
06804       }
06805 
06806       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06807       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06808          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06809          if (cmd < 0 || cmd == 't' || cmd == '#')
06810             return cmd;
06811       }
06812    }
06813 
06814    return cmd;
06815 }

static int vm_options ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
) [static]

Definition at line 6817 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_waitfordigit(), ast_vm_user::context, DISPOSE, LOG_DEBUG, LOG_NOTICE, option_debug, ast_vm_user::password, play_record_review(), RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), and vm_tempgreeting().

Referenced by vm_execmain().

06818 {
06819    int cmd = 0;
06820    int retries = 0;
06821    int duration = 0;
06822    char newpassword[80] = "";
06823    char newpassword2[80] = "";
06824    char prefile[PATH_MAX] = "";
06825    unsigned char buf[256];
06826    int bytes=0;
06827 
06828    if (ast_adsi_available(chan))
06829    {
06830       bytes += adsi_logo(buf + bytes);
06831       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06832       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06833       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06834       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06835       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06836    }
06837    while ((cmd >= 0) && (cmd != 't')) {
06838       if (cmd)
06839          retries = 0;
06840       switch (cmd) {
06841       case '1':
06842          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06843          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06844          break;
06845       case '2': 
06846          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06847          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06848          break;
06849       case '3': 
06850          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06851          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06852          break;
06853       case '4': 
06854          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06855          break;
06856       case '5':
06857          if (vmu->password[0] == '-') {
06858             cmd = ast_play_and_wait(chan, "vm-no");
06859             break;
06860          }
06861          newpassword[1] = '\0';
06862          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06863          if (cmd == '#')
06864             newpassword[0] = '\0';
06865          else {
06866             if (cmd < 0)
06867                break;
06868             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06869                break;
06870             }
06871          }
06872          newpassword2[1] = '\0';
06873          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06874          if (cmd == '#')
06875             newpassword2[0] = '\0';
06876          else {
06877             if (cmd < 0)
06878                break;
06879 
06880             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) {
06881                break;
06882             }
06883          }
06884          if (strcmp(newpassword, newpassword2)) {
06885             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06886             cmd = ast_play_and_wait(chan, "vm-mismatch");
06887             break;
06888          }
06889          if (ast_strlen_zero(ext_pass_cmd)) 
06890             vm_change_password(vmu,newpassword);
06891          else 
06892             vm_change_password_shell(vmu,newpassword);
06893          if (option_debug > 2)
06894             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06895          cmd = ast_play_and_wait(chan,"vm-passchanged");
06896          break;
06897       case '*': 
06898          cmd = 't';
06899          break;
06900       default: 
06901          cmd = 0;
06902          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06903          RETRIEVE(prefile, -1, vmu);
06904          if (ast_fileexists(prefile, NULL, NULL))
06905             cmd = ast_play_and_wait(chan, "vm-tmpexists");
06906          DISPOSE(prefile, -1);
06907          if (!cmd)
06908             cmd = ast_play_and_wait(chan, "vm-options");
06909          if (!cmd)
06910             cmd = ast_waitfordigit(chan,6000);
06911          if (!cmd)
06912             retries++;
06913          if (retries > 3)
06914             cmd = 't';
06915       }
06916    }
06917    if (cmd == 't')
06918       cmd = 0;
06919    return cmd;
06920 }

static int vm_play_folder_name ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 5793 of file app_voicemail.c.

References ast_play_and_wait(), ast_channel::language, vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().

Referenced by get_folder(), vm_execmain(), and vm_instructions().

05794 {
05795    int cmd;
05796 
05797    if (!strncasecmp(chan->language, "it", 2) || !strncasecmp(chan->language, "es", 2) || !strncasecmp(chan->language, "fr", 2) || !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, French or Portuguese syntax */
05798       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05799       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05800    } else if (!strncasecmp(chan->language, "gr", 2)){
05801       return vm_play_folder_name_gr(chan, mbox);
05802    } else if (!strncasecmp(chan->language, "pl", 2)){
05803       return vm_play_folder_name_pl(chan, mbox);
05804    } else if (!strncasecmp(chan->language, "ua", 2)){  /* Ukrainian syntax */
05805       return vm_play_folder_name_ua(chan, mbox);
05806    } else if (!strcasecmp(chan->language, "he")){  /* Hebrew syntax */
05807       cmd = ast_play_and_wait(chan, mbox);
05808       return cmd;
05809    } else {  /* Default English */
05810       cmd = ast_play_and_wait(chan, mbox);
05811       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05812    }
05813 }

static int vm_play_folder_name_gr ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 5746 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05747 {
05748    int cmd;
05749    char *buf;
05750 
05751    buf = alloca(strlen(mbox)+2); 
05752    strcpy(buf, mbox);
05753    strcat(buf,"s");
05754 
05755    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
05756       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
05757       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05758    } else {
05759       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05760       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
05761    }
05762 }

static int vm_play_folder_name_pl ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 5764 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05765 {
05766    int cmd;
05767 
05768    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05769       if (!strcasecmp(mbox, "vm-INBOX"))
05770          cmd = ast_play_and_wait(chan, "vm-new-e");
05771       else
05772          cmd = ast_play_and_wait(chan, "vm-old-e");
05773       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05774    } else {
05775       cmd = ast_play_and_wait(chan, "vm-messages");
05776       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05777    }
05778 }

static int vm_play_folder_name_ua ( struct ast_channel chan,
char *  mbox 
) [static]

Definition at line 5780 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05781 {
05782    int cmd;
05783 
05784    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05785       cmd = ast_play_and_wait(chan, "vm-messages");
05786       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05787    } else {
05788       cmd = ast_play_and_wait(chan, mbox);
05789       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05790    }
05791 }

static int vm_tempgreeting ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
) [static]

Definition at line 6922 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_log(), ast_play_and_wait(), ast_waitfordigit(), ast_vm_user::context, create_dirpath(), DELETE, DISPOSE, play_record_review(), RETRIEVE, and vm_state::username.

Referenced by vm_options().

06923 {
06924    int res;
06925    int cmd = 0;
06926    int retries = 0;
06927    int duration = 0;
06928    char prefile[PATH_MAX] = "";
06929    unsigned char buf[256];
06930    char dest[PATH_MAX];
06931    int bytes = 0;
06932 
06933    if (ast_adsi_available(chan)) {
06934       bytes += adsi_logo(buf + bytes);
06935       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
06936       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06937       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06938       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06939       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06940    }
06941 
06942    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06943    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
06944       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
06945       return -1;
06946    }
06947    while ((cmd >= 0) && (cmd != 't')) {
06948       if (cmd)
06949          retries = 0;
06950       RETRIEVE(prefile, -1, vmu);
06951       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
06952          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06953          cmd = 't';  
06954       } else {
06955          switch (cmd) {
06956          case '1':
06957             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06958             break;
06959          case '2':
06960             DELETE(prefile, -1, prefile, vmu);
06961             ast_play_and_wait(chan, "vm-tempremoved");
06962             cmd = 't';  
06963             break;
06964          case '*': 
06965             cmd = 't';
06966             break;
06967          default:
06968             cmd = ast_play_and_wait(chan,
06969                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
06970                   "vm-tempgreeting2" : "vm-tempgreeting");
06971             if (!cmd)
06972                cmd = ast_waitfordigit(chan,6000);
06973             if (!cmd)
06974                retries++;
06975             if (retries > 3)
06976                cmd = 't';
06977          }
06978       }
06979       DISPOSE(prefile, -1);
06980    }
06981    if (cmd == 't')
06982       cmd = 0;
06983    return cmd;
06984 }

static int vmauthenticate ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 7942 of file app_voicemail.c.

References ast_copy_string(), AST_MAX_EXTENSION, ast_module_user_add, ast_module_user_remove, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, pbx_builtin_setvar_helper(), s, and vm_authenticate().

Referenced by load_module().

07943 {
07944    struct ast_module_user *u;
07945    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
07946    struct ast_vm_user vmus;
07947    char *options = NULL;
07948    int silent = 0, skipuser = 0;
07949    int res = -1;
07950 
07951    u = ast_module_user_add(chan);
07952    
07953    if (s) {
07954       s = ast_strdupa(s);
07955       user = strsep(&s, "|");
07956       options = strsep(&s, "|");
07957       if (user) {
07958          s = user;
07959          user = strsep(&s, "@");
07960          context = strsep(&s, "");
07961          if (!ast_strlen_zero(user))
07962             skipuser++;
07963          ast_copy_string(mailbox, user, sizeof(mailbox));
07964       }
07965    }
07966 
07967    if (options) {
07968       silent = (strchr(options, 's')) != NULL;
07969    }
07970 
07971    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
07972       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
07973       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
07974       ast_play_and_wait(chan, "auth-thankyou");
07975       res = 0;
07976    }
07977 
07978    ast_module_user_remove(u);
07979    return res;
07980 }

static struct tm* vmu_tm ( const struct ast_vm_user vmu,
struct tm *  tm 
) [static]

Definition at line 3034 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_vm_user::list, vm_zone::name, vm_zone::timezone, and ast_vm_user::zonetag.

Referenced by make_email_file(), and sendpage().

03035 {
03036    const struct vm_zone *z = NULL;
03037    time_t t = time(NULL);
03038 
03039    /* Does this user have a timezone specified? */
03040    if (!ast_strlen_zero(vmu->zonetag)) {
03041       /* Find the zone in the list */
03042       AST_LIST_LOCK(&zones);
03043       AST_LIST_TRAVERSE(&zones, z, list) {
03044          if (!strcmp(z->name, vmu->zonetag))
03045             break;
03046       }
03047       AST_LIST_UNLOCK(&zones);
03048    }
03049    ast_localtime(&t, tm, z ? z->timezone : NULL);
03050    return tm;
03051 }

static int wait_file ( struct ast_channel chan,
struct vm_state vms,
char *  file 
) [static]

Definition at line 5294 of file app_voicemail.c.

References ast_control_streamfile().

05295 {
05296    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05297 }

static int wait_file2 ( struct ast_channel chan,
struct vm_state vms,
char *  file 
) [static]

Definition at line 5286 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_stream_and_wait(), and ast_channel::language.

Referenced by play_message(), play_message_callerid(), and play_message_duration().

05287 {
05288    int res;
05289    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05290       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05291    return res;
05292 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 9216 of file app_voicemail.c.

char* addesc = "Comedian Mail" [static]

Definition at line 459 of file app_voicemail.c.

unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static]

Definition at line 581 of file app_voicemail.c.

unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static]

Definition at line 582 of file app_voicemail.c.

int adsiver = 1 [static]

Definition at line 583 of file app_voicemail.c.

char* app = "VoiceMail" [static]

Definition at line 535 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 538 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 540 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 541 of file app_voicemail.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 9216 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 566 of file app_voicemail.c.

char charset[32] = "ISO-8859-1" [static]

Definition at line 579 of file app_voicemail.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 569 of file app_voicemail.c.

struct ast_cli_entry cli_show_voicemail_users_deprecated [static]

Initial value:

 {
   { "show", "voicemail", "users", NULL },
   handle_voicemail_show_users, NULL,
   NULL, complete_voicemail_show_users }

Definition at line 8084 of file app_voicemail.c.

struct ast_cli_entry cli_show_voicemail_zones_deprecated [static]

Initial value:

 {
   { "show", "voicemail", "zones", NULL },
   handle_voicemail_show_zones, NULL,
   NULL, NULL }

Definition at line 8089 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 8094 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 464 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 510 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 492 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 524 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 565 of file app_voicemail.c.

Referenced by directory_exec().

char* emailbody = NULL [static]

Definition at line 572 of file app_voicemail.c.

char emaildateformat[32] = "%A, %B %d, %Y at %r" [static]

Definition at line 584 of file app_voicemail.c.

char* emailsubject = NULL [static]

Definition at line 573 of file app_voicemail.c.

char emailtitle[100] [static]

Definition at line 578 of file app_voicemail.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 567 of file app_voicemail.c.

Referenced by conf_run().

char ext_pass_cmd[128] [static]

Definition at line 445 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 551 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 576 of file app_voicemail.c.

struct ast_flags globalflags = {0} [static]

Definition at line 561 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 550 of file app_voicemail.c.

int maxgreet [static]

Definition at line 557 of file app_voicemail.c.

int maxlogins [static]

Definition at line 559 of file app_voicemail.c.

int maxmsg [static]

Definition at line 547 of file app_voicemail.c.

int maxsilence [static]

Definition at line 546 of file app_voicemail.c.

Referenced by ast_record_review().

int my_umask

Definition at line 447 of file app_voicemail.c.

char* pagerbody = NULL [static]

Definition at line 574 of file app_voicemail.c.

char pagerfromstring[100] [static]

Definition at line 577 of file app_voicemail.c.

char* pagersubject = NULL [static]

Definition at line 575 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 563 of file app_voicemail.c.

char serveremail[80] [static]

Definition at line 549 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 548 of file app_voicemail.c.

int skipms [static]

Definition at line 558 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 552 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char* synopsis_vm [static]

Initial value:

"Leave a Voicemail message"

Definition at line 461 of file app_voicemail.c.

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 507 of file app_voicemail.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 489 of file app_voicemail.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 521 of file app_voicemail.c.

char userscontext[AST_MAX_EXTENSION] = "default" [static]

Definition at line 457 of file app_voicemail.c.

Referenced by pbx_load_users().

struct ast_app_option vm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'j' ] = { .flag = OPT_PRIORITY_JUMP }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 },} [static]

Definition at line 236 of file app_voicemail.c.

Referenced by vm_exec(), and vm_execmain().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 443 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 553 of file app_voicemail.c.

int vmmaxmessage [static]

Definition at line 556 of file app_voicemail.c.

int vmminmessage [static]

Definition at line 555 of file app_voicemail.c.

char voicemail_show_users_help[] [static]

Initial value:

"Usage: voicemail show users [for <context>]\n"
"       Lists all mailboxes currently set up\n"

Definition at line 7982 of file app_voicemail.c.

char voicemail_show_zones_help[] [static]

Initial value:

"Usage: voicemail show zones\n"
"       Lists zone message formats\n"

Definition at line 7986 of file app_voicemail.c.

double volgain [static]

Definition at line 554 of file app_voicemail.c.

char zonetag[80] [static]

Definition at line 545 of file app_voicemail.c.

Referenced by build_peer().


Generated on Tue Apr 28 22:50:19 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7