Wed Aug 15 01:24:41 2007

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"

Include dependency graph for app_voicemail.c:

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
struct  vm_state
struct  vm_zone

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_file(g,h));
#define DELETE(a, b, c)   (vm_delete(c))
#define DISPOSE(a, b)
#define ENDL   "\n"
#define eol   "\r\n"
#define ERROR_LOCK_PATH   -100
#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)
#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 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)
 AST_APP_OPTIONS (vm_app_options,{AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION('j', OPT_PRIORITY_JUMP), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),})
static AST_LIST_HEAD_STATIC (zones, vm_zone)
static AST_LIST_HEAD_STATIC (users, ast_vm_user)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,)
static int base_encode (char *filename, FILE *so)
static int change_password_realtime (struct ast_vm_user *vmu, const char *password)
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 void copy_file (char *frompath, char *topath)
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 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 struct
ast_vm_user
find_or_create (char *context, char *mbox)
static struct
ast_vm_user
find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static struct
ast_vm_user
find_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_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 get_lastdigits (int num)
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, char *context, 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, int len, char *dir, int num)
static const 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_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 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_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_pt (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_it (struct ast_channel *chan, struct vm_state *vms)
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_ru (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_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 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 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_interface
smdi_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"
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


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 156 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 168 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 169 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 169 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 153 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 149 of file app_voicemail.c.

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

Definition at line 406 of file app_voicemail.c.

Referenced by copy_message(), and save_to_folder().

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

Definition at line 407 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 402 of file app_voicemail.c.

Referenced by advanced_options(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), play_record_review(), and vm_tempgreeting().

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 170 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 191 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 EXISTS ( a,
b,
c,
 )     (ast_fileexists(c,NULL,d) > 0)

Definition at line 404 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 162 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 172 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 173 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 164 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 165 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 405 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
 ) 

Definition at line 401 of file app_voicemail.c.

Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), and vm_tempgreeting().

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

Definition at line 160 of file app_voicemail.c.

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 147 of file app_voicemail.c.

Referenced by run_externnotify().

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

Definition at line 403 of file app_voicemail.c.

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

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 422 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 188 of file app_voicemail.c.

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

#define VM_ATTACH   (1 << 11)

Definition at line 186 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 187 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 185 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 179 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 183 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 182 of file app_voicemail.c.

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

#define VM_OPERATOR   (1 << 1)

Definition at line 176 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 184 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 175 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 177 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 180 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

Definition at line 189 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 181 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Definition at line 178 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 190 of file app_voicemail.c.

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 155 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 151 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

Definition at line 152 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 194 of file app_voicemail.c.

00194      {
00195    OPT_SILENT =           (1 << 0),
00196    OPT_BUSY_GREETING =    (1 << 1),
00197    OPT_UNAVAIL_GREETING = (1 << 2),
00198    OPT_RECORDGAIN =       (1 << 3),
00199    OPT_PREPEND_MAILBOX =  (1 << 4),
00200    OPT_PRIORITY_JUMP =    (1 << 5),
00201    OPT_AUTOPLAY =         (1 << 6),
00202 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 204 of file app_voicemail.c.

00204      {
00205    OPT_ARG_RECORDGAIN = 0,
00206    OPT_ARG_PLAYFOLDER = 1,
00207    /* This *must* be the last value in this enum! */
00208    OPT_ARG_ARRAY_SIZE = 2,
00209 } vm_option_args;


Function Documentation

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

Definition at line 2559 of file app_voicemail.c.

References ast_strlen_zero(), and VM_SPOOL_DIR.

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

02560 {
02561    DIR *dir;
02562    struct dirent *de;
02563    char fn[256];
02564    int ret = 0;
02565    if (!folder)
02566       folder = "INBOX";
02567    /* If no mailbox, return immediately */
02568    if (ast_strlen_zero(mailbox))
02569       return 0;
02570    if (!context)
02571       context = "default";
02572    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
02573    dir = opendir(fn);
02574    if (!dir)
02575       return 0;
02576    while ((de = readdir(dir))) {
02577       if (!strncasecmp(de->d_name, "msg", 3)) {
02578          if (shortcircuit) {
02579             ret = 1;
02580             break;
02581          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
02582             ret++;
02583       }
02584    }
02585    closedir(dir);
02586    return ret;
02587 }

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

Definition at line 3313 of file app_voicemail.c.

References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), ast_log(), and LOG_WARNING.

Referenced by vm_authenticate(), and vm_execmain().

03314 {
03315    int x;
03316    if (!ast_adsi_available(chan))
03317       return;
03318    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
03319    if (x < 0)
03320       return;
03321    if (!x) {
03322       if (adsi_load_vmail(chan, useadsi)) {
03323          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
03324          return;
03325       }
03326    } else
03327       *useadsi = 1;
03328 }

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

Definition at line 3500 of file app_voicemail.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_set_keys(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curmsg, vm_state::deleted, keys, and vm_state::lastmsg.

Referenced by vm_execmain().

03501 {
03502    int bytes=0;
03503    unsigned char buf[256];
03504    unsigned char keys[8];
03505 
03506    int x;
03507 
03508    if (!ast_adsi_available(chan))
03509       return;
03510 
03511    /* New meaning for keys */
03512    for (x=0;x<5;x++)
03513       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03514 
03515    keys[6] = 0x0;
03516    keys[7] = 0x0;
03517 
03518    if (!vms->curmsg) {
03519       /* No prev key, provide "Folder" instead */
03520       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03521    }
03522    if (vms->curmsg >= vms->lastmsg) {
03523       /* If last message ... */
03524       if (vms->curmsg) {
03525          /* but not only message, provide "Folder" instead */
03526          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03527       } else {
03528          /* Otherwise if only message, leave blank */
03529          keys[3] = 1;
03530       }
03531    }
03532 
03533    /* If deleted, show "undeleted" */
03534    if (vms->deleted[vms->curmsg]) 
03535       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03536 
03537    /* Except "Exit" */
03538    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03539    bytes += ast_adsi_set_keys(buf + bytes, keys);
03540    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03541 
03542    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03543 }

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

Definition at line 3378 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().

03379 {
03380    unsigned char buf[256];
03381    int bytes=0;
03382    unsigned char keys[8];
03383    int x,y;
03384 
03385    if (!ast_adsi_available(chan))
03386       return;
03387 
03388    for (x=0;x<5;x++) {
03389       y = ADSI_KEY_APPS + 12 + start + x;
03390       if (y > ADSI_KEY_APPS + 12 + 4)
03391          y = 0;
03392       keys[x] = ADSI_KEY_SKT | y;
03393    }
03394    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
03395    keys[6] = 0;
03396    keys[7] = 0;
03397 
03398    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
03399    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
03400    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03401    bytes += ast_adsi_set_keys(buf + bytes, keys);
03402    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03403 
03404    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03405 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 3648 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().

03649 {
03650    unsigned char buf[256];
03651    int bytes=0;
03652 
03653    if (!ast_adsi_available(chan))
03654       return;
03655    bytes += adsi_logo(buf + bytes);
03656    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
03657    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
03658    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03659    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03660 
03661    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03662 }

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

Definition at line 3182 of file app_voicemail.c.

References addesc, ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsifdn, adsisec, adsiver, 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().

03183 {
03184    unsigned char buf[256];
03185    int bytes=0;
03186    int x;
03187    char num[5];
03188 
03189    *useadsi = 0;
03190    bytes += ast_adsi_data_mode(buf + bytes);
03191    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03192 
03193    bytes = 0;
03194    bytes += adsi_logo(buf);
03195    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
03196 #ifdef DISPLAY
03197    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
03198 #endif
03199    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03200    bytes += ast_adsi_data_mode(buf + bytes);
03201    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03202 
03203    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
03204       bytes = 0;
03205       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
03206       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
03207       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03208       bytes += ast_adsi_voice_mode(buf + bytes, 0);
03209       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03210       return 0;
03211    }
03212 
03213 #ifdef DISPLAY
03214    /* Add a dot */
03215    bytes = 0;
03216    bytes += ast_adsi_logo(buf);
03217    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
03218    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
03219    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03220    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03221 #endif
03222    bytes = 0;
03223    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
03224    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
03225    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
03226    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
03227    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
03228    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
03229    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03230 
03231 #ifdef DISPLAY
03232    /* Add another dot */
03233    bytes = 0;
03234    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
03235    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03236 
03237    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03238    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03239 #endif
03240 
03241    bytes = 0;
03242    /* These buttons we load but don't use yet */
03243    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
03244    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
03245    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
03246    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
03247    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
03248    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
03249    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03250 
03251 #ifdef DISPLAY
03252    /* Add another dot */
03253    bytes = 0;
03254    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
03255    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03256    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03257 #endif
03258 
03259    bytes = 0;
03260    for (x=0;x<5;x++) {
03261       snprintf(num, sizeof(num), "%d", x);
03262       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
03263    }
03264    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
03265    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03266 
03267 #ifdef DISPLAY
03268    /* Add another dot */
03269    bytes = 0;
03270    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
03271    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03272    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03273 #endif
03274 
03275    if (ast_adsi_end_download(chan)) {
03276       bytes = 0;
03277       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
03278       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
03279       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03280       bytes += ast_adsi_voice_mode(buf + bytes, 0);
03281       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03282       return 0;
03283    }
03284    bytes = 0;
03285    bytes += ast_adsi_download_disconnect(buf + bytes);
03286    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03287    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03288 
03289    if (option_debug)
03290       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
03291 
03292 #ifdef DISPLAY
03293    /* Add last dot */
03294    bytes = 0;
03295    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
03296    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03297 #endif
03298    if (option_debug)
03299       ast_log(LOG_DEBUG, "Restarting session...\n");
03300 
03301    bytes = 0;
03302    /* Load the session now */
03303    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
03304       *useadsi = 1;
03305       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
03306    } else
03307       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
03308 
03309    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03310    return 0;
03311 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 3330 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().

03331 {
03332    unsigned char buf[256];
03333    int bytes=0;
03334    unsigned char keys[8];
03335    int x;
03336    if (!ast_adsi_available(chan))
03337       return;
03338 
03339    for (x=0;x<8;x++)
03340       keys[x] = 0;
03341    /* Set one key for next */
03342    keys[3] = ADSI_KEY_APPS + 3;
03343 
03344    bytes += adsi_logo(buf + bytes);
03345    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
03346    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
03347    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03348    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
03349    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
03350    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
03351    bytes += ast_adsi_set_keys(buf + bytes, keys);
03352    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03353    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03354 }

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

Definition at line 3174 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().

03175 {
03176    int bytes = 0;
03177    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
03178    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
03179    return bytes;
03180 }

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

Definition at line 3407 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(), ast_callerid_parse(), ast_strlen_zero(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, keys, vm_state::lastmsg, name, and strsep().

Referenced by play_message(), and vm_execmain().

03408 {
03409    int bytes=0;
03410    unsigned char buf[256]; 
03411    char buf1[256], buf2[256];
03412    char fn2[PATH_MAX];
03413 
03414    char cid[256]="";
03415    char *val;
03416    char *name, *num;
03417    char datetime[21]="";
03418    FILE *f;
03419 
03420    unsigned char keys[8];
03421 
03422    int x;
03423 
03424    if (!ast_adsi_available(chan))
03425       return;
03426 
03427    /* Retrieve important info */
03428    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
03429    f = fopen(fn2, "r");
03430    if (f) {
03431       while (!feof(f)) {   
03432          fgets((char *)buf, sizeof(buf), f);
03433          if (!feof(f)) {
03434             char *stringp=NULL;
03435             stringp = (char *)buf;
03436             strsep(&stringp, "=");
03437             val = strsep(&stringp, "=");
03438             if (!ast_strlen_zero(val)) {
03439                if (!strcmp((char *)buf, "callerid"))
03440                   ast_copy_string(cid, val, sizeof(cid));
03441                if (!strcmp((char *)buf, "origdate"))
03442                   ast_copy_string(datetime, val, sizeof(datetime));
03443             }
03444          }
03445       }
03446       fclose(f);
03447    }
03448    /* New meaning for keys */
03449    for (x=0;x<5;x++)
03450       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03451    keys[6] = 0x0;
03452    keys[7] = 0x0;
03453 
03454    if (!vms->curmsg) {
03455       /* No prev key, provide "Folder" instead */
03456       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03457    }
03458    if (vms->curmsg >= vms->lastmsg) {
03459       /* If last message ... */
03460       if (vms->curmsg) {
03461          /* but not only message, provide "Folder" instead */
03462          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03463          bytes += ast_adsi_voice_mode(buf + bytes, 0);
03464 
03465       } else {
03466          /* Otherwise if only message, leave blank */
03467          keys[3] = 1;
03468       }
03469    }
03470 
03471    if (!ast_strlen_zero(cid)) {
03472       ast_callerid_parse(cid, &name, &num);
03473       if (!name)
03474          name = num;
03475    } else
03476       name = "Unknown Caller";
03477 
03478    /* If deleted, show "undeleted" */
03479 
03480    if (vms->deleted[vms->curmsg])
03481       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03482 
03483    /* Except "Exit" */
03484    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03485    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
03486       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
03487    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
03488 
03489    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03490    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03491    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
03492    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
03493    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03494    bytes += ast_adsi_set_keys(buf + bytes, keys);
03495    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03496 
03497    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03498 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 3356 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().

03357 {
03358    unsigned char buf[256];
03359    int bytes=0;
03360    unsigned char keys[8];
03361    int x;
03362    if (!ast_adsi_available(chan))
03363       return;
03364 
03365    for (x=0;x<8;x++)
03366       keys[x] = 0;
03367    /* Set one key for next */
03368    keys[3] = ADSI_KEY_APPS + 3;
03369 
03370    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03371    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
03372    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
03373    bytes += ast_adsi_set_keys(buf + bytes, keys);
03374    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03375    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03376 }

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

Definition at line 3545 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().

03546 {
03547    unsigned char buf[256] = "";
03548    char buf1[256] = "", buf2[256] = "";
03549    int bytes=0;
03550    unsigned char keys[8];
03551    int x;
03552 
03553    char *newm = (vms->newmessages == 1) ? "message" : "messages";
03554    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
03555    if (!ast_adsi_available(chan))
03556       return;
03557    if (vms->newmessages) {
03558       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
03559       if (vms->oldmessages) {
03560          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
03561          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
03562       } else {
03563          snprintf(buf2, sizeof(buf2), "%s.", newm);
03564       }
03565    } else if (vms->oldmessages) {
03566       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
03567       snprintf(buf2, sizeof(buf2), "%s.", oldm);
03568    } else {
03569       strcpy(buf1, "You have no messages.");
03570       buf2[0] = ' ';
03571       buf2[1] = '\0';
03572    }
03573    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03574    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03575    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03576 
03577    for (x=0;x<6;x++)
03578       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03579    keys[6] = 0;
03580    keys[7] = 0;
03581 
03582    /* Don't let them listen if there are none */
03583    if (vms->lastmsg < 0)
03584       keys[0] = 1;
03585    bytes += ast_adsi_set_keys(buf + bytes, keys);
03586 
03587    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03588 
03589    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03590 }

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

Definition at line 3592 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().

03593 {
03594    unsigned char buf[256] = "";
03595    char buf1[256] = "", buf2[256] = "";
03596    int bytes=0;
03597    unsigned char keys[8];
03598    int x;
03599 
03600    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
03601 
03602    if (!ast_adsi_available(chan))
03603       return;
03604 
03605    /* Original command keys */
03606    for (x=0;x<6;x++)
03607       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03608 
03609    keys[6] = 0;
03610    keys[7] = 0;
03611 
03612    if ((vms->lastmsg + 1) < 1)
03613       keys[0] = 0;
03614 
03615    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
03616       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
03617 
03618    if (vms->lastmsg + 1)
03619       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
03620    else
03621       strcpy(buf2, "no messages.");
03622    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03623    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03624    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
03625    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03626    bytes += ast_adsi_set_keys(buf + bytes, keys);
03627 
03628    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03629 
03630    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03631    
03632 }

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 7745 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, DISPOSE, find_user(), vm_state::fn, vm_state::fn2, vm_state::heard, leave_voicemail(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, make_file(), name, option_debug, option_verbose, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

07746 {
07747    int res = 0;
07748 #ifdef IMAP_STORAGE
07749    char origtimeS[256],cidS[256],contextS[256];
07750    char *header_content,*temp;
07751 #endif
07752    char filename[PATH_MAX];
07753    struct ast_config *msg_cfg = NULL;
07754    const char *origtime, *context;
07755    char *cid, *name, *num;
07756    int retries = 0;
07757 
07758    vms->starting = 0; 
07759 #ifdef IMAP_STORAGE
07760    /* START HERE */
07761    /* get the message info!! */
07762    if(option_debug > 2)
07763       ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
07764    if (vms->msgArray[vms->curmsg] == 0) {
07765       ast_log (LOG_WARNING,"Trying to access unknown message\n");
07766       return -1;
07767    }
07768 
07769    /* This will only work for new messages... */
07770    header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
07771    /* empty string means no valid header */
07772    if (ast_strlen_zero(header_content)) {
07773       ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
07774       return -1;
07775    }
07776 
07777    /* Get info from headers!! */
07778    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
07779    
07780    if (temp)
07781       ast_copy_string(cidS,temp, sizeof(cidS));
07782    else
07783       cidS[0] = '\0';
07784    
07785    cid = &cidS[0];
07786    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
07787    
07788    if (temp)
07789       ast_copy_string(contextS,temp, sizeof(contextS));
07790    else
07791       contextS[0] = '\0';
07792    
07793    context = &contextS[0];
07794    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
07795    
07796    if (temp)
07797       ast_copy_string(origtimeS,temp, sizeof(origtimeS));
07798    else
07799       origtimeS[0] = '\0';
07800    
07801    origtime = &origtimeS[0];
07802    
07803    ast_copy_string(filename, "IMAP_STORAGE", sizeof(filename));
07804 #else
07805    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
07806 
07807    /* Retrieve info from VM attribute file */
07808 
07809    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
07810    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
07811    RETRIEVE(vms->curdir, vms->curmsg);
07812    msg_cfg = ast_config_load(filename);
07813    DISPOSE(vms->curdir, vms->curmsg);
07814    if (!msg_cfg) {
07815       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
07816       return 0;
07817    }
07818 
07819    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
07820       ast_config_destroy(msg_cfg);
07821       return 0;
07822    }
07823 
07824    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
07825 
07826    context = ast_variable_retrieve(msg_cfg, "message", "context");
07827    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
07828       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
07829 #endif
07830    switch (option) {
07831    case 3:
07832       if (!res)
07833          res = play_message_datetime(chan, vmu, origtime, filename);
07834       if (!res)
07835          res = play_message_callerid(chan, vms, cid, context, 0);
07836 
07837       res = 't';
07838       break;
07839 
07840    case 2:  /* Call back */
07841 
07842       if (ast_strlen_zero(cid))
07843          break;
07844 
07845       ast_callerid_parse(cid, &name, &num);
07846       while ((res > -1) && (res != 't')) {
07847          switch (res) {
07848          case '1':
07849             if (num) {
07850                /* Dial the CID number */
07851                res = dialout(chan, vmu, num, vmu->callback);
07852                if (res) {
07853                   ast_config_destroy(msg_cfg);
07854                   return 9;
07855                }
07856             } else {
07857                res = '2';
07858             }
07859             break;
07860 
07861          case '2':
07862             /* Want to enter a different number, can only do this if there's a dialout context for this user */
07863             if (!ast_strlen_zero(vmu->dialout)) {
07864                res = dialout(chan, vmu, NULL, vmu->dialout);
07865                if (res) {
07866                   ast_config_destroy(msg_cfg);
07867                   return 9;
07868                }
07869             } else {
07870                if (option_verbose > 2)
07871                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
07872                res = ast_play_and_wait(chan, "vm-sorry");
07873             }
07874             ast_config_destroy(msg_cfg);
07875             return res;
07876          case '*':
07877             res = 't';
07878             break;
07879          case '3':
07880          case '4':
07881          case '5':
07882          case '6':
07883          case '7':
07884          case '8':
07885          case '9':
07886          case '0':
07887 
07888             res = ast_play_and_wait(chan, "vm-sorry");
07889             retries++;
07890             break;
07891          default:
07892             if (num) {
07893                if (option_verbose > 2)
07894                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
07895                res = ast_play_and_wait(chan, "vm-num-i-have");
07896                if (!res)
07897                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
07898                if (!res)
07899                   res = ast_play_and_wait(chan, "vm-tocallnum");
07900                /* Only prompt for a caller-specified number if there is a dialout context specified */
07901                if (!ast_strlen_zero(vmu->dialout)) {
07902                   if (!res)
07903                      res = ast_play_and_wait(chan, "vm-calldiffnum");
07904                }
07905             } else {
07906                res = ast_play_and_wait(chan, "vm-nonumber");
07907                if (!ast_strlen_zero(vmu->dialout)) {
07908                   if (!res)
07909                      res = ast_play_and_wait(chan, "vm-toenternumber");
07910                }
07911             }
07912             if (!res)
07913                res = ast_play_and_wait(chan, "vm-star-cancel");
07914             if (!res)
07915                res = ast_waitfordigit(chan, 6000);
07916             if (!res) {
07917                retries++;
07918                if (retries > 3)
07919                   res = 't';
07920             }
07921             break; 
07922             
07923          }
07924          if (res == 't')
07925             res = 0;
07926          else if (res == '*')
07927             res = -1;
07928       }
07929       break;
07930       
07931    case 1:  /* Reply */
07932       /* Send reply directly to sender */
07933       if (ast_strlen_zero(cid))
07934          break;
07935 
07936       ast_callerid_parse(cid, &name, &num);
07937       if (!num) {
07938          if (option_verbose > 2)
07939             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
07940          if (!res)
07941             res = ast_play_and_wait(chan, "vm-nonumber");
07942          ast_config_destroy(msg_cfg);
07943          return res;
07944       } else {
07945          struct ast_vm_user vmu2;
07946          if (find_user(&vmu2, vmu->context, num)) {
07947             struct leave_vm_options leave_options;
07948             char mailbox[AST_MAX_EXTENSION * 2 + 2];
07949             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
07950 
07951             if (option_verbose > 2)
07952                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
07953             
07954             memset(&leave_options, 0, sizeof(leave_options));
07955             leave_options.record_gain = record_gain;
07956             res = leave_voicemail(chan, mailbox, &leave_options);
07957             if (!res)
07958                res = 't';
07959             ast_config_destroy(msg_cfg);
07960             return res;
07961          } else {
07962             /* Sender has no mailbox, can't reply */
07963             if (option_verbose > 2)
07964                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
07965             ast_play_and_wait(chan, "vm-nobox");
07966             res = 't';
07967             ast_config_destroy(msg_cfg);
07968             return res;
07969          }
07970       } 
07971       res = 0;
07972 
07973       break;
07974    }
07975 
07976 #ifndef IMAP_STORAGE
07977    ast_config_destroy(msg_cfg);
07978 
07979    if (!res) {
07980       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
07981       vms->heard[msg] = 1;
07982       res = wait_file(chan, vms, vms->fn);
07983    }
07984 #endif
07985    return res;
07986 }

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

Definition at line 6857 of file app_voicemail.c.

References apply_options(), ast_strdupa, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, ast_vm_user::pager, ast_vm_user::password, populate_defaults(), s, and strsep().

Referenced by load_config().

06858 {
06859    /* Assumes lock is already held */
06860    char *tmp;
06861    char *stringp;
06862    char *s;
06863    struct ast_vm_user *vmu;
06864 
06865    tmp = ast_strdupa(data);
06866 
06867    if ((vmu = find_or_create(context, mbox))) {
06868       populate_defaults(vmu);
06869 
06870       stringp = tmp;
06871       if ((s = strsep(&stringp, ","))) 
06872          ast_copy_string(vmu->password, s, sizeof(vmu->password));
06873       if (stringp && (s = strsep(&stringp, ","))) 
06874          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
06875       if (stringp && (s = strsep(&stringp, ","))) 
06876          ast_copy_string(vmu->email, s, sizeof(vmu->email));
06877       if (stringp && (s = strsep(&stringp, ","))) 
06878          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
06879       if (stringp && (s = strsep(&stringp, ","))) 
06880          apply_options(vmu, s);
06881    }
06882    return 0;
06883 }

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

Definition at line 566 of file app_voicemail.c.

References apply_options(), 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().

00567 {
00568    int x;
00569    if (!strcasecmp(var, "attach")) {
00570       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00571    } else if (!strcasecmp(var, "attachfmt")) {
00572       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00573    } else if (!strcasecmp(var, "serveremail")) {
00574       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00575    } else if (!strcasecmp(var, "language")) {
00576       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00577    } else if (!strcasecmp(var, "tz")) {
00578       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00579 #ifdef IMAP_STORAGE
00580    } else if (!strcasecmp(var, "imapuser")) {
00581       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00582    } else if (!strcasecmp(var, "imappassword")) {
00583       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00584 #endif
00585    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00586       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00587    } else if (!strcasecmp(var, "saycid")){
00588       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00589    } else if (!strcasecmp(var,"sendvoicemail")){
00590       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00591    } else if (!strcasecmp(var, "review")){
00592       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00593    } else if (!strcasecmp(var, "tempgreetwarn")){
00594       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00595    } else if (!strcasecmp(var, "operator")){
00596       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00597    } else if (!strcasecmp(var, "envelope")){
00598       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00599    } else if (!strcasecmp(var, "sayduration")){
00600       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00601    } else if (!strcasecmp(var, "saydurationm")){
00602       if (sscanf(value, "%d", &x) == 1) {
00603          vmu->saydurationm = x;
00604       } else {
00605          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00606       }
00607    } else if (!strcasecmp(var, "forcename")){
00608       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00609    } else if (!strcasecmp(var, "forcegreetings")){
00610       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00611    } else if (!strcasecmp(var, "callback")) {
00612       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00613    } else if (!strcasecmp(var, "dialout")) {
00614       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00615    } else if (!strcasecmp(var, "exitcontext")) {
00616       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00617    } else if (!strcasecmp(var, "maxmsg")) {
00618       vmu->maxmsg = atoi(value);
00619       if (vmu->maxmsg <= 0) {
00620          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00621          vmu->maxmsg = MAXMSG;
00622       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00623          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00624          vmu->maxmsg = MAXMSGLIMIT;
00625       }
00626    } else if (!strcasecmp(var, "volgain")) {
00627       sscanf(value, "%lf", &vmu->volgain);
00628    } else if (!strcasecmp(var, "options")) {
00629       apply_options(vmu, value);
00630    }
00631 }

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

Definition at line 649 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00650 {  /* Destructively Parse options and apply */
00651    char *stringp;
00652    char *s;
00653    char *var, *value;
00654    stringp = ast_strdupa(options);
00655    while ((s = strsep(&stringp, "|"))) {
00656       value = s;
00657       if ((var = strsep(&value, "=")) && value) {
00658          apply_option(vmu, var, value);
00659       }
00660    }  
00661 }

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

Definition at line 663 of file app_voicemail.c.

References apply_option(), 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, and ast_variable::value.

Referenced by find_user_realtime(), and load_config().

00664 {
00665    struct ast_variable *tmp;
00666    tmp = var;
00667    while (tmp) {
00668       if (!strcasecmp(tmp->name, "vmsecret")) {
00669          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00670       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00671          if (ast_strlen_zero(retval->password))
00672             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00673       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00674          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00675       } else if (!strcasecmp(tmp->name, "pager")) {
00676          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00677       } else if (!strcasecmp(tmp->name, "email")) {
00678          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00679       } else if (!strcasecmp(tmp->name, "fullname")) {
00680          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00681       } else if (!strcasecmp(tmp->name, "context")) {
00682          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00683 #ifdef IMAP_STORAGE
00684       } else if (!strcasecmp(tmp->name, "imapuser")) {
00685          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00686       } else if (!strcasecmp(tmp->name, "imappassword")) {
00687          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00688 #endif
00689       } else
00690          apply_option(retval, tmp->name, tmp->value);
00691       tmp = tmp->next;
00692    } 
00693 }

AST_APP_OPTIONS ( vm_app_options   ) 

static AST_LIST_HEAD_STATIC ( zones  ,
vm_zone   
) [static]

static AST_LIST_HEAD_STATIC ( users  ,
ast_vm_user   
) [static]

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
tdesc  ,
load = load_module,
unload = unload_module,
reload = reload 
)

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

Definition at line 1618 of file app_voicemail.c.

References ast_log(), BASEMAXINLINE, eol, inchar(), baseio::iocp, LOG_WARNING, and ochar().

Referenced by make_email_file().

01619 {
01620    unsigned char dtable[BASEMAXINLINE];
01621    int i,hiteof= 0;
01622    FILE *fi;
01623    struct baseio bio;
01624 
01625    memset(&bio, 0, sizeof(bio));
01626    bio.iocp = BASEMAXINLINE;
01627 
01628    if (!(fi = fopen(filename, "rb"))) {
01629       ast_log(LOG_WARNING, "Failed to open log file: %s: %s\n", filename, strerror(errno));
01630       return -1;
01631    }
01632 
01633    for (i= 0;i<9;i++) {
01634       dtable[i]= 'A'+i;
01635       dtable[i+9]= 'J'+i;
01636       dtable[26+i]= 'a'+i;
01637       dtable[26+i+9]= 'j'+i;
01638    }
01639    for (i= 0;i<8;i++) {
01640       dtable[i+18]= 'S'+i;
01641       dtable[26+i+18]= 's'+i;
01642    }
01643    for (i= 0;i<10;i++) {
01644       dtable[52+i]= '0'+i;
01645    }
01646    dtable[62]= '+';
01647    dtable[63]= '/';
01648 
01649    while (!hiteof){
01650       unsigned char igroup[3],ogroup[4];
01651       int c,n;
01652 
01653       igroup[0]= igroup[1]= igroup[2]= 0;
01654 
01655       for (n= 0;n<3;n++) {
01656          if ((c = inchar(&bio, fi)) == EOF) {
01657             hiteof= 1;
01658             break;
01659          }
01660 
01661          igroup[n]= (unsigned char)c;
01662       }
01663 
01664       if (n> 0) {
01665          ogroup[0]= dtable[igroup[0]>>2];
01666          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
01667          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
01668          ogroup[3]= dtable[igroup[2]&0x3F];
01669 
01670          if (n<3) {
01671             ogroup[3]= '=';
01672 
01673             if (n<2)
01674                ogroup[2]= '=';
01675          }
01676 
01677          for (i= 0;i<4;i++)
01678             ochar(&bio, ogroup[i], so);
01679       }
01680    }
01681 
01682    if (fputs(eol,so)==EOF)
01683       return 0;
01684 
01685    fclose(fi);
01686 
01687    return 1;
01688 }

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

Definition at line 633 of file app_voicemail.c.

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

Referenced by vm_change_password().

00634 {
00635    int res;
00636    if (!ast_strlen_zero(vmu->uniqueid)) {
00637       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00638       if (res > 0) {
00639          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00640          res = 0;
00641       } else if (!res) {
00642          res = -1;
00643       }
00644       return res;
00645    }
00646    return -1;
00647 }

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

Definition at line 4730 of file app_voicemail.c.

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

Referenced by vm_execmain().

04731 {
04732    int x = 0;
04733 #ifndef IMAP_STORAGE
04734    int res = 0, nummsg;
04735 #endif
04736 
04737    if (vms->lastmsg <= -1)
04738       goto done;
04739 
04740    vms->curmsg = -1; 
04741 #ifndef IMAP_STORAGE
04742    /* Get the deleted messages fixed */ 
04743    if (vm_lock_path(vms->curdir))
04744       return ERROR_LOCK_PATH;
04745     
04746    for (x = 0; x < vmu->maxmsg; x++) { 
04747       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
04748          /* Save this message.  It's not in INBOX or hasn't been heard */ 
04749          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
04750          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
04751             break;
04752          vms->curmsg++; 
04753          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
04754          if (strcmp(vms->fn, vms->fn2)) { 
04755             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
04756          } 
04757       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
04758          /* Move to old folder before deleting */ 
04759          res = save_to_folder(vmu, vms, x, 1);
04760          if (res == ERROR_LOCK_PATH) {
04761             /* If save failed do not delete the message */
04762             vms->deleted[x] = 0;
04763             vms->heard[x] = 0;
04764             --x;
04765          } 
04766       } 
04767    } 
04768 
04769    /* Delete ALL remaining messages */
04770    nummsg = x - 1;
04771    for (x = vms->curmsg + 1; x <= nummsg; x++) {
04772       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
04773       if (EXISTS(vms->curdir, x, vms->fn, NULL))
04774          DELETE(vms->curdir, x, vms->fn);
04775    }
04776    ast_unlock_path(vms->curdir);
04777 #else
04778    if (vms->deleted) {
04779       for (x=0;x < vmu->maxmsg;x++) { 
04780          if (vms->deleted[x]) { 
04781             if(option_debug > 2)
04782                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
04783             IMAP_DELETE(vms->curdir, x, vms->fn, vms);
04784          }
04785       }
04786    }
04787 #endif
04788 
04789 done:
04790    if (vms->deleted)
04791       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
04792    if (vms->heard)
04793       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
04794 
04795    return 0;
04796 }

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

Definition at line 7046 of file app_voicemail.c.

References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.

07047 {
07048    int which = 0;
07049    int wordlen;
07050    struct ast_vm_user *vmu;
07051    const char *context = "";
07052 
07053    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
07054    if (pos > 4)
07055       return NULL;
07056    if (pos == 3)
07057       return (state == 0) ? ast_strdup("for") : NULL;
07058    wordlen = strlen(word);
07059    AST_LIST_TRAVERSE(&users, vmu, list) {
07060       if (!strncasecmp(word, vmu->context, wordlen)) {
07061          if (context && strcmp(context, vmu->context) && ++which > state)
07062             return ast_strdup(vmu->context);
07063          /* ignore repeated contexts ? */
07064          context = vmu->context;
07065       }
07066    }
07067    return NULL;
07068 }

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

Definition at line 1470 of file app_voicemail.c.

References ast_log(), LOG_WARNING, and VOICEMAIL_FILE_MODE.

01471 {
01472    int ifd;
01473    int ofd;
01474    int res;
01475    int len;
01476    char buf[4096];
01477 
01478 #ifdef HARDLINK_WHEN_POSSIBLE
01479    /* Hard link if possible; saves disk space & is faster */
01480    if (link(infile, outfile)) {
01481 #endif
01482       if ((ifd = open(infile, O_RDONLY)) < 0) {
01483          ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
01484          return -1;
01485       }
01486       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
01487          ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
01488          close(ifd);
01489          return -1;
01490       }
01491       do {
01492          len = read(ifd, buf, sizeof(buf));
01493          if (len < 0) {
01494             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
01495             close(ifd);
01496             close(ofd);
01497             unlink(outfile);
01498          }
01499          if (len) {
01500             res = write(ofd, buf, len);
01501             if (errno == ENOMEM || errno == ENOSPC || res != len) {
01502                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
01503                close(ifd);
01504                close(ofd);
01505                unlink(outfile);
01506             }
01507          }
01508       } while (len);
01509       close(ifd);
01510       close(ofd);
01511       return 0;
01512 #ifdef HARDLINK_WHEN_POSSIBLE
01513    } else {
01514       /* Hard link succeeded */
01515       return 0;
01516    }
01517 #endif
01518 }

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

Definition at line 1520 of file app_voicemail.c.

References ast_filecopy(), and copy().

01521 {
01522    char frompath2[PATH_MAX], topath2[PATH_MAX];
01523    ast_filecopy(frompath, topath, NULL);
01524    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
01525    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
01526    copy(frompath2, topath2);
01527 }

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 2514 of file app_voicemail.c.

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

Referenced by forward_message(), and leave_voicemail().

02515 {
02516    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
02517    const char *frombox = mbox(imbox);
02518    int recipmsgnum;
02519 
02520    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
02521 
02522    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
02523    
02524    if (!dir)
02525       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
02526    else
02527       ast_copy_string(fromdir, dir, sizeof(fromdir));
02528 
02529    make_file(frompath, sizeof(frompath), fromdir, msgnum);
02530 
02531    if (vm_lock_path(todir))
02532       return ERROR_LOCK_PATH;
02533 
02534    recipmsgnum = 0;
02535    do {
02536       make_file(topath, sizeof(topath), todir, recipmsgnum);
02537       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
02538          break;
02539       recipmsgnum++;
02540    } while (recipmsgnum < recip->maxmsg);
02541    if (recipmsgnum < recip->maxmsg) {
02542       COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
02543    } else {
02544       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
02545    }
02546    ast_unlock_path(todir);
02547    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
02548    
02549    return 0;
02550 }

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

Definition at line 1437 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

01438 {
01439    /* Find all .txt files - even if they are not in sequence from 0000 */
01440 
01441    int vmcount = 0;
01442    DIR *vmdir = NULL;
01443    struct dirent *vment = NULL;
01444 
01445    if (vm_lock_path(dir))
01446       return ERROR_LOCK_PATH;
01447 
01448    if ((vmdir = opendir(dir))) {
01449       while ((vment = readdir(vmdir))) {
01450          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
01451             vmcount++;
01452       }
01453       closedir(vmdir);
01454    }
01455    ast_unlock_path(dir);
01456    
01457    return vmcount;
01458 }

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 904 of file app_voicemail.c.

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

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

00905 {
00906    mode_t   mode = VOICEMAIL_DIR_MODE;
00907 
00908    if (!ast_strlen_zero(context)) {
00909       make_dir(dest, len, context, "", "");
00910       if (mkdir(dest, mode) && errno != EEXIST) {
00911          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00912          return -1;
00913       }
00914    }
00915    if (!ast_strlen_zero(ext)) {
00916       make_dir(dest, len, context, ext, "");
00917       if (mkdir(dest, mode) && errno != EEXIST) {
00918          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00919          return -1;
00920       }
00921    }
00922    if (!ast_strlen_zero(folder)) {
00923       make_dir(dest, len, context, ext, folder);
00924       if (mkdir(dest, mode) && errno != EEXIST) {
00925          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00926          return -1;
00927       }
00928    }
00929    return 0;
00930 }

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

Definition at line 7684 of file app_voicemail.c.

References 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.

07685 {
07686    int cmd = 0;
07687    char destination[80] = "";
07688    int retries = 0;
07689 
07690    if (!num) {
07691       if (option_verbose > 2)
07692          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
07693       while (retries < 3 && cmd != 't') {
07694          destination[1] = '\0';
07695          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
07696          if (!cmd)
07697             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
07698          if (!cmd)
07699             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
07700          if (!cmd) {
07701             cmd = ast_waitfordigit(chan, 6000);
07702             if (cmd)
07703                destination[0] = cmd;
07704          }
07705          if (!cmd) {
07706             retries++;
07707          } else {
07708 
07709             if (cmd < 0)
07710                return 0;
07711             if (cmd == '*') {
07712                if (option_verbose > 2)
07713                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
07714                return 0;
07715             }
07716             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
07717                retries++;
07718             else
07719                cmd = 't';
07720          }
07721       }
07722       if (retries >= 3) {
07723          return 0;
07724       }
07725       
07726    } else {
07727       if (option_verbose > 2)
07728          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
07729       ast_copy_string(destination, num, sizeof(destination));
07730    }
07731 
07732    if (!ast_strlen_zero(destination)) {
07733       if (destination[strlen(destination) -1 ] == '*')
07734          return 0; 
07735       if (option_verbose > 2)
07736          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
07737       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
07738       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
07739       chan->priority = 0;
07740       return 9;
07741    }
07742    return 0;
07743 }

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

Definition at line 6837 of file app_voicemail.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::mailbox, and VM_SEARCH.

Referenced by append_mailbox(), and load_config().

06838 {
06839    struct ast_vm_user *vmu;
06840    AST_LIST_TRAVERSE(&users, vmu, list) {
06841       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
06842          break;
06843       if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
06844          break;
06845    }
06846    
06847    if (!vmu) {
06848       if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
06849          ast_copy_string(vmu->context, context, sizeof(vmu->context));
06850          ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
06851          AST_LIST_INSERT_TAIL(&users, vmu, list);
06852       }
06853    }
06854    return vmu;
06855 }

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

Definition at line 724 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, VM_ALLOCED, and VM_SEARCH.

00725 {
00726    /* This function could be made to generate one from a database, too */
00727    struct ast_vm_user *vmu=NULL, *cur;
00728    AST_LIST_LOCK(&users);
00729 
00730    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00731       context = "default";
00732 
00733    AST_LIST_TRAVERSE(&users, cur, list) {
00734       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00735          break;
00736       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00737          break;
00738    }
00739    if (cur) {
00740       /* Make a copy, so that on a reload, we have no race */
00741       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00742          memcpy(vmu, cur, sizeof(*vmu));
00743          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00744          AST_LIST_NEXT(vmu, list) = NULL;
00745       }
00746    } else
00747       vmu = find_user_realtime(ivm, context, mailbox);
00748    AST_LIST_UNLOCK(&users);
00749    return vmu;
00750 }

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

Definition at line 695 of file app_voicemail.c.

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

Referenced by find_user().

00696 {
00697    struct ast_variable *var;
00698    struct ast_vm_user *retval;
00699 
00700    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00701       if (!ivm)
00702          ast_set_flag(retval, VM_ALLOCED);   
00703       else
00704          memset(retval, 0, sizeof(*retval));
00705       if (mailbox) 
00706          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00707       populate_defaults(retval);
00708       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00709          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00710       else
00711          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00712       if (var) {
00713          apply_options_full(retval, var);
00714          ast_variables_destroy(var);
00715       } else { 
00716          if (!ivm) 
00717             free(retval);
00718          retval = NULL;
00719       }  
00720    } 
00721    return retval;
00722 }

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 3856 of file app_voicemail.c.

References app, ast_clear_flag, 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_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, copy_message(), vm_state::curdir, vm_state::curmsg, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, leave_voicemail(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_vm_user::mailbox, option_debug, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), ast_vm_user::serveremail, STORE, strsep(), username, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), VM_SPOOL_DIR, and vmfmts.

Referenced by vm_execmain().

03857 {
03858 #ifdef IMAP_STORAGE
03859    BODY *body;
03860    char *header_content;
03861    char *temp;
03862    char todir[256];
03863    int todircount=0;
03864    struct vm_state *dstvms;
03865 #endif
03866    char username[70]="";
03867    int res = 0, cmd = 0;
03868    struct ast_vm_user *receiver = NULL, *vmtmp;
03869    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
03870    char *stringp;
03871    const char *s;
03872    int saved_messages = 0, found = 0;
03873    int valid_extensions = 0;
03874    char *dir;
03875    int curmsg;
03876 
03877    if (vms == NULL) return -1;
03878    dir = vms->curdir;
03879    curmsg = vms->curmsg;
03880    
03881    while (!res && !valid_extensions) {
03882       int use_directory = 0;
03883       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
03884          int done = 0;
03885          int retries = 0;
03886          cmd=0;
03887          while ((cmd >= 0) && !done ){
03888             if (cmd)
03889                retries = 0;
03890             switch (cmd) {
03891             case '1': 
03892                use_directory = 0;
03893                done = 1;
03894                break;
03895             case '2': 
03896                use_directory = 1;
03897                done=1;
03898                break;
03899             case '*': 
03900                cmd = 't';
03901                done = 1;
03902                break;
03903             default: 
03904                /* Press 1 to enter an extension press 2 to use the directory */
03905                cmd = ast_play_and_wait(chan,"vm-forward");
03906                if (!cmd)
03907                   cmd = ast_waitfordigit(chan,3000);
03908                if (!cmd)
03909                   retries++;
03910                if (retries > 3)
03911                {
03912                   cmd = 't';
03913                   done = 1;
03914                }
03915                
03916             }
03917          }
03918          if (cmd < 0 || cmd == 't')
03919             break;
03920       }
03921       
03922       if (use_directory) {
03923          /* use app_directory */
03924          
03925          char old_context[sizeof(chan->context)];
03926          char old_exten[sizeof(chan->exten)];
03927          int old_priority;
03928          struct ast_app* app;
03929 
03930          
03931          app = pbx_findapp("Directory");
03932          if (app) {
03933             char vmcontext[256];
03934             /* make backup copies */
03935             memcpy(old_context, chan->context, sizeof(chan->context));
03936             memcpy(old_exten, chan->exten, sizeof(chan->exten));
03937             old_priority = chan->priority;
03938             
03939             /* call the the Directory, changes the channel */
03940             sprintf(vmcontext, "%s||v", context ? context : "default");
03941             res = pbx_exec(chan, app, vmcontext);
03942             
03943             ast_copy_string(username, chan->exten, sizeof(username));
03944             
03945             /* restore the old context, exten, and priority */
03946             memcpy(chan->context, old_context, sizeof(chan->context));
03947             memcpy(chan->exten, old_exten, sizeof(chan->exten));
03948             chan->priority = old_priority;
03949             
03950          } else {
03951             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
03952             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
03953          }
03954       } else {
03955          /* Ask for an extension */
03956          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
03957          if (res)
03958             break;
03959          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
03960             break;
03961       }
03962       
03963       /* start all over if no username */
03964       if (ast_strlen_zero(username))
03965          continue;
03966       stringp = username;
03967       s = strsep(&stringp, "*");
03968       /* start optimistic */
03969       valid_extensions = 1;
03970       while (s) {
03971          /* Don't forward to ourselves.  find_user is going to malloc since we have a NULL as first argument */
03972          if (strcmp(s,sender->mailbox) && (receiver = find_user(NULL, context, s))) {
03973             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
03974             found++;
03975          } else {
03976             valid_extensions = 0;
03977             break;
03978          }
03979          s = strsep(&stringp, "*");
03980       }
03981       /* break from the loop of reading the extensions */
03982       if (valid_extensions)
03983          break;
03984       /* "I am sorry, that's not a valid extension.  Please try again." */
03985       res = ast_play_and_wait(chan, "pbx-invalid");
03986    }
03987    /* check if we're clear to proceed */
03988    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
03989       return res;
03990    if (flag==1) {
03991       struct leave_vm_options leave_options;
03992       char mailbox[AST_MAX_EXTENSION * 2 + 2];
03993       snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
03994 
03995       /* Send VoiceMail */
03996       memset(&leave_options, 0, sizeof(leave_options));
03997       leave_options.record_gain = record_gain;
03998       cmd = leave_voicemail(chan, mailbox, &leave_options);
03999    } else {
04000 
04001       /* Forward VoiceMail */
04002       long duration = 0;
04003       RETRIEVE(dir, curmsg);
04004       cmd = vm_forwardoptions(chan, sender, dir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, vms);
04005       if (!cmd) {
04006          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
04007 #ifdef IMAP_STORAGE
04008             /* Need to get message content */
04009             if(option_debug > 2)
04010                ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
04011             if (vms->msgArray[vms->curmsg] == 0) {
04012                ast_log (LOG_WARNING,"Trying to access unknown message\n");
04013                return -1;
04014             }
04015 
04016             /* This will only work for new messages... */
04017             header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
04018             /* empty string means no valid header */
04019             if (ast_strlen_zero(header_content)) {
04020                ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
04021                return -1;
04022             }
04023             /* Get header info needed by sendmail */
04024             temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
04025             if (temp)
04026                duration = atoi(temp);
04027             else
04028                duration = 0;
04029 
04030             /* Attach only the first format */
04031             fmt = ast_strdupa(fmt);
04032             if (fmt) {
04033                stringp = fmt;
04034                strsep(&stringp, "|");
04035             } else {
04036                ast_log (LOG_ERROR,"audio format not set. Default to WAV\n");
04037                fmt = "WAV";
04038             }
04039             if (!strcasecmp(fmt, "wav49"))
04040                fmt = "WAV";
04041             if(option_debug > 2)
04042                ast_log (LOG_DEBUG,"**** format set to %s, vmfmts set to %s\n",fmt,vmfmts);
04043             /* ast_copy_string(fmt, vmfmts, sizeof(fmt));*/
04044             /* if (!ast_strlen_zero(fmt)) { */
04045             snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
04046             make_gsm_file(vms->fn, vms->imapuser, todir, vms->curmsg);
04047             if(option_debug > 2)
04048                ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
04049             /*mail_fetchstructure (mailstream, vmArray[0], &body); */
04050             mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
04051             save_body(body,vms,"3","gsm");
04052             /* should not assume "fmt" here! */
04053             save_body(body,vms,"2",fmt);
04054 
04055             /* get destination mailbox */
04056             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox,0);
04057             if (dstvms) {
04058                init_mailstream(dstvms, 0);
04059                if (!dstvms->mailstream) {
04060                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
04061                } else {
04062                   STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
04063                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
04064                }
04065             } else {
04066                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
04067             }
04068 
04069             char *myserveremail = serveremail;
04070             if (!ast_strlen_zero(vmtmp->serveremail))
04071                myserveremail = vmtmp->serveremail;
04072             int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
04073             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
04074             /* NULL category for IMAP storage */
04075             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);
04076 #else
04077             copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir);
04078 #endif
04079             saved_messages++;
04080             AST_LIST_REMOVE_CURRENT(&extensions, list);
04081             free_user(vmtmp);
04082             if (res)
04083                break;
04084          }
04085          AST_LIST_TRAVERSE_SAFE_END;
04086          if (saved_messages > 0) {
04087             /* give confirmation that the message was saved */
04088             /* commented out since we can't forward batches yet
04089             if (saved_messages == 1)
04090                res = ast_play_and_wait(chan, "vm-message");
04091             else
04092                res = ast_play_and_wait(chan, "vm-messages");
04093             if (!res)
04094                res = ast_play_and_wait(chan, "vm-saved"); */
04095             res = ast_play_and_wait(chan, "vm-msgsaved");
04096          }  
04097       }
04098    }
04099 
04100    /* If anything failed above, we still have this list to free */
04101    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
04102       free_user(vmtmp);
04103    return res ? res : cmd;
04104 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 2085 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

02086 {
02087    if (ast_test_flag(vmu, VM_ALLOCED))
02088       free(vmu);
02089 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 2091 of file app_voicemail.c.

References free.

02092 {
02093    free(z);
02094 }

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

Definition at line 2042 of file app_voicemail.c.

References ast_localtime(), and t.

Referenced by leave_voicemail(), and tds_log().

02043 {
02044    struct tm tm;
02045    time_t t;
02046    t = time(0);
02047    ast_localtime(&t, &tm, NULL);
02048    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
02049 }

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

Definition at line 3668 of file app_voicemail.c.

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

Referenced by get_folder2().

03669 {
03670    int x;
03671    int d;
03672    char fn[PATH_MAX];
03673    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
03674    if (d)
03675       return d;
03676    for (x = start; x< 5; x++) {  /* For all folders */
03677       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
03678          return d;
03679       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
03680       if (d)
03681          return d;
03682       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
03683       d = vm_play_folder_name(chan, fn);
03684       if (d)
03685          return d;
03686       d = ast_waitfordigit(chan, 500);
03687       if (d)
03688          return d;
03689    }
03690    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
03691    if (d)
03692       return d;
03693    d = ast_waitfordigit(chan, 4000);
03694    return d;
03695 }

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

Definition at line 3697 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

03698 {
03699    int res = 0;
03700    res = ast_play_and_wait(chan, fn);  /* Folder name */
03701    while (((res < '0') || (res > '9')) &&
03702          (res != '#') && (res >= 0)) {
03703       res = get_folder(chan, 0);
03704    }
03705    return res;
03706 }

static int get_lastdigits ( int  num  )  [static]

Definition at line 5510 of file app_voicemail.c.

Referenced by vm_intro_ru().

05511 {
05512    num %= 100;
05513    return (num < 20) ? num : num % 10;
05514 }

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

Definition at line 6976 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::mailbox, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_vm_user::zonetag.

06977 {
06978    struct ast_vm_user *vmu;
06979    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
06980 
06981    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
06982    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
06983 
06984    AST_LIST_LOCK(&users);
06985    if (!AST_LIST_EMPTY(&users)) {
06986       if (argc == 3)
06987          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
06988       else {
06989          int count = 0;
06990          AST_LIST_TRAVERSE(&users, vmu, list) {
06991             if (!strcmp(argv[4],vmu->context))
06992                count++;
06993          }
06994          if (count) {
06995             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
06996          } else {
06997             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
06998             AST_LIST_UNLOCK(&users);
06999             return RESULT_FAILURE;
07000          }
07001       }
07002       AST_LIST_TRAVERSE(&users, vmu, list) {
07003          int newmsgs = 0, oldmsgs = 0;
07004          char count[12], tmp[256] = "";
07005 
07006          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
07007             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
07008             inboxcount(tmp, &newmsgs, &oldmsgs);
07009             snprintf(count,sizeof(count),"%d",newmsgs);
07010             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
07011          }
07012       }
07013    } else {
07014       ast_cli(fd, "There are no voicemail users currently defined\n");
07015       AST_LIST_UNLOCK(&users);
07016       return RESULT_FAILURE;
07017    }
07018    AST_LIST_UNLOCK(&users);
07019    return RESULT_SUCCESS;
07020 }

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

Definition at line 7022 of file app_voicemail.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

07023 {
07024    struct vm_zone *zone;
07025    char *output_format = "%-15s %-20s %-45s\n";
07026    int res = RESULT_SUCCESS;
07027 
07028    if (argc != 3)
07029       return RESULT_SHOWUSAGE;
07030 
07031    AST_LIST_LOCK(&zones);
07032    if (!AST_LIST_EMPTY(&zones)) {
07033       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
07034       AST_LIST_TRAVERSE(&zones, zone, list) {
07035          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
07036       }
07037    } else {
07038       ast_cli(fd, "There are no voicemail zones currently defined\n");
07039       res = RESULT_FAILURE;
07040    }
07041    AST_LIST_UNLOCK(&zones);
07042 
07043    return res;
07044 }

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

Definition at line 2590 of file app_voicemail.c.

References __has_voicemail(), mbox(), and strsep().

02591 {
02592    char tmp[256], *tmp2 = tmp, *mbox, *context;
02593    ast_copy_string(tmp, mailbox, sizeof(tmp));
02594    while ((mbox = strsep(&tmp2, ","))) {
02595       if ((context = strchr(mbox, '@')))
02596          *context++ = '\0';
02597       else
02598          context = "default";
02599       if (__has_voicemail(context, mbox, folder, 1))
02600          return 1;
02601    }
02602    return 0;
02603 }

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

Definition at line 2606 of file app_voicemail.c.

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

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

02607 {
02608    char tmp[256];
02609    char *context;
02610 
02611    if (newmsgs)
02612       *newmsgs = 0;
02613    if (oldmsgs)
02614       *oldmsgs = 0;
02615    /* If no mailbox, return immediately */
02616    if (ast_strlen_zero(mailbox))
02617       return 0;
02618    if (strchr(mailbox, ',')) {
02619       int tmpnew, tmpold;
02620       char *mb, *cur;
02621 
02622       ast_copy_string(tmp, mailbox, sizeof(tmp));
02623       mb = tmp;
02624       while ((cur = strsep(&mb, ", "))) {
02625          if (!ast_strlen_zero(cur)) {
02626             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
02627                return -1;
02628             else {
02629                if (newmsgs)
02630                   *newmsgs += tmpnew; 
02631                if (oldmsgs)
02632                   *oldmsgs += tmpold;
02633             }
02634          }
02635       }
02636       return 0;
02637    }
02638    ast_copy_string(tmp, mailbox, sizeof(tmp));
02639    context = strchr(tmp, '@');
02640    if (context) {
02641       *context = '\0';
02642       context++;
02643    } else
02644       context = "default";
02645    if (newmsgs)
02646       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
02647    if (oldmsgs)
02648       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
02649    return 0;
02650 }

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

Definition at line 1570 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

01571 {
01572    int l;
01573 
01574    if (bio->ateof)
01575       return 0;
01576 
01577    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
01578       if (ferror(fi))
01579          return -1;
01580 
01581       bio->ateof = 1;
01582       return 0;
01583    }
01584 
01585    bio->iolen= l;
01586    bio->iocp= 0;
01587 
01588    return 1;
01589 }

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

Definition at line 1591 of file app_voicemail.c.

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

Referenced by base_encode().

01592 {
01593    if (bio->iocp>=bio->iolen) {
01594       if (!inbuf(bio, fi))
01595          return EOF;
01596    }
01597 
01598    return bio->iobuf[bio->iocp++];
01599 }

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

Definition at line 2051 of file app_voicemail.c.

References ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, LOG_WARNING, RETRIEVE, and VM_SPOOL_DIR.

Referenced by leave_voicemail().

02052 {
02053    int res;
02054    char fn[PATH_MAX];
02055    char dest[PATH_MAX];
02056 
02057    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
02058 
02059    if ((res = create_dirpath(dest, sizeof(dest), context, ext, "greet"))) {
02060       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
02061       return -1;
02062    }
02063 
02064    RETRIEVE(fn, -1);
02065    if (ast_fileexists(fn, NULL, NULL) > 0) {
02066       res = ast_stream_and_wait(chan, fn, chan->language, ecodes);
02067       if (res) {
02068          DISPOSE(fn, -1);
02069          return res;
02070       }
02071    } else {
02072       /* Dispose just in case */
02073       DISPOSE(fn, -1);
02074       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
02075       if (res)
02076          return res;
02077       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
02078       if (res)
02079          return res;
02080    }
02081    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
02082    return res;
02083 }

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

Definition at line 1533 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().

01534 {
01535    int x;
01536    char fn[PATH_MAX];
01537 
01538    if (vm_lock_path(dir))
01539       return ERROR_LOCK_PATH;
01540 
01541    for (x = 0; x < vmu->maxmsg; x++) {
01542       make_file(fn, sizeof(fn), dir, x);
01543       if (ast_fileexists(fn, NULL, NULL) < 1)
01544          break;
01545    }
01546    ast_unlock_path(dir);
01547 
01548    return x - 1;
01549 }

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

Definition at line 2701 of file app_voicemail.c.

References ast_callerid_merge(), ast_calloc, 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(), vm_state::curbox, DISPOSE, EXISTS, ast_vm_user::exit, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), INTRO, invent_message(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, mbox(), my_umask, 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_record_review(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, S_OR, STORE, strsep(), transfer, vm_state::username, VERBOSE_PREFIX_3, vm_lock_path(), VM_OPERATOR, VM_SPOOL_DIR, vmfmts, vmmaxmessage, vmminmessage, and VOICEMAIL_FILE_MODE.

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

02702 {
02703 #ifdef IMAP_STORAGE
02704    int newmsgs, oldmsgs;
02705    struct vm_state *vms = NULL;
02706 #endif
02707    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
02708    char callerid[256];
02709    FILE *txt;
02710    char date[256];
02711    int txtdes;
02712    int res = 0;
02713    int msgnum;
02714    int duration = 0;
02715    int ausemacro = 0;
02716    int ousemacro = 0;
02717    int ouseexten = 0;
02718    char dir[PATH_MAX], tmpdir[PATH_MAX];
02719    char dest[PATH_MAX];
02720    char fn[PATH_MAX];
02721    char prefile[PATH_MAX] = "";
02722    char tempfile[PATH_MAX] = "";
02723    char ext_context[256] = "";
02724    char fmt[80];
02725    char *context;
02726    char ecodes[16] = "#";
02727    char tmp[1024] = "", *tmpptr;
02728    struct ast_vm_user *vmu;
02729    struct ast_vm_user svm;
02730    const char *category = NULL;
02731 
02732    ast_copy_string(tmp, ext, sizeof(tmp));
02733    ext = tmp;
02734    context = strchr(tmp, '@');
02735    if (context) {
02736       *context++ = '\0';
02737       tmpptr = strchr(context, '&');
02738    } else {
02739       tmpptr = strchr(ext, '&');
02740    }
02741 
02742    if (tmpptr)
02743       *tmpptr++ = '\0';
02744 
02745    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
02746 
02747    if(option_debug > 2)
02748       ast_log(LOG_DEBUG, "Before find_user\n");
02749    if (!(vmu = find_user(&svm, context, ext))) {
02750       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
02751       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
02752          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
02753       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02754       return res;
02755    }
02756    /* Setup pre-file if appropriate */
02757    if (strcmp(vmu->context, "default"))
02758       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
02759    else
02760       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
02761    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
02762       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
02763       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
02764    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
02765       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
02766       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
02767    }
02768    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
02769    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
02770       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
02771       return -1;
02772    }
02773    RETRIEVE(tempfile, -1);
02774    if (ast_fileexists(tempfile, NULL, NULL) > 0)
02775       ast_copy_string(prefile, tempfile, sizeof(prefile));
02776    DISPOSE(tempfile, -1);
02777    /* It's easier just to try to make it than to check for its existence */
02778    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
02779    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
02780 
02781    /* Check current or macro-calling context for special extensions */
02782    if (ast_test_flag(vmu, VM_OPERATOR)) {
02783       if (!ast_strlen_zero(vmu->exit)) {
02784          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
02785             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02786             ouseexten = 1;
02787          }
02788       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
02789          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02790          ouseexten = 1;
02791       }
02792       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
02793       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02794       ousemacro = 1;
02795       }
02796    }
02797 
02798    if (!ast_strlen_zero(vmu->exit)) {
02799       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
02800          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02801    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
02802       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02803    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
02804       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02805       ausemacro = 1;
02806    }
02807 
02808    /* Play the beginning intro if desired */
02809    if (!ast_strlen_zero(prefile)) {
02810       RETRIEVE(prefile, -1);
02811       if (ast_fileexists(prefile, NULL, NULL) > 0) {
02812          if (ast_streamfile(chan, prefile, chan->language) > -1) 
02813             res = ast_waitstream(chan, ecodes);
02814       } else {
02815          if (option_debug)
02816             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
02817          res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
02818       }
02819       DISPOSE(prefile, -1);
02820       if (res < 0) {
02821          if (option_debug)
02822             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
02823          free_user(vmu);
02824          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02825          return -1;
02826       }
02827    }
02828    if (res == '#') {
02829       /* On a '#' we skip the instructions */
02830       ast_set_flag(options, OPT_SILENT);
02831       res = 0;
02832    }
02833    if (!res && !ast_test_flag(options, OPT_SILENT)) {
02834       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
02835       if (res == '#') {
02836          ast_set_flag(options, OPT_SILENT);
02837          res = 0;
02838       }
02839    }
02840    if (res > 0)
02841       ast_stopstream(chan);
02842    /* Check for a '*' here in case the caller wants to escape from voicemail to something
02843     other than the operator -- an automated attendant or mailbox login for example */
02844    if (res == '*') {
02845       chan->exten[0] = 'a';
02846       chan->exten[1] = '\0';
02847       if (!ast_strlen_zero(vmu->exit)) {
02848          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02849       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
02850          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02851       }
02852       chan->priority = 0;
02853       free_user(vmu);
02854       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02855       return 0;
02856    }
02857 
02858    /* Check for a '0' here */
02859    if (res == '0') {
02860    transfer:
02861       if (ouseexten || ousemacro) {
02862          chan->exten[0] = 'o';
02863          chan->exten[1] = '\0';
02864          if (!ast_strlen_zero(vmu->exit)) {
02865             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02866          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
02867             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02868          }
02869          ast_play_and_wait(chan, "transfer");
02870          chan->priority = 0;
02871          free_user(vmu);
02872          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02873       }
02874       return 0;
02875    }
02876    if (res < 0) {
02877       free_user(vmu);
02878       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02879       return -1;
02880    }
02881    /* The meat of recording the message...  All the announcements and beeps have been played*/
02882    ast_copy_string(fmt, vmfmts, sizeof(fmt));
02883    if (!ast_strlen_zero(fmt)) {
02884       msgnum = 0;
02885 
02886 #ifdef IMAP_STORAGE
02887       /* Is ext a mailbox? */
02888       /* must open stream for this user to get info! */
02889       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
02890       if(res < 0) {
02891          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
02892          return -1;
02893       }
02894       if(!(vms = get_vm_state_by_mailbox(ext,0))) {
02895       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
02896        * rarely be used*/
02897          if (!(vms = ast_calloc(1, sizeof(*vms)))) {
02898             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
02899             return -1;
02900          }
02901          ast_copy_string(vms->imapuser, vmu->imapuser, sizeof(vms->imapuser));
02902          ast_copy_string(vms->username, ext, sizeof(vms->username));
02903          vms->mailstream = NIL;
02904          if (option_debug > 2)
02905             ast_log(LOG_DEBUG, "Copied %s to %s\n", vmu->imapuser, vms->imapuser);
02906          vms->updated=1;
02907          ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
02908          init_vm_state(vms);
02909          vmstate_insert(vms);
02910          vms = get_vm_state_by_mailbox(ext,0);
02911       }
02912       vms->newmessages++;
02913       /* here is a big difference! We add one to it later */
02914       msgnum = newmsgs + oldmsgs;
02915       if (option_debug > 2)
02916          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
02917       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
02918       /* set variable for compatability */
02919       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
02920 
02921       /* Check if mailbox is full */
02922       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
02923          if(option_debug)
02924             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
02925          ast_play_and_wait(chan, "vm-mailboxfull");
02926          return -1;
02927       }
02928       /* here is a big difference! We add one to it later */
02929       if (option_debug > 2)
02930          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
02931 #else
02932       if (count_messages(vmu, dir) >= vmu->maxmsg) {
02933          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
02934          if (!res)
02935             res = ast_waitstream(chan, "");
02936          ast_log(LOG_WARNING, "No more messages possible\n");
02937          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02938          goto leave_vm_out;
02939       }
02940 
02941 #endif
02942       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
02943       txtdes = mkstemp(tmptxtfile);
02944       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
02945       if (txtdes < 0) {
02946          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
02947          if (!res)
02948             res = ast_waitstream(chan, "");
02949          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
02950          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02951          goto leave_vm_out;
02952       }
02953 
02954       /* Now play the beep once we have the message number for our next message. */
02955       if (res >= 0) {
02956          /* Unless we're *really* silent, try to send the beep */
02957          res = ast_stream_and_wait(chan, "beep", chan->language, "");
02958       }
02959             
02960       /* Store information */
02961       txt = fdopen(txtdes, "w+");
02962       if (txt) {
02963          get_date(date, sizeof(date));
02964          fprintf(txt, 
02965             ";\n"
02966             "; Message Information file\n"
02967             ";\n"
02968             "[message]\n"
02969             "origmailbox=%s\n"
02970             "context=%s\n"
02971             "macrocontext=%s\n"
02972             "exten=%s\n"
02973             "priority=%d\n"
02974             "callerchan=%s\n"
02975             "callerid=%s\n"
02976             "origdate=%s\n"
02977             "origtime=%ld\n"
02978             "category=%s\n",
02979             ext,
02980             chan->context,
02981             chan->macrocontext, 
02982             chan->exten,
02983             chan->priority,
02984             chan->name,
02985             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
02986             date, (long)time(NULL),
02987             category ? category : ""); 
02988       } else
02989          ast_log(LOG_WARNING, "Error opening text file for output\n");
02990 #ifdef IMAP_STORAGE
02991       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
02992 #else
02993       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, NULL);
02994 #endif
02995 
02996       if (txt) {
02997          if (duration < vmminmessage) {
02998             if (option_verbose > 2) 
02999                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
03000             ast_filedelete(tmptxtfile, NULL);
03001             unlink(tmptxtfile);
03002          } else {
03003             fprintf(txt, "duration=%d\n", duration);
03004             fclose(txt);
03005             if (vm_lock_path(dir)) {
03006                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
03007                /* Delete files */
03008                ast_filedelete(tmptxtfile, NULL);
03009                unlink(tmptxtfile);
03010             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
03011                if (option_debug) 
03012                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
03013                unlink(tmptxtfile);
03014                ast_unlock_path(dir);
03015             } else {
03016                for (;;) {
03017                   make_file(fn, sizeof(fn), dir, msgnum);
03018                   if (!EXISTS(dir, msgnum, fn, NULL))
03019                      break;
03020                   msgnum++;
03021                }
03022 
03023                /* assign a variable with the name of the voicemail file */ 
03024 #ifndef IMAP_STORAGE
03025                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
03026 #else
03027                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
03028 #endif
03029 
03030                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
03031                ast_filerename(tmptxtfile, fn, NULL);
03032                rename(tmptxtfile, txtfile);
03033 
03034                ast_unlock_path(dir);
03035 #ifndef IMAP_STORAGE
03036                /* We must store the file first, before copying the message, because
03037                 * ODBC storage does the entire copy with SQL.
03038                 */
03039                if (ast_fileexists(fn, NULL, NULL) > 0) {
03040                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
03041                }
03042 
03043                /* Are there to be more recipients of this message? */
03044                while (tmpptr) {
03045                   struct ast_vm_user recipu, *recip;
03046                   char *exten, *context;
03047                
03048                   exten = strsep(&tmpptr, "&");
03049                   context = strchr(exten, '@');
03050                   if (context) {
03051                      *context = '\0';
03052                      context++;
03053                   }
03054                   if ((recip = find_user(&recipu, context, exten))) {
03055                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
03056                      free_user(recip);
03057                   }
03058                }
03059 #endif
03060                /* Notification and disposal needs to happen after the copy, though. */
03061                if (ast_fileexists(fn, NULL, NULL)) {
03062                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03063                   DISPOSE(dir, msgnum);
03064                }
03065             }
03066          }
03067       }
03068       if (res == '0') {
03069          goto transfer;
03070       } else if (res > 0)
03071          res = 0;
03072 
03073       if (duration < vmminmessage)
03074          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
03075          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03076       else
03077          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
03078    } else
03079       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
03080 leave_vm_out:
03081    free_user(vmu);
03082    
03083    return res;
03084 }

static int load_config ( void   )  [static]

Definition at line 7090 of file app_voicemail.c.

References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_config_option(), ast_false(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_malloc, ast_set2_flag, ast_set_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, ast_vm_user::context, dialcontext, emailbody, emaildateformat, emailsubject, emailtitle, exitcontext, ext_pass_cmd, externnotify, find_or_create(), free, free_user(), free_zone(), fromstring, globalflags, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_vm_user::mailcmd, MAX_NUM_CID_CONTEXTS, maxgreet, maxlogins, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, maxsilence, ast_variable::name, ast_variable::next, option_debug, pagerbody, pagerfromstring, pagersubject, populate_defaults(), s, saydurationminfo, SENDMAIL, ast_vm_user::serveremail, silencethreshold, skipms, smdi_iface, strsep(), userscontext, ast_variable::value, var, VM_ALLOCED, 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, vmfmts, vmmaxmessage, vmminmessage, VOICEMAIL_CONFIG, and ast_vm_user::volgain.

07091 {
07092    struct ast_vm_user *cur;
07093    struct vm_zone *zcur;
07094    struct ast_config *cfg, *ucfg;
07095    char *cat;
07096    struct ast_variable *var;
07097    const char *notifystr = NULL;
07098    const char *smdistr = NULL;
07099    const char *astattach;
07100    const char *astsearch;
07101    const char *astsaycid;
07102    const char *send_voicemail;
07103 #ifdef IMAP_STORAGE
07104    const char *imap_server;
07105    const char *imap_port;
07106    const char *imap_flags;
07107    const char *imap_folder;
07108    const char *auth_user;
07109    const char *auth_password;
07110    const char *expunge_on_hangup;
07111 #endif
07112    const char *astcallop;
07113    const char *astreview;
07114    const char *asttempgreetwarn;
07115    const char *astskipcmd;
07116    const char *asthearenv;
07117    const char *astsaydurationinfo;
07118    const char *astsaydurationminfo;
07119    const char *silencestr;
07120    const char *maxmsgstr;
07121    const char *astdirfwd;
07122    const char *thresholdstr;
07123    const char *fmt;
07124    const char *astemail;
07125    const char *ucontext;
07126    const char *astmailcmd = SENDMAIL;
07127    const char *astforcename;
07128    const char *astforcegreet;
07129    const char *s;
07130    char *q,*stringp;
07131    const char *dialoutcxt = NULL;
07132    const char *callbackcxt = NULL;  
07133    const char *exitcxt = NULL;   
07134    const char *extpc;
07135    const char *emaildateformatstr;
07136    const char *volgainstr;
07137    int x;
07138    int tmpadsi[4];
07139 
07140    cfg = ast_config_load(VOICEMAIL_CONFIG);
07141 
07142    AST_LIST_LOCK(&users);
07143    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
07144       ast_set_flag(cur, VM_ALLOCED);
07145       free_user(cur);
07146    }
07147 
07148    AST_LIST_LOCK(&zones);
07149    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 
07150       free_zone(zcur);
07151    AST_LIST_UNLOCK(&zones);
07152 
07153    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
07154 
07155    if (cfg) {
07156       /* General settings */
07157 
07158       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
07159          ucontext = "default";
07160       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
07161       /* Attach voice message to mail message ? */
07162       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
07163          astattach = "yes";
07164       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
07165 
07166       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
07167          astsearch = "no";
07168       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
07169 
07170       volgain = 0.0;
07171       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
07172          sscanf(volgainstr, "%lf", &volgain);
07173 
07174 #ifdef ODBC_STORAGE
07175       strcpy(odbc_database, "asterisk");
07176       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
07177          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
07178       }
07179       strcpy(odbc_table, "voicemessages");
07180       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
07181          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
07182       }
07183 #endif      
07184       /* Mail command */
07185       strcpy(mailcmd, SENDMAIL);
07186       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
07187          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
07188 
07189       maxsilence = 0;
07190       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
07191          maxsilence = atoi(silencestr);
07192          if (maxsilence > 0)
07193             maxsilence *= 1000;
07194       }
07195       
07196       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
07197          maxmsg = MAXMSG;
07198       } else {
07199          maxmsg = atoi(maxmsgstr);
07200          if (maxmsg <= 0) {
07201             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
07202             maxmsg = MAXMSG;
07203          } else if (maxmsg > MAXMSGLIMIT) {
07204             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
07205             maxmsg = MAXMSGLIMIT;
07206          }
07207       }
07208 
07209       /* Load date format config for voicemail mail */
07210       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
07211          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
07212       }
07213 
07214       /* External password changing command */
07215       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
07216          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
07217       }
07218 #ifdef IMAP_STORAGE
07219       /* IMAP server address */
07220       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
07221          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
07222       } else {
07223          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
07224       }
07225       /* IMAP server port */
07226       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
07227          ast_copy_string(imapport, imap_port, sizeof(imapport));
07228       } else {
07229          ast_copy_string(imapport,"143", sizeof(imapport));
07230       }
07231       /* IMAP server flags */
07232       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
07233          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
07234       }
07235       /* IMAP server master username */
07236       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
07237          ast_copy_string(authuser, auth_user, sizeof(authuser));
07238       }
07239       /* IMAP server master password */
07240       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
07241          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
07242       }
07243       /* Expunge on exit */
07244       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
07245          if(ast_false(expunge_on_hangup))
07246             expungeonhangup = 0;
07247          else
07248             expungeonhangup = 1;
07249       } else {
07250          expungeonhangup = 1;
07251       }
07252       /* IMAP voicemail folder */
07253       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
07254          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
07255       } else {
07256          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
07257       }
07258 #endif
07259       /* External voicemail notify application */
07260       
07261       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
07262          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
07263          if (option_debug > 2)
07264             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
07265          if (!strcasecmp(externnotify, "smdi")) {
07266             if (option_debug)
07267                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
07268             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
07269                smdi_iface = ast_smdi_interface_find(smdistr);
07270             } else {
07271                if (option_debug)
07272                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
07273                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
07274             }
07275 
07276             if (!smdi_iface) {
07277                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
07278                externnotify[0] = '\0';
07279             } else {
07280                if (option_debug > 2)
07281                   ast_log(LOG_DEBUG, "Using SMDI port %s\n", smdi_iface->name);
07282             }
07283          }
07284       } else {
07285          externnotify[0] = '\0';
07286       }
07287 
07288       /* Silence treshold */
07289       silencethreshold = 256;
07290       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
07291          silencethreshold = atoi(thresholdstr);
07292       
07293       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
07294          astemail = ASTERISK_USERNAME;
07295       ast_copy_string(serveremail, astemail, sizeof(serveremail));
07296       
07297       vmmaxmessage = 0;
07298       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
07299          if (sscanf(s, "%d", &x) == 1) {
07300             vmmaxmessage = x;
07301          } else {
07302             ast_log(LOG_WARNING, "Invalid max message time length\n");
07303          }
07304       }
07305 
07306       vmminmessage = 0;
07307       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
07308          if (sscanf(s, "%d", &x) == 1) {
07309             vmminmessage = x;
07310             if (maxsilence <= vmminmessage)
07311                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
07312          } else {
07313             ast_log(LOG_WARNING, "Invalid min message time length\n");
07314          }
07315       }
07316       fmt = ast_variable_retrieve(cfg, "general", "format");
07317       if (!fmt)
07318          fmt = "wav";   
07319       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
07320 
07321       skipms = 3000;
07322       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
07323          if (sscanf(s, "%d", &x) == 1) {
07324             maxgreet = x;
07325          } else {
07326             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
07327          }
07328       }
07329 
07330       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
07331          if (sscanf(s, "%d", &x) == 1) {
07332             skipms = x;
07333          } else {
07334             ast_log(LOG_WARNING, "Invalid skipms value\n");
07335          }
07336       }
07337 
07338       maxlogins = 3;
07339       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
07340          if (sscanf(s, "%d", &x) == 1) {
07341             maxlogins = x;
07342          } else {
07343             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
07344          }
07345       }
07346 
07347       /* Force new user to record name ? */
07348       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
07349          astforcename = "no";
07350       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
07351 
07352       /* Force new user to record greetings ? */
07353       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
07354          astforcegreet = "no";
07355       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
07356 
07357       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
07358          if (option_debug > 2)
07359             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
07360          stringp = ast_strdupa(s);
07361          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
07362             if (!ast_strlen_zero(stringp)) {
07363                q = strsep(&stringp,",");
07364                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
07365                   q++;
07366                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
07367                if (option_debug > 2)
07368                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
07369             } else {
07370                cidinternalcontexts[x][0] = '\0';
07371             }
07372          }
07373       }
07374       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
07375          if (option_debug)
07376             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
07377          astreview = "no";
07378       }
07379       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
07380 
07381       /*Temperary greeting reminder */
07382       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
07383          if (option_debug)
07384             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
07385          asttempgreetwarn = "no";
07386       } else {
07387          if (option_debug)
07388             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
07389       }
07390       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
07391 
07392       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
07393          if (option_debug)
07394             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
07395          astcallop = "no";
07396       }
07397       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
07398 
07399       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
07400          if (option_debug)
07401             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
07402          astsaycid = "no";
07403       } 
07404       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
07405 
07406       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
07407          if (option_debug)
07408             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
07409          send_voicemail = "no";
07410       }
07411       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
07412    
07413       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
07414          if (option_debug)
07415             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
07416          asthearenv = "yes";
07417       }
07418       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
07419 
07420       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
07421          if (option_debug)
07422             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
07423          astsaydurationinfo = "yes";
07424       }
07425       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
07426 
07427       saydurationminfo = 2;
07428       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
07429          if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
07430             saydurationminfo = x;
07431          } else {
07432             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
07433          }
07434       }
07435 
07436       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
07437          if (option_debug)
07438             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
07439          astskipcmd = "no";
07440       }
07441       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
07442 
07443       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
07444          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
07445          if (option_debug)
07446             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
07447       } else {
07448          dialcontext[0] = '\0';  
07449       }
07450       
07451       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
07452          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
07453          if (option_debug)
07454             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
07455       } else {
07456          callcontext[0] = '\0';
07457       }
07458 
07459       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
07460          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
07461          if (option_debug)
07462             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
07463       } else {
07464          exitcontext[0] = '\0';
07465       }
07466 
07467       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
07468          astdirfwd = "no";
07469       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
07470       if ((ucfg = ast_config_load("users.conf"))) {   
07471          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
07472             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
07473                continue;
07474             if ((cur = find_or_create(userscontext, cat))) {
07475                populate_defaults(cur);
07476                apply_options_full(cur, ast_variable_browse(ucfg, cat));
07477                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
07478             }
07479          }
07480          ast_config_destroy(ucfg);
07481       }
07482       cat = ast_category_browse(cfg, NULL);
07483       while (cat) {
07484          if (strcasecmp(cat, "general")) {
07485             var = ast_variable_browse(cfg, cat);
07486             if (strcasecmp(cat, "zonemessages")) {
07487                /* Process mailboxes in this context */
07488                while (var) {
07489                   append_mailbox(cat, var->name, var->value);
07490                   var = var->next;
07491                }
07492             } else {
07493                /* Timezones in this context */
07494                while (var) {
07495                   struct vm_zone *z;
07496                   if ((z = ast_malloc(sizeof(*z)))) {
07497                      char *msg_format, *timezone;
07498                      msg_format = ast_strdupa(var->value);
07499                      timezone = strsep(&msg_format, "|");
07500                      if (msg_format) {
07501                         ast_copy_string(z->name, var->name, sizeof(z->name));
07502                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
07503                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
07504                         AST_LIST_LOCK(&zones);
07505                         AST_LIST_INSERT_HEAD(&zones, z, list);
07506                         AST_LIST_UNLOCK(&zones);
07507                      } else {
07508                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
07509                         free(z);
07510                      }
07511                   } else {
07512                      free(z);
07513                      AST_LIST_UNLOCK(&users);
07514                      ast_config_destroy(cfg);
07515                      return -1;
07516                   }
07517                   var = var->next;
07518                }
07519             }
07520          }
07521          cat = ast_category_browse(cfg, cat);
07522       }
07523       memset(fromstring,0,sizeof(fromstring));
07524       memset(pagerfromstring,0,sizeof(pagerfromstring));
07525       memset(emailtitle,0,sizeof(emailtitle));
07526       strcpy(charset, "ISO-8859-1");
07527       if (emailbody) {
07528          free(emailbody);
07529          emailbody = NULL;
07530       }
07531       if (emailsubject) {
07532          free(emailsubject);
07533          emailsubject = NULL;
07534       }
07535       if (pagerbody) {
07536          free(pagerbody);
07537          pagerbody = NULL;
07538       }
07539       if (pagersubject) {
07540          free(pagersubject);
07541          pagersubject = NULL;
07542       }
07543       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
07544          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
07545       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
07546          ast_copy_string(fromstring,s,sizeof(fromstring));
07547       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
07548          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
07549       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
07550          ast_copy_string(charset,s,sizeof(charset));
07551       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
07552          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
07553          for (x = 0; x < 4; x++) {
07554             memcpy(&adsifdn[x], &tmpadsi[x], 1);
07555          }
07556       }
07557       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
07558          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
07559          for (x = 0; x < 4; x++) {
07560             memcpy(&adsisec[x], &tmpadsi[x], 1);
07561          }
07562       }
07563       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
07564          if (atoi(s)) {
07565             adsiver = atoi(s);
07566          }
07567       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
07568          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
07569          ast_copy_string(emailtitle,s,sizeof(emailtitle));
07570       }
07571       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
07572          emailsubject = ast_strdup(s);
07573       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
07574          char *tmpread, *tmpwrite;
07575          emailbody = ast_strdup(s);
07576 
07577          /* substitute strings \t and \n into the appropriate characters */
07578          tmpread = tmpwrite = emailbody;
07579          while ((tmpwrite = strchr(tmpread,'\\'))) {
07580             switch (tmpwrite[1]) {
07581             case 'r':
07582                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07583                *tmpwrite = '\r';
07584                break;
07585             case 'n':
07586                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07587                *tmpwrite = '\n';
07588                break;
07589             case 't':
07590                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07591                *tmpwrite = '\t';
07592                break;
07593             default:
07594                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
07595             }
07596             tmpread = tmpwrite + 1;
07597          }
07598       }
07599       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
07600          pagersubject = ast_strdup(s);
07601       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
07602          char *tmpread, *tmpwrite;
07603          pagerbody = ast_strdup(s);
07604 
07605          /* substitute strings \t and \n into the appropriate characters */
07606          tmpread = tmpwrite = pagerbody;
07607          while ((tmpwrite = strchr(tmpread, '\\'))) {
07608             switch (tmpwrite[1]) {
07609             case 'r':
07610                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07611                *tmpwrite = '\r';
07612                break;
07613             case 'n':
07614                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07615                *tmpwrite = '\n';
07616                break;
07617             case 't':
07618                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07619                *tmpwrite = '\t';
07620                break;
07621             default:
07622                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
07623             }
07624             tmpread = tmpwrite + 1;
07625          }
07626       }
07627       AST_LIST_UNLOCK(&users);
07628       ast_config_destroy(cfg);
07629       return 0;
07630    } else {
07631       AST_LIST_UNLOCK(&users);
07632       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
07633       return 0;
07634    }
07635 }

static int load_module ( void   )  [static]

Definition at line 7658 of file app_voicemail.c.

References app, app2, app3, app4, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_install_vm_functions(), ast_register_application(), cli_voicemail, descrip_vm, descrip_vm_box_exists, descrip_vmain, descrip_vmauthenticate, has_voicemail(), inboxcount(), load_config(), messagecount(), my_umask, synopsis_vm, synopsis_vm_box_exists, synopsis_vmain, synopsis_vmauthenticate, vm_box_exists(), vm_exec(), vm_execmain(), VM_SPOOL_DIR, and vmauthenticate().

07659 {
07660    int res;
07661    my_umask = umask(0);
07662    umask(my_umask);
07663    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
07664    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
07665    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
07666    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
07667    if (res)
07668       return(res);
07669 
07670    if ((res=load_config())) {
07671       return(res);
07672    }
07673 
07674    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
07675 
07676    /* compute the location of the voicemail spool directory */
07677    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
07678 
07679    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
07680 
07681    return res;
07682 }

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

Definition at line 854 of file app_voicemail.c.

References VM_SPOOL_DIR.

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

00855 {
00856    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00857 }

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 1762 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strlen_zero(), ast_test_flag, base_encode(), charset, ast_vm_user::context, create_dirpath(), ast_vm_user::email, emailbody, emaildateformat, emailsubject, emailtitle, ENDL, fromstring, ast_vm_user::fullname, globalflags, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, my_umask, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

01763 {
01764    char date[256];
01765    char host[MAXHOSTNAMELEN] = "";
01766    char who[256];
01767    char bound[256];
01768    char fname[256];
01769    char dur[256];
01770    char tmpcmd[256];
01771    struct tm tm;
01772    char *passdata2;
01773    size_t len_passdata;
01774 #ifdef IMAP_STORAGE
01775 #define ENDL "\r\n"
01776 #else
01777 #define ENDL "\n"
01778 #endif
01779 
01780    gethostname(host, sizeof(host) - 1);
01781    if (strchr(srcemail, '@'))
01782       ast_copy_string(who, srcemail, sizeof(who));
01783    else {
01784       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01785    }
01786    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01787    strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
01788    fprintf(p, "Date: %s" ENDL, date);
01789 
01790    /* Set date format for voicemail mail */
01791    strftime(date, sizeof(date), emaildateformat, &tm);
01792 
01793    if (*fromstring) {
01794       struct ast_channel *ast;
01795       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01796          char *passdata;
01797          int vmlen = strlen(fromstring)*3 + 200;
01798          if ((passdata = alloca(vmlen))) {
01799             memset(passdata, 0, vmlen);
01800             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01801             pbx_substitute_variables_helper(ast, fromstring, passdata, vmlen);
01802             len_passdata = strlen(passdata) * 2 + 3;
01803             passdata2 = alloca(len_passdata);
01804             fprintf(p, "From: %s <%s>" ENDL, quote(passdata, passdata2, len_passdata), who);
01805          } else
01806             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01807          ast_channel_free(ast);
01808       } else
01809          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01810    } else
01811       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
01812    len_passdata = strlen(vmu->fullname) * 2 + 3;
01813    passdata2 = alloca(len_passdata);
01814    fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata), vmu->email);
01815    if (emailsubject) {
01816       struct ast_channel *ast;
01817       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01818          char *passdata;
01819          int vmlen = strlen(emailsubject)*3 + 200;
01820          if ((passdata = alloca(vmlen))) {
01821             memset(passdata, 0, vmlen);
01822             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01823             pbx_substitute_variables_helper(ast, emailsubject, passdata, vmlen);
01824             fprintf(p, "Subject: %s" ENDL, passdata);
01825          } else
01826             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01827          ast_channel_free(ast);
01828       } else
01829          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01830    } else   if (*emailtitle) {
01831       fprintf(p, emailtitle, msgnum + 1, mailbox) ;
01832       fprintf(p, ENDL) ;
01833    } else if (ast_test_flag((&globalflags), VM_PBXSKIP))
01834       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
01835    else
01836       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
01837    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
01838    if(imap) {
01839       /* additional information needed for IMAP searching */
01840       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
01841       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
01842       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
01843       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
01844       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
01845       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
01846       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
01847       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, cidnum);
01848       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, cidname);
01849       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
01850       if (!ast_strlen_zero(category))
01851          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
01852       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
01853       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
01854    }
01855    if (!ast_strlen_zero(cidnum))
01856       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, cidnum);
01857    if (!ast_strlen_zero(cidname))
01858       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, cidname);
01859    fprintf(p, "MIME-Version: 1.0" ENDL);
01860    if (attach_user_voicemail) {
01861       /* Something unique. */
01862       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
01863 
01864       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
01865       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
01866       fprintf(p, "--%s" ENDL, bound);
01867    }
01868    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
01869    if (emailbody) {
01870       struct ast_channel *ast;
01871       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01872          char *passdata;
01873          int vmlen = strlen(emailbody)*3 + 200;
01874          if ((passdata = alloca(vmlen))) {
01875             memset(passdata, 0, vmlen);
01876             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01877             pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
01878             fprintf(p, "%s" ENDL, passdata);
01879          } else
01880             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01881          ast_channel_free(ast);
01882       } else
01883          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01884    } else {
01885       fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a %s long message (number %d)" ENDL
01886 
01887       "in mailbox %s from %s, on %s so you might" ENDL
01888       "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, 
01889       dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
01890    }
01891    if (attach_user_voicemail) {
01892       /* Eww. We want formats to tell us their own MIME type */
01893       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
01894       char tmpdir[256], newtmp[256];
01895       int tmpfd = -1;
01896    
01897       if (vmu->volgain < -.001 || vmu->volgain > .001) {
01898          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
01899          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
01900          tmpfd = mkstemp(newtmp);
01901          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
01902          if (option_debug > 2)
01903             ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
01904          if (tmpfd > -1) {
01905             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
01906             ast_safe_system(tmpcmd);
01907             attach = newtmp;
01908             if (option_debug > 2)
01909                ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
01910          }
01911       }
01912       fprintf(p, "--%s" ENDL, bound);
01913       fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
01914       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
01915       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
01916       fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
01917       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
01918       base_encode(fname, p);
01919       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
01920       if (tmpfd > -1) {
01921          unlink(fname);
01922          close(tmpfd);
01923          unlink(newtmp);
01924       }
01925    }
01926 #undef ENDL
01927 }

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

Definition at line 891 of file app_voicemail.c.

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

00892 {
00893    return snprintf(dest, len, "%s/msg%04d", dir, num);
00894 }

static const char* mbox ( int  id  )  [static]

Definition at line 2096 of file app_voicemail.c.

Referenced by adsi_load_vmail(), copy_message(), get_folder(), has_voicemail(), leave_voicemail(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().

02097 {
02098    static const char *msgs[] = {
02099       "INBOX",
02100       "Old",
02101       "Work",
02102       "Family",
02103       "Friends",
02104       "Cust1",
02105       "Cust2",
02106       "Cust3",
02107       "Cust4",
02108       "Cust5",
02109    };
02110    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown";
02111 }

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

Definition at line 2553 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

02554 {
02555    return __has_voicemail(context, mailbox, folder, 0);
02556 }

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 3793 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, LOG_WARNING, 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, strsep(), VM_ATTACH, and VM_DELETE.

Referenced by copy_message(), and leave_voicemail().

03794 {
03795    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
03796    int newmsgs = 0, oldmsgs = 0;
03797    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
03798 
03799    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
03800    make_file(fn, sizeof(fn), todir, msgnum);
03801    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
03802 
03803    if (!ast_strlen_zero(vmu->attachfmt)) {
03804       if (strstr(fmt, vmu->attachfmt)) {
03805          fmt = vmu->attachfmt;
03806       } else {
03807          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);
03808       }
03809    }
03810 
03811    /* Attach only the first format */
03812    fmt = ast_strdupa(fmt);
03813    stringp = fmt;
03814    strsep(&stringp, "|");
03815 
03816    if (!ast_strlen_zero(vmu->email)) {
03817       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03818       char *myserveremail = serveremail;
03819       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
03820       if (!ast_strlen_zero(vmu->serveremail))
03821          myserveremail = vmu->serveremail;
03822       
03823       if (attach_user_voicemail)
03824          RETRIEVE(todir, msgnum);
03825 
03826       /*XXX possible imap issue, should category be NULL XXX*/
03827       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
03828 
03829       if (attach_user_voicemail)
03830          DISPOSE(todir, msgnum);
03831    }
03832 
03833    if (!ast_strlen_zero(vmu->pager)) {
03834       char *myserveremail = serveremail;
03835       if (!ast_strlen_zero(vmu->serveremail))
03836          myserveremail = vmu->serveremail;
03837       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
03838    }
03839 
03840    if (ast_test_flag(vmu, VM_DELETE)) {
03841       DELETE(todir, msgnum, fn);
03842    }
03843 
03844 #ifdef IMAP_STORAGE
03845    DELETE(todir, msgnum, fn);
03846 #endif
03847    /* Leave voicemail for someone */
03848    if (ast_app_has_voicemail(ext_context, NULL)) {
03849       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
03850    }
03851    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);
03852    run_externnotify(vmu->context, vmu->mailbox);
03853    return 0;
03854 }

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

Definition at line 1601 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

01602 {
01603    if (bio->linelength>=BASELINELEN) {
01604       if (fputs(eol,so)==EOF)
01605          return -1;
01606 
01607       bio->linelength= 0;
01608    }
01609 
01610    if (putc(((unsigned char)c),so)==EOF)
01611       return -1;
01612 
01613    bio->linelength++;
01614 
01615    return 1;
01616 }

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

Definition at line 4687 of file app_voicemail.c.

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

Referenced by vm_execmain().

04688 {
04689    int res = 0;
04690    int count_msg, last_msg;
04691 
04692    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
04693    
04694    /* Rename the member vmbox HERE so that we don't try to return before
04695     * we know what's going on.
04696     */
04697    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
04698    
04699    /* Faster to make the directory than to check if it exists. */
04700    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
04701 
04702    count_msg = count_messages(vmu, vms->curdir);
04703    if (count_msg < 0)
04704       return count_msg;
04705    else
04706       vms->lastmsg = count_msg - 1;
04707 
04708    /*
04709    The following test is needed in case sequencing gets messed up.
04710    There appears to be more than one way to mess up sequence, so
04711    we will not try to find all of the root causes--just fix it when
04712    detected.
04713    */
04714 
04715    last_msg = last_message_index(vmu, vms->curdir);
04716    if (last_msg < 0)
04717       return last_msg;
04718    else if (vms->lastmsg != last_msg)
04719    {
04720       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
04721       res = resequence_mailbox(vmu, vms->curdir);
04722       if (res)
04723          return res;
04724    }
04725 
04726    return 0;
04727 }

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

Definition at line 4456 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, vm_state::lastmsg, LOG_WARNING, 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_es(), vm_browse_messages_gr(), vm_browse_messages_it(), vm_browse_messages_pt(), and vm_execmain().

04457 {
04458    int res = 0;
04459    char filename[256], *cid;
04460    const char *origtime, *context, *category, *duration;
04461    struct ast_config *msg_cfg;
04462 
04463    vms->starting = 0; 
04464    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04465    adsi_message(chan, vms);
04466    if (!vms->curmsg)
04467       res = wait_file2(chan, vms, "vm-first");  /* "First" */
04468    else if (vms->curmsg == vms->lastmsg)
04469       res = wait_file2(chan, vms, "vm-last");      /* "last" */
04470    if (!res) {
04471       /* POLISH syntax */
04472       if (!strcasecmp(chan->language, "pl")) { 
04473          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04474             int ten, one;
04475             char nextmsg[256];
04476             ten = (vms->curmsg + 1) / 10;
04477             one = (vms->curmsg + 1) % 10;
04478             
04479             if (vms->curmsg < 20) {
04480                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
04481                res = wait_file2(chan, vms, nextmsg);
04482             } else {
04483                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
04484                res = wait_file2(chan, vms, nextmsg);
04485                if (one > 0) {
04486                   if (!res) {
04487                      snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
04488                      res = wait_file2(chan, vms, nextmsg);
04489                   }
04490                }
04491             }
04492          }
04493          if (!res)
04494             res = wait_file2(chan, vms, "vm-message");
04495       } else {
04496          if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
04497             res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
04498          else /* DEFAULT syntax */
04499             res = wait_file2(chan, vms, "vm-message");
04500          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04501             if (!res)
04502                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
04503          }
04504       }
04505    }
04506 
04507    /* Retrieve info from VM attribute file */
04508    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
04509    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
04510    RETRIEVE(vms->curdir, vms->curmsg);
04511    msg_cfg = ast_config_load(filename);
04512    if (!msg_cfg) {
04513       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
04514       return 0;
04515    }
04516 
04517    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
04518       ast_log(LOG_WARNING, "No origtime?!\n");
04519       DISPOSE(vms->curdir, vms->curmsg);
04520       ast_config_destroy(msg_cfg);
04521       return 0;
04522    }
04523 
04524    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
04525    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
04526    category = ast_variable_retrieve(msg_cfg, "message", "category");
04527 
04528    context = ast_variable_retrieve(msg_cfg, "message", "context");
04529    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
04530       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
04531    if (!res)
04532       res = play_message_category(chan, category);
04533    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
04534       res = play_message_datetime(chan, vmu, origtime, filename);
04535    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
04536       res = play_message_callerid(chan, vms, cid, context, 0);
04537    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
04538       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
04539    /* Allow pressing '1' to skip envelope / callerid */
04540    if (res == '1')
04541       res = 0;
04542    ast_config_destroy(msg_cfg);
04543 
04544    if (!res) {
04545       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04546       vms->heard[vms->curmsg] = 1;
04547       res = wait_file(chan, vms, vms->fn);
04548    }
04549    DISPOSE(vms->curdir, vms->curmsg);
04550    return res;
04551 }

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

Definition at line 4204 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(), cidinternalcontexts, LOG_DEBUG, MAX_NUM_CID_CONTEXTS, name, option_debug, option_verbose, VERBOSE_PREFIX_3, VM_SPOOL_DIR, and wait_file2().

Referenced by advanced_options(), and play_message().

04205 {
04206    int res = 0;
04207    int i;
04208    char *callerid, *name;
04209    char prefile[PATH_MAX] = "";
04210    
04211 
04212    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
04213    /* 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 */
04214    if ((cid == NULL)||(context == NULL))
04215       return res;
04216 
04217    /* Strip off caller ID number from name */
04218    if (option_debug > 2)
04219       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
04220    ast_callerid_parse(cid, &name, &callerid);
04221    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
04222       /* Check for internal contexts and only */
04223       /* say extension when the call didn't come from an internal context in the list */
04224       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
04225          if (option_debug > 2)
04226             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
04227          if ((strcmp(cidinternalcontexts[i], context) == 0))
04228             break;
04229       }
04230       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
04231          if (!res) {
04232             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
04233             if (!ast_strlen_zero(prefile)) {
04234             /* See if we can find a recorded name for this person instead of their extension number */
04235                if (ast_fileexists(prefile, NULL, NULL) > 0) {
04236                   if (option_verbose > 2)
04237                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
04238                   if (!callback)
04239                      res = wait_file2(chan, vms, "vm-from");
04240                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
04241                } else {
04242                   if (option_verbose > 2)
04243                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
04244                   /* BB: Say "from extension" as one saying to sound smoother */
04245                   if (!callback)
04246                      res = wait_file2(chan, vms, "vm-from-extension");
04247                   res = ast_say_digit_str(chan, callerid, "", chan->language);
04248                }
04249             }
04250          }
04251       }
04252 
04253       else if (!res){
04254          if (option_debug > 2)
04255             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
04256          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
04257          if (!callback)
04258             res = wait_file2(chan, vms, "vm-from-phonenumber");
04259          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
04260       }
04261    } else {
04262       /* Number unknown */
04263       if (option_debug)
04264          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
04265       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
04266       res = wait_file2(chan, vms, "vm-unknown-caller");
04267    }
04268    return res;
04269 }

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

Definition at line 4119 of file app_voicemail.c.

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

Referenced by play_message().

04120 {
04121    int res = 0;
04122 
04123    if (!ast_strlen_zero(category))
04124       res = ast_play_and_wait(chan, category);
04125 
04126    if (res) {
04127       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
04128       res = 0;
04129    }
04130 
04131    return res;
04132 }

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

Definition at line 4134 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(), LOG_WARNING, pbx_builtin_setvar_helper(), t, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

04135 {
04136    int res = 0;
04137    struct vm_zone *the_zone = NULL;
04138    time_t t;
04139 
04140    if (ast_get_time_t(origtime, &t, 0, NULL)) {
04141       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
04142       return 0;
04143    }
04144 
04145    /* Does this user have a timezone specified? */
04146    if (!ast_strlen_zero(vmu->zonetag)) {
04147       /* Find the zone in the list */
04148       struct vm_zone *z;
04149       AST_LIST_LOCK(&zones);
04150       AST_LIST_TRAVERSE(&zones, z, list) {
04151          if (!strcmp(z->name, vmu->zonetag)) {
04152             the_zone = z;
04153             break;
04154          }
04155       }
04156       AST_LIST_UNLOCK(&zones);
04157    }
04158 
04159 /* No internal variable parsing for now, so we'll comment it out for the time being */
04160 #if 0
04161    /* Set the DIFF_* variables */
04162    ast_localtime(&t, &time_now, NULL);
04163    tv_now = ast_tvnow();
04164    tnow = tv_now.tv_sec;
04165    ast_localtime(&tnow, &time_then, NULL);
04166 
04167    /* Day difference */
04168    if (time_now.tm_year == time_then.tm_year)
04169       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
04170    else
04171       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
04172    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
04173 
04174    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
04175 #endif
04176    if (the_zone)
04177       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
04178    else if (!strcasecmp(chan->language,"pl"))       /* POLISH syntax */
04179       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
04180    else if (!strcasecmp(chan->language,"se"))       /* SWEDISH syntax */
04181       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
04182    else if (!strcasecmp(chan->language,"no"))       /* NORWEGIAN syntax */
04183       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04184    else if (!strcasecmp(chan->language,"de"))       /* GERMAN syntax */
04185       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04186    else if (!strcasecmp(chan->language,"nl"))      /* DUTCH syntax */
04187       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
04188    else if (!strcasecmp(chan->language,"it"))      /* ITALIAN syntax */
04189       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);
04190    else if (!strcasecmp(chan->language,"gr"))
04191       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
04192    else if (!strcasecmp(chan->language,"pt_BR"))
04193       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);      
04194    else
04195       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
04196 #if 0
04197    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
04198 #endif
04199    return res;
04200 }

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

Definition at line 4271 of file app_voicemail.c.

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

Referenced by play_message().

04272 {
04273    int res = 0;
04274    int durationm;
04275    int durations;
04276    /* Verify that we have a duration for the message */
04277    if (duration == NULL)
04278       return res;
04279 
04280    /* Convert from seconds to minutes */
04281    durations=atoi(duration);
04282    durationm=(durations / 60);
04283 
04284    if (option_debug > 2)
04285       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
04286 
04287    if ((!res) && (durationm >= minduration)) {
04288       res = wait_file2(chan, vms, "vm-duration");
04289 
04290       /* POLISH syntax */
04291       if (!strcasecmp(chan->language, "pl")) {
04292          div_t num = div(durationm, 10);
04293 
04294          if (durationm == 1) {
04295             res = ast_play_and_wait(chan, "digits/1z");
04296             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
04297          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
04298             if (num.rem == 2) {
04299                if (!num.quot) {
04300                   res = ast_play_and_wait(chan, "digits/2-ie");
04301                } else {
04302                   res = say_and_wait(chan, durationm - 2 , chan->language);
04303                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
04304                }
04305             } else {
04306                res = say_and_wait(chan, durationm, chan->language);
04307             }
04308             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
04309          } else {
04310             res = say_and_wait(chan, durationm, chan->language);
04311             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
04312          }
04313       /* DEFAULT syntax */
04314       } else {
04315          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
04316          res = wait_file2(chan, vms, "vm-minutes");
04317       }
04318    }
04319    return res;
04320 }

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 7988 of file app_voicemail.c.

References ast_channel_setoption(), 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, LOG_WARNING, ast_vm_user::mailbox, maxsilence, option_verbose, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.

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

07991 {
07992    /* Record message & let caller review or re-record it, or set options if applicable */
07993    int res = 0;
07994    int cmd = 0;
07995    int max_attempts = 3;
07996    int attempts = 0;
07997    int recorded = 0;
07998    int message_exists = 0;
07999    signed char zero_gain = 0;
08000    char tempfile[PATH_MAX];
08001    char *acceptdtmf = "#";
08002    char *canceldtmf = "";
08003 
08004    /* Note that urgent and private are for flagging messages as such in the future */
08005 
08006    /* barf if no pointer passed to store duration in */
08007    if (duration == NULL) {
08008       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
08009       return -1;
08010    }
08011 
08012    if (!outsidecaller)
08013       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
08014    else
08015       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
08016 
08017    cmd = '3';  /* Want to start by recording */
08018 
08019    while ((cmd >= 0) && (cmd != 't')) {
08020       switch (cmd) {
08021       case '1':
08022          if (!message_exists) {
08023             /* In this case, 1 is to record a message */
08024             cmd = '3';
08025             break;
08026          } else {
08027             /* Otherwise 1 is to save the existing message */
08028             if (option_verbose > 2)
08029                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
08030             if (!outsidecaller)
08031                ast_filerename(tempfile, recordfile, NULL);
08032             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
08033             if (!outsidecaller) {
08034                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
08035                DISPOSE(recordfile, -1);
08036             }
08037             cmd = 't';
08038             return res;
08039          }
08040       case '2':
08041          /* Review */
08042          if (option_verbose > 2)
08043             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
08044          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
08045          break;
08046       case '3':
08047          message_exists = 0;
08048          /* Record */
08049          if (recorded == 1) {
08050             if (option_verbose > 2)
08051                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
08052          } else { 
08053             if (option_verbose > 2)
08054                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
08055          }
08056          if (recorded && outsidecaller) {
08057             cmd = ast_play_and_wait(chan, INTRO);
08058             cmd = ast_play_and_wait(chan, "beep");
08059          }
08060          recorded = 1;
08061          /* 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 */
08062          if (record_gain)
08063             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
08064          if (ast_test_flag(vmu, VM_OPERATOR))
08065             canceldtmf = "0";
08066          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
08067          if (record_gain)
08068             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
08069          if (cmd == -1) {
08070             /* User has hung up, no options to give */
08071             if (!outsidecaller) {
08072                /* user was recording a greeting and they hung up, so let's delete the recording. */
08073                ast_filedelete(tempfile, NULL);
08074             }
08075             return cmd;
08076          }
08077          if (cmd == '0') {
08078             break;
08079          } else if (cmd == '*') {
08080             break;
08081          } 
08082 #if 0       
08083          else if (vmu->review && (*duration < 5)) {
08084             /* Message is too short */
08085             if (option_verbose > 2)
08086                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
08087             cmd = ast_play_and_wait(chan, "vm-tooshort");
08088             cmd = ast_filedelete(tempfile, NULL);
08089             break;
08090          }
08091          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
08092             /* Message is all silence */
08093             if (option_verbose > 2)
08094                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
08095             cmd = ast_filedelete(tempfile, NULL);
08096             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
08097             if (!cmd)
08098                cmd = ast_play_and_wait(chan, "vm-speakup");
08099             break;
08100          }
08101 #endif
08102          else {
08103             /* If all is well, a message exists */
08104             message_exists = 1;
08105             cmd = 0;
08106          }
08107          break;
08108       case '4':
08109       case '5':
08110       case '6':
08111       case '7':
08112       case '8':
08113       case '9':
08114       case '*':
08115       case '#':
08116          cmd = ast_play_and_wait(chan, "vm-sorry");
08117          break;
08118 #if 0 
08119 /*  XXX Commented out for the moment because of the dangers of deleting
08120     a message while recording (can put the message numbers out of sync) */
08121       case '*':
08122          /* Cancel recording, delete message, offer to take another message*/
08123          cmd = ast_play_and_wait(chan, "vm-deleted");
08124          cmd = ast_filedelete(tempfile, NULL);
08125          if (outsidecaller) {
08126             res = vm_exec(chan, NULL);
08127             return res;
08128          }
08129          else
08130             return 1;
08131 #endif
08132       case '0':
08133          if (!ast_test_flag(vmu, VM_OPERATOR)) {
08134             cmd = ast_play_and_wait(chan, "vm-sorry");
08135             break;
08136          }
08137          if (message_exists || recorded) {
08138             cmd = ast_play_and_wait(chan, "vm-saveoper");
08139             if (!cmd)
08140                cmd = ast_waitfordigit(chan, 3000);
08141             if (cmd == '1') {
08142                ast_play_and_wait(chan, "vm-msgsaved");
08143                cmd = '0';
08144             } else {
08145                ast_play_and_wait(chan, "vm-deleted");
08146                DELETE(recordfile, -1, recordfile);
08147                cmd = '0';
08148             }
08149          }
08150          return cmd;
08151       default:
08152          /* If the caller is an ouside caller, and the review option is enabled,
08153             allow them to review the message, but let the owner of the box review
08154             their OGM's */
08155          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
08156             return cmd;
08157          if (message_exists) {
08158             cmd = ast_play_and_wait(chan, "vm-review");
08159          }
08160          else {
08161             cmd = ast_play_and_wait(chan, "vm-torerecord");
08162             if (!cmd)
08163                cmd = ast_waitfordigit(chan, 600);
08164          }
08165          
08166          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
08167             cmd = ast_play_and_wait(chan, "vm-reachoper");
08168             if (!cmd)
08169                cmd = ast_waitfordigit(chan, 600);
08170          }
08171 #if 0
08172          if (!cmd)
08173             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
08174 #endif
08175          if (!cmd)
08176             cmd = ast_waitfordigit(chan, 6000);
08177          if (!cmd) {
08178             attempts++;
08179          }
08180          if (attempts > max_attempts) {
08181             cmd = 't';
08182          }
08183       }
08184    }
08185    if (outsidecaller)
08186       ast_play_and_wait(chan, "vm-goodbye");
08187    if (cmd == 't')
08188       cmd = 0;
08189    return cmd;
08190 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 553 of file app_voicemail.c.

References ast_copy_flags, AST_FLAGS_ALL, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::exit, exitcontext, globalflags, ast_vm_user::maxmsg, ast_vm_user::saydurationm, saydurationminfo, and ast_vm_user::volgain.

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

00554 {
00555    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00556    if (saydurationminfo)
00557       vmu->saydurationm = saydurationminfo;
00558    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00559    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00560    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00561    if (maxmsg)
00562       vmu->maxmsg = maxmsg;
00563    vmu->volgain = volgain;
00564 }

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 1690 of file app_voicemail.c.

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

Referenced by make_email_file(), and sendpage().

01691 {
01692    char callerid[256];
01693    /* Prepare variables for substition in email body and subject */
01694    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
01695    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
01696    snprintf(passdata, passdatasize, "%d", msgnum);
01697    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
01698    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
01699    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
01700    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
01701    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
01702    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
01703    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
01704    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
01705 }

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

Definition at line 1707 of file app_voicemail.c.

01708 {
01709    char *ptr = to;
01710    *ptr++ = '"';
01711    for (; ptr < to + len - 1; from++) {
01712       if (*from == '"')
01713          *ptr++ = '\\';
01714       else if (*from == '\0')
01715          break;
01716       *ptr++ = *from;
01717    }
01718    if (ptr < to + len - 1)
01719       *ptr++ = '"';
01720    *ptr = '\0';
01721    return to;
01722 }

static int reload ( void   )  [static]

Definition at line 7637 of file app_voicemail.c.

References load_config().

07638 {
07639    return(load_config());
07640 }

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

Definition at line 1460 of file app_voicemail.c.

References ast_filerename().

01461 {
01462    char stxt[PATH_MAX];
01463    char dtxt[PATH_MAX];
01464    ast_filerename(sfn,dfn,NULL);
01465    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
01466    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
01467    rename(stxt, dtxt);
01468 }

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

Definition at line 3087 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().

03088 {
03089    /* we know max messages, so stop process when number is hit */
03090 
03091    int x,dest;
03092    char sfn[PATH_MAX];
03093    char dfn[PATH_MAX];
03094 
03095    if (vm_lock_path(dir))
03096       return ERROR_LOCK_PATH;
03097 
03098    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
03099       make_file(sfn, sizeof(sfn), dir, x);
03100       if (EXISTS(dir, x, sfn, NULL)) {
03101          
03102          if (x != dest) {
03103             make_file(dfn, sizeof(dfn), dir, dest);
03104             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
03105          }
03106          
03107          dest++;
03108       }
03109    }
03110    ast_unlock_path(dir);
03111 
03112    return 0;
03113 }

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

Definition at line 752 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, ast_vm_user::mailbox, and ast_vm_user::password.

Referenced by vm_change_password().

00753 {
00754    /* This function could be made to generate one from a database, too */
00755    struct ast_vm_user *cur;
00756    int res = -1;
00757    AST_LIST_LOCK(&users);
00758    AST_LIST_TRAVERSE(&users, cur, list) {
00759       if ((!context || !strcasecmp(context, cur->context)) &&
00760          (!strcasecmp(mailbox, cur->mailbox)))
00761             break;
00762    }
00763    if (cur) {
00764       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00765       res = 0;
00766    }
00767    AST_LIST_UNLOCK(&users);
00768    return res;
00769 }

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

Definition at line 2654 of file app_voicemail.c.

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

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

02655 {
02656    char arguments[255];
02657    char ext_context[256] = "";
02658    int newvoicemails = 0, oldvoicemails = 0;
02659    struct ast_smdi_mwi_message *mwi_msg;
02660 
02661    if (!ast_strlen_zero(context))
02662       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
02663    else
02664       ast_copy_string(ext_context, extension, sizeof(ext_context));
02665 
02666    if (!strcasecmp(externnotify, "smdi")) {
02667       if (ast_app_has_voicemail(ext_context, NULL)) 
02668          ast_smdi_mwi_set(smdi_iface, extension);
02669       else
02670          ast_smdi_mwi_unset(smdi_iface, extension);
02671 
02672       if ((mwi_msg = ast_smdi_mwi_message_wait(smdi_iface, SMDI_MWI_WAIT_TIMEOUT))) {
02673          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s on %s\n", extension, smdi_iface->name);
02674          if (!strncmp(mwi_msg->cause, "INV", 3))
02675             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
02676          else if (!strncmp(mwi_msg->cause, "BLK", 3))
02677             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
02678          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
02679          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
02680       } else {
02681          if (option_debug)
02682             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s on %s\n", extension, smdi_iface->name);
02683       }
02684    } else if (!ast_strlen_zero(externnotify)) {
02685       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
02686          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
02687       } else {
02688          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
02689          if (option_debug)
02690             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
02691          ast_safe_system(arguments);
02692       }
02693    }
02694 }

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

Definition at line 3123 of file app_voicemail.c.

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

Referenced by close_mailbox(), and vm_execmain().

03124 {
03125 #ifdef IMAP_STORAGE
03126    /* we must use mbox(x) folder names, and copy the message there */
03127    /* simple. huh? */
03128    char dbox[256];
03129    long res;
03130    char sequence[10];
03131 
03132    /* if save to Old folder, just leave in INBOX */
03133    if (box == 1) return 10;
03134    /* get the real IMAP message number for this message */
03135    sprintf(sequence,"%ld",vms->msgArray[msg]);
03136    imap_mailbox_name(dbox, vms, box, 1);
03137    if(option_debug > 2)
03138       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,dbox);
03139    res = mail_copy(vms->mailstream,sequence,dbox);
03140    if (res == 1) return 0;
03141    return 1;
03142 #else
03143    char *dir = vms->curdir;
03144    char *username = vms->username;
03145    char *context = vmu->context;
03146    char sfn[PATH_MAX];
03147    char dfn[PATH_MAX];
03148    char ddir[PATH_MAX];
03149    const char *dbox = mbox(box);
03150    int x;
03151    make_file(sfn, sizeof(sfn), dir, msg);
03152    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
03153 
03154    if (vm_lock_path(ddir))
03155       return ERROR_LOCK_PATH;
03156 
03157    for (x = 0; x < vmu->maxmsg; x++) {
03158       make_file(dfn, sizeof(dfn), ddir, x);
03159       if (!EXISTS(ddir, x, dfn, NULL))
03160          break;
03161    }
03162    if (x >= vmu->maxmsg) {
03163       ast_unlock_path(ddir);
03164       return -1;
03165    }
03166    if (strcmp(sfn, dfn)) {
03167       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
03168    }
03169    ast_unlock_path(ddir);
03170 #endif
03171    return 0;
03172 }

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

Definition at line 3116 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(), vm_intro_ru(), and vm_intro_se().

03117 {
03118    int d;
03119    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
03120    return d;
03121 }

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 1928 of file app_voicemail.c.

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

Referenced by forward_message(), and notify_new_message().

01929 {
01930    FILE *p=NULL;
01931    char tmp[80] = "/tmp/astmail-XXXXXX";
01932    char tmp2[256];
01933 
01934    if (vmu && ast_strlen_zero(vmu->email)) {
01935       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
01936       return(0);
01937    }
01938    if (!strcmp(format, "wav49"))
01939       format = "WAV";
01940    if (option_debug > 2)
01941       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));
01942    /* Make a temporary file instead of piping directly to sendmail, in case the mail
01943       command hangs */
01944    if ((p = vm_mkftemp(tmp)) == NULL) {
01945       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
01946       return -1;
01947    } else {
01948       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
01949       fclose(p);
01950       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01951       ast_safe_system(tmp2);
01952       if (option_debug > 2)
01953          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
01954    }
01955    return 0;
01956 }

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 1958 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_safe_system(), AST_STATE_DOWN, fromstring, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailcmd, option_debug, pagerbody, pagerfromstring, pagersubject, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().

Referenced by notify_new_message().

01959 {
01960    char date[256];
01961    char host[MAXHOSTNAMELEN] = "";
01962    char who[256];
01963    char dur[PATH_MAX];
01964    char tmp[80] = "/tmp/astmail-XXXXXX";
01965    char tmp2[PATH_MAX];
01966    struct tm tm;
01967    FILE *p;
01968 
01969    if ((p = vm_mkftemp(tmp)) == NULL) {
01970       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
01971       return -1;
01972    } else {
01973       gethostname(host, sizeof(host)-1);
01974       if (strchr(srcemail, '@'))
01975          ast_copy_string(who, srcemail, sizeof(who));
01976       else {
01977          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
01978       }
01979       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
01980       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
01981       fprintf(p, "Date: %s\n", date);
01982 
01983       if (*pagerfromstring) {
01984          struct ast_channel *ast;
01985          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
01986             char *passdata;
01987             int vmlen = strlen(fromstring)*3 + 200;
01988             if ((passdata = alloca(vmlen))) {
01989                memset(passdata, 0, vmlen);
01990                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
01991                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
01992                fprintf(p, "From: %s <%s>\n", passdata, who);
01993             } else 
01994                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
01995             ast_channel_free(ast);
01996          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
01997       } else
01998          fprintf(p, "From: Asterisk PBX <%s>\n", who);
01999       fprintf(p, "To: %s\n", pager);
02000       if (pagersubject) {
02001          struct ast_channel *ast;
02002          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
02003             char *passdata;
02004             int vmlen = strlen(pagersubject) * 3 + 200;
02005             if ((passdata = alloca(vmlen))) {
02006                memset(passdata, 0, vmlen);
02007                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
02008                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
02009                fprintf(p, "Subject: %s\n\n", passdata);
02010             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
02011             ast_channel_free(ast);
02012          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
02013       } else
02014          fprintf(p, "Subject: New VM\n\n");
02015       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
02016       if (pagerbody) {
02017          struct ast_channel *ast;
02018          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
02019             char *passdata;
02020             int vmlen = strlen(pagerbody)*3 + 200;
02021             if ((passdata = alloca(vmlen))) {
02022                memset(passdata, 0, vmlen);
02023                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
02024                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
02025                fprintf(p, "%s\n", passdata);
02026             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
02027          ast_channel_free(ast);
02028          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
02029       } else {
02030          fprintf(p, "New %s long msg in box %s\n"
02031                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
02032       }
02033       fclose(p);
02034       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
02035       ast_safe_system(tmp2);
02036       if (option_debug > 2)
02037          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
02038    }
02039    return 0;
02040 }

static int unload_module ( void   )  [static]

Definition at line 7642 of file app_voicemail.c.

References app, app2, app3, app4, ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_uninstall_vm_functions(), ast_unregister_application(), and cli_voicemail.

07643 {
07644    int res;
07645    
07646    res = ast_unregister_application(app);
07647    res |= ast_unregister_application(app2);
07648    res |= ast_unregister_application(app3);
07649    res |= ast_unregister_application(app4);
07650    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
07651    ast_uninstall_vm_functions();
07652    
07653    ast_module_user_hangup_all();
07654 
07655    return res;
07656 }

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 6075 of file app_voicemail.c.

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

Referenced by vm_execmain(), and vmauthenticate().

06078 {
06079    int useadsi=0, valid=0, logretries=0;
06080    char password[AST_MAX_EXTENSION]="", *passptr;
06081    struct ast_vm_user vmus, *vmu = NULL;
06082 
06083    /* If ADSI is supported, setup login screen */
06084    adsi_begin(chan, &useadsi);
06085    if (!skipuser && useadsi)
06086       adsi_login(chan);
06087    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
06088       ast_log(LOG_WARNING, "Couldn't stream login file\n");
06089       return -1;
06090    }
06091    
06092    /* Authenticate them and get their mailbox/password */
06093    
06094    while (!valid && (logretries < maxlogins)) {
06095       /* Prompt for, and read in the username */
06096       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
06097          ast_log(LOG_WARNING, "Couldn't read username\n");
06098          return -1;
06099       }
06100       if (ast_strlen_zero(mailbox)) {
06101          if (chan->cid.cid_num) {
06102             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
06103          } else {
06104             if (option_verbose > 2)
06105                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
06106             return -1;
06107          }
06108       }
06109       if (useadsi)
06110          adsi_password(chan);
06111 
06112       if (!ast_strlen_zero(prefix)) {
06113          char fullusername[80] = "";
06114          ast_copy_string(fullusername, prefix, sizeof(fullusername));
06115          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
06116          ast_copy_string(mailbox, fullusername, mailbox_size);
06117       }
06118 
06119       if (option_debug)
06120          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
06121       vmu = find_user(&vmus, context, mailbox);
06122       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
06123          /* saved password is blank, so don't bother asking */
06124          password[0] = '\0';
06125       } else {
06126          if (ast_streamfile(chan, "vm-password", chan->language)) {
06127             ast_log(LOG_WARNING, "Unable to stream password file\n");
06128             return -1;
06129          }
06130          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
06131             ast_log(LOG_WARNING, "Unable to read password\n");
06132             return -1;
06133          }
06134       }
06135 
06136       if (vmu) {
06137          passptr = vmu->password;
06138          if (passptr[0] == '-') passptr++;
06139       }
06140       if (vmu && !strcmp(passptr, password))
06141          valid++;
06142       else {
06143          if (option_verbose > 2)
06144             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
06145          if (!ast_strlen_zero(prefix))
06146             mailbox[0] = '\0';
06147       }
06148       logretries++;
06149       if (!valid) {
06150          if (skipuser || logretries >= maxlogins) {
06151             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
06152                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
06153                return -1;
06154             }
06155          } else {
06156             if (useadsi)
06157                adsi_login(chan);
06158             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
06159                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
06160                return -1;
06161             }
06162          }
06163          if (ast_waitstream(chan, "")) /* Channel is hung up */
06164             return -1;
06165       }
06166    }
06167    if (!valid && (logretries >= maxlogins)) {
06168       ast_stopstream(chan);
06169       ast_play_and_wait(chan, "vm-goodbye");
06170       return -1;
06171    }
06172    if (vmu && !skipuser) {
06173       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
06174    }
06175    return 0;
06176 }

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

Definition at line 6885 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, ast_channel::exten, find_user(), LOG_ERROR, LOG_WARNING, mbox(), pbx_builtin_setvar_helper(), and ast_channel::priority.

Referenced by load_module().

06886 {
06887    struct ast_module_user *u;
06888    struct ast_vm_user svm;
06889    char *context, *box;
06890    int priority_jump = 0;
06891    AST_DECLARE_APP_ARGS(args,
06892       AST_APP_ARG(mbox);
06893       AST_APP_ARG(options);
06894    );
06895 
06896    if (ast_strlen_zero(data)) {
06897       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
06898       return -1;
06899    }
06900 
06901    u = ast_module_user_add(chan);
06902 
06903    box = ast_strdupa(data);
06904 
06905    AST_STANDARD_APP_ARGS(args, box);
06906 
06907    if (args.options) {
06908       if (strchr(args.options, 'j'))
06909          priority_jump = 1;
06910    }
06911 
06912    if ((context = strchr(args.mbox, '@'))) {
06913       *context = '\0';
06914       context++;
06915    }
06916 
06917    if (find_user(&svm, context, args.mbox)) {
06918       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
06919       if (priority_jump || ast_opt_priority_jumping)
06920          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
06921             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);
06922    } else
06923       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
06924    ast_module_user_remove(u);
06925    return 0;
06926 }

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

Definition at line 6060 of file app_voicemail.c.

References vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_it(), and vm_browse_messages_pt().

Referenced by vm_execmain().

06061 {
06062    if (!strcasecmp(chan->language, "es")) {  /* SPANISH */
06063       return vm_browse_messages_es(chan, vms, vmu);
06064    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
06065       return vm_browse_messages_it(chan, vms, vmu);
06066    } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {   /* PORTUGUESE */
06067       return vm_browse_messages_pt(chan, vms, vmu);
06068    } else if (!strcasecmp(chan->language, "gr")){
06069       return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
06070    } else { /* Default to English syntax */
06071       return vm_browse_messages_en(chan, vms, vmu);
06072    }
06073 }

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

Definition at line 5983 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().

05984 {
05985    int cmd=0;
05986 
05987    if (vms->lastmsg > -1) {
05988       cmd = play_message(chan, vmu, vms);
05989    } else {
05990       cmd = ast_play_and_wait(chan, "vm-youhave");
05991       if (!cmd) 
05992          cmd = ast_play_and_wait(chan, "vm-no");
05993       if (!cmd) {
05994          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
05995          cmd = ast_play_and_wait(chan, vms->fn);
05996       }
05997       if (!cmd)
05998          cmd = ast_play_and_wait(chan, "vm-messages");
05999    }
06000    return cmd;
06001 }

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

Definition at line 6023 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().

06024 {
06025    int cmd=0;
06026 
06027    if (vms->lastmsg > -1) {
06028       cmd = play_message(chan, vmu, vms);
06029    } else {
06030       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06031       if (!cmd)
06032          cmd = ast_play_and_wait(chan, "vm-messages");
06033       if (!cmd) {
06034          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06035          cmd = ast_play_and_wait(chan, vms->fn);
06036       }
06037    }
06038    return cmd;
06039 }

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

Definition at line 5955 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().

05956 {
05957    int cmd=0;
05958 
05959    if (vms->lastmsg > -1) {
05960       cmd = play_message(chan, vmu, vms);
05961    } else {
05962       cmd = ast_play_and_wait(chan, "vm-youhaveno");
05963       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
05964          if (!cmd) {
05965             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
05966             cmd = ast_play_and_wait(chan, vms->fn);
05967          }
05968          if (!cmd)
05969             cmd = ast_play_and_wait(chan, "vm-messages");
05970       } else {
05971          if (!cmd)
05972             cmd = ast_play_and_wait(chan, "vm-messages");
05973          if (!cmd) {
05974             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
05975             cmd = ast_play_and_wait(chan, vms->fn);
05976          }
05977       }
05978    } 
05979    return cmd;
05980 }

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

Definition at line 6004 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().

06005 {
06006    int cmd=0;
06007 
06008    if (vms->lastmsg > -1) {
06009       cmd = play_message(chan, vmu, vms);
06010    } else {
06011       cmd = ast_play_and_wait(chan, "vm-no");
06012       if (!cmd)
06013          cmd = ast_play_and_wait(chan, "vm-message");
06014       if (!cmd) {
06015          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06016          cmd = ast_play_and_wait(chan, vms->fn);
06017       }
06018    }
06019    return cmd;
06020 }

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

Definition at line 6042 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().

06043 {
06044    int cmd=0;
06045 
06046    if (vms->lastmsg > -1) {
06047       cmd = play_message(chan, vmu, vms);
06048    } else {
06049       cmd = ast_play_and_wait(chan, "vm-no");
06050       if (!cmd) {
06051          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06052          cmd = ast_play_and_wait(chan, vms->fn);
06053       }
06054       if (!cmd)
06055          cmd = ast_play_and_wait(chan, "vm-messages");
06056    }
06057    return cmd;
06058 }

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

Definition at line 771 of file app_voicemail.c.

References ast_category_browse(), ast_category_get(), ast_config_load_with_comments(), 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().

00772 {
00773    struct ast_config   *cfg=NULL;
00774    struct ast_variable *var=NULL;
00775    struct ast_category *cat=NULL;
00776    char *category=NULL, *value=NULL, *new=NULL;
00777    const char *tmp=NULL;
00778                
00779    if (!change_password_realtime(vmu, newpassword))
00780       return;
00781 
00782    /* check voicemail.conf */
00783    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00784       while ((category = ast_category_browse(cfg, category))) {
00785          if (!strcasecmp(category, vmu->context)) {
00786             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00787             if (!tmp) {
00788                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00789                break;
00790             }
00791             value = strstr(tmp,",");
00792             if (!value) {
00793                ast_log(LOG_WARNING, "variable has bad format.\n");
00794                break;
00795             }
00796             new = alloca((strlen(value)+strlen(newpassword)+1));
00797             sprintf(new,"%s%s", newpassword, value);
00798             if (!(cat = ast_category_get(cfg, category))) {
00799                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00800                break;
00801             }
00802             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00803          }
00804       }
00805       /* save the results */
00806       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00807       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00808       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00809    }
00810    category = NULL;
00811    var = NULL;
00812    /* check users.conf and update the password stored for the mailbox*/
00813    /* if no vmsecret entry exists create one. */
00814    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00815       if (option_debug > 3)
00816          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00817       while ((category = ast_category_browse(cfg, category))) {
00818          if (option_debug > 3)
00819             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00820          if (!strcasecmp(category, vmu->mailbox)) {
00821             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00822                if (option_debug > 3)
00823                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00824                var = ast_variable_new("vmsecret", newpassword);
00825             } 
00826             new = alloca(strlen(newpassword)+1);
00827             sprintf(new, "%s", newpassword);
00828             if (!(cat = ast_category_get(cfg, category))) {
00829                if (option_debug > 3)
00830                   ast_log(LOG_DEBUG, "failed to get category!\n");
00831                break;
00832             }
00833             if (!var)      
00834                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00835             else
00836                ast_variable_append(cat, var);
00837          }
00838       }
00839       /* save the results and clean things up */
00840       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00841       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00842       config_text_file_save("users.conf", cfg, "AppVoicemail");
00843    }
00844 }

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

Definition at line 846 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00847 {
00848    char buf[255];
00849    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00850    if (!ast_safe_system(buf))
00851       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00852 }

static int vm_delete ( char *  file  )  [static]

Definition at line 1554 of file app_voicemail.c.

References ast_filedelete().

01555 {
01556    char *txt;
01557    int txtsize = 0;
01558 
01559    txtsize = (strlen(file) + 5)*sizeof(char);
01560    txt = alloca(txtsize);
01561    /* Sprintf here would safe because we alloca'd exactly the right length,
01562     * but trying to eliminate all sprintf's anyhow
01563     */
01564    snprintf(txt, txtsize, "%s.txt", file);
01565    unlink(txt);
01566    return ast_filedelete(file, NULL);
01567 }

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

Definition at line 6738 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, ast_channel::context, ERROR_LOCK_PATH, ast_channel::exten, leave_voicemail(), LOG_ERROR, LOG_WARNING, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_PRIORITY_JUMP, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), ast_channel::priority, and leave_vm_options::record_gain.

Referenced by load_module(), and play_record_review().

06739 {
06740    int res = 0;
06741    struct ast_module_user *u;
06742    char *tmp;
06743    struct leave_vm_options leave_options;
06744    struct ast_flags flags = { 0 };
06745    static int deprecate_warning = 0;
06746    char *opts[OPT_ARG_ARRAY_SIZE];
06747    AST_DECLARE_APP_ARGS(args,
06748       AST_APP_ARG(argv0);
06749       AST_APP_ARG(argv1);
06750    );
06751 
06752    u = ast_module_user_add(chan);
06753    
06754    memset(&leave_options, 0, sizeof(leave_options));
06755 
06756    if (chan->_state != AST_STATE_UP)
06757       ast_answer(chan);
06758 
06759    if (!ast_strlen_zero(data)) {
06760       tmp = ast_strdupa(data);
06761       AST_STANDARD_APP_ARGS(args, tmp);
06762       if (args.argc == 2) {
06763          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
06764             ast_module_user_remove(u);
06765             return -1;
06766          }
06767          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
06768          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
06769             int gain;
06770 
06771             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
06772                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
06773                ast_module_user_remove(u);
06774                return -1;
06775             } else {
06776                leave_options.record_gain = (signed char) gain;
06777             }
06778          }
06779       } else {
06780          /* old style options parsing */
06781          int old = 0;
06782          char *orig_argv0 = args.argv0;
06783          while (*(args.argv0)) {
06784             if (*(args.argv0) == 's') {
06785                old = 1;
06786                ast_set_flag(&leave_options, OPT_SILENT);
06787             } else if (*(args.argv0) == 'b') {
06788                old = 1;
06789                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
06790             } else if (*(args.argv0) == 'u') {
06791                old = 1;
06792                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
06793             } else if (*(args.argv0) == 'j') {
06794                old = 1;
06795                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
06796             } else
06797                break;
06798             (args.argv0)++;
06799          }
06800          if (!deprecate_warning && old) {
06801             deprecate_warning = 1;
06802             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
06803             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
06804          }
06805       }
06806    } else {
06807       char tmp[256];
06808       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
06809       if (res < 0) {
06810          ast_module_user_remove(u);
06811          return res;
06812       }
06813       if (ast_strlen_zero(tmp)) {
06814          ast_module_user_remove(u);
06815          return 0;
06816       }
06817       args.argv0 = ast_strdupa(tmp);
06818    }
06819 
06820    res = leave_voicemail(chan, args.argv0, &leave_options);
06821 
06822    if (res == ERROR_LOCK_PATH) {
06823       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
06824       /*Send the call to n+101 priority, where n is the current priority*/
06825       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
06826          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
06827             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
06828       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
06829       res = 0;
06830    }
06831    
06832    ast_module_user_remove(u);
06833 
06834    return res;
06835 }

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

Definition at line 6178 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_DECLARE_APP_ARGS, ast_log(), ast_module_user_add, ast_module_user_remove, 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(), vm_state::curdir, vm_state::curmsg, vm_state::deleted, ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), vm_state::fn, forward_message(), free, free_user(), get_folder2(), globalflags, has_voicemail(), vm_state::heard, ast_vm_user::language, vm_state::lastmsg, LOG_DEBUG, LOG_WARNING, ast_vm_user::mailbox, make_file(), manager_event(), maxlogins, ast_vm_user::maxmsg, mbox(), vm_state::newmessages, vm_state::oldmessages, 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(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::username, VERBOSE_PREFIX_3, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, vm_state::vmbox, and vmfmts.

Referenced by load_module().

06179 {
06180    /* XXX This is, admittedly, some pretty horrendus code.  For some
06181       reason it just seemed a lot easier to do with GOTO's.  I feel
06182       like I'm back in my GWBASIC days. XXX */
06183    int res=-1;
06184    int cmd=0;
06185    int valid = 0;
06186    struct ast_module_user *u;
06187    char prefixstr[80] ="";
06188    char ext_context[256]="";
06189    int box;
06190    int useadsi = 0;
06191    int skipuser = 0;
06192    struct vm_state vms;
06193    struct ast_vm_user *vmu = NULL, vmus;
06194    char *context=NULL;
06195    int silentexit = 0;
06196    struct ast_flags flags = { 0 };
06197    signed char record_gain = 0;
06198    int play_auto = 0;
06199    int play_folder = 0;
06200 #ifdef IMAP_STORAGE
06201    int deleted = 0;
06202 #endif
06203    u = ast_module_user_add(chan);
06204 
06205    /* Add the vm_state to the active list and keep it active */
06206    memset(&vms, 0, sizeof(vms));
06207    vms.lastmsg = -1;
06208 
06209    memset(&vmus, 0, sizeof(vmus));
06210 
06211    if (chan->_state != AST_STATE_UP) {
06212       if (option_debug)
06213          ast_log(LOG_DEBUG, "Before ast_answer\n");
06214       ast_answer(chan);
06215    }
06216 
06217    if (!ast_strlen_zero(data)) {
06218       char *opts[OPT_ARG_ARRAY_SIZE];
06219       char *parse;
06220       AST_DECLARE_APP_ARGS(args,
06221          AST_APP_ARG(argv0);
06222          AST_APP_ARG(argv1);
06223       );
06224 
06225       parse = ast_strdupa(data);
06226 
06227       AST_STANDARD_APP_ARGS(args, parse);
06228 
06229       if (args.argc == 2) {
06230          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
06231             ast_module_user_remove(u);
06232             return -1;
06233          }
06234          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
06235             int gain;
06236             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
06237                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
06238                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
06239                   ast_module_user_remove(u);
06240                   return -1;
06241                } else {
06242                   record_gain = (signed char) gain;
06243                }
06244             } else {
06245                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
06246             }
06247          }
06248          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
06249             play_auto = 1;
06250             if (opts[OPT_ARG_PLAYFOLDER]) {
06251                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
06252                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
06253                }
06254             } else {
06255                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
06256             }  
06257             if ( play_folder > 9 || play_folder < 0) {
06258                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
06259                play_folder = 0;
06260             }
06261          }
06262       } else {
06263          /* old style options parsing */
06264          while (*(args.argv0)) {
06265             if (*(args.argv0) == 's')
06266                ast_set_flag(&flags, OPT_SILENT);
06267             else if (*(args.argv0) == 'p')
06268                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
06269             else 
06270                break;
06271             (args.argv0)++;
06272          }
06273 
06274       }
06275 
06276       valid = ast_test_flag(&flags, OPT_SILENT);
06277 
06278       if ((context = strchr(args.argv0, '@')))
06279          *context++ = '\0';
06280 
06281       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
06282          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
06283       else
06284          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
06285 
06286       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
06287          skipuser++;
06288       else
06289          valid = 0;
06290    }
06291 
06292    if (!valid)
06293       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
06294 
06295    if (option_debug)
06296       ast_log(LOG_DEBUG, "After vm_authenticate\n");
06297    if (!res) {
06298       valid = 1;
06299       if (!skipuser)
06300          vmu = &vmus;
06301    } else {
06302       res = 0;
06303    }
06304 
06305    /* If ADSI is supported, setup login screen */
06306    adsi_begin(chan, &useadsi);
06307 
06308 #ifdef IMAP_STORAGE
06309    vms.interactive = 1;
06310    vms.updated = 1;
06311    vmstate_insert(&vms);
06312    init_vm_state(&vms);
06313 #endif
06314    if (!valid)
06315       goto out;
06316 
06317    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
06318       /* TODO: Handle memory allocation failure */
06319    }
06320    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
06321       /* TODO: Handle memory allocation failure */
06322    }
06323    
06324    /* Set language from config to override channel language */
06325    if (!ast_strlen_zero(vmu->language))
06326       ast_string_field_set(chan, language, vmu->language);
06327 #ifndef IMAP_STORAGE
06328    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
06329 #endif
06330    /* Retrieve old and new message counts */
06331    if (option_debug)
06332       ast_log(LOG_DEBUG, "Before open_mailbox\n");
06333    res = open_mailbox(&vms, vmu, 1);
06334    if (res == ERROR_LOCK_PATH)
06335       goto out;
06336    vms.oldmessages = vms.lastmsg + 1;
06337    if (option_debug > 2)
06338       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
06339    /* Start in INBOX */
06340    res = open_mailbox(&vms, vmu, 0);
06341    if (res == ERROR_LOCK_PATH)
06342       goto out;
06343    vms.newmessages = vms.lastmsg + 1;
06344    if (option_debug > 2)
06345       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
06346       
06347    /* Select proper mailbox FIRST!! */
06348    if (play_auto) {
06349       res = open_mailbox(&vms, vmu, play_folder);
06350       if (res == ERROR_LOCK_PATH)
06351          goto out;
06352 
06353       /* If there are no new messages, inform the user and hangup */
06354       if (vms.lastmsg == -1) {
06355          cmd = vm_browse_messages(chan, &vms, vmu);
06356          res = 0;
06357          goto out;
06358       }
06359    } else {
06360       if (!vms.newmessages && vms.oldmessages) {
06361          /* If we only have old messages start here */
06362          res = open_mailbox(&vms, vmu, 1);
06363          play_folder = 1;
06364          if (res == ERROR_LOCK_PATH)
06365             goto out;
06366       }
06367    }
06368 
06369    if (useadsi)
06370       adsi_status(chan, &vms);
06371    res = 0;
06372 
06373    /* Check to see if this is a new user */
06374    if (!strcasecmp(vmu->mailbox, vmu->password) && 
06375       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
06376       if (ast_play_and_wait(chan, "vm-newuser") == -1)
06377          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
06378       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
06379       if ((cmd == 't') || (cmd == '#')) {
06380          /* Timeout */
06381          res = 0;
06382          goto out;
06383       } else if (cmd < 0) {
06384          /* Hangup */
06385          res = -1;
06386          goto out;
06387       }
06388    }
06389 #ifdef IMAP_STORAGE
06390       if(option_debug > 2)
06391          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
06392       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
06393          if (option_debug)
06394             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
06395          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06396       }
06397 #endif
06398    if (play_auto) {
06399       cmd = '1';
06400    } else {
06401       cmd = vm_intro(chan, vmu, &vms);
06402    }
06403 
06404    vms.repeats = 0;
06405    vms.starting = 1;
06406    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
06407       /* Run main menu */
06408       switch (cmd) {
06409       case '1':
06410          vms.curmsg = 0;
06411          /* Fall through */
06412       case '5':
06413          cmd = vm_browse_messages(chan, &vms, vmu);
06414          break;
06415       case '2': /* Change folders */
06416          if (useadsi)
06417             adsi_folders(chan, 0, "Change to folder...");
06418          cmd = get_folder2(chan, "vm-changeto", 0);
06419          if (cmd == '#') {
06420             cmd = 0;
06421          } else if (cmd > 0) {
06422             cmd = cmd - '0';
06423             res = close_mailbox(&vms, vmu);
06424             if (res == ERROR_LOCK_PATH)
06425                goto out;
06426             res = open_mailbox(&vms, vmu, cmd);
06427             if (res == ERROR_LOCK_PATH)
06428                goto out;
06429             play_folder = cmd;
06430             cmd = 0;
06431          }
06432          if (useadsi)
06433             adsi_status2(chan, &vms);
06434             
06435          if (!cmd)
06436             cmd = vm_play_folder_name(chan, vms.vmbox);
06437 
06438          vms.starting = 1;
06439          break;
06440       case '3': /* Advanced options */
06441          cmd = 0;
06442          vms.repeats = 0;
06443          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
06444             switch (cmd) {
06445             case '1': /* Reply */
06446                if (vms.lastmsg > -1 && !vms.starting) {
06447                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
06448                   if (cmd == ERROR_LOCK_PATH) {
06449                      res = cmd;
06450                      goto out;
06451                   }
06452                } else
06453                   cmd = ast_play_and_wait(chan, "vm-sorry");
06454                cmd = 't';
06455                break;
06456             case '2': /* Callback */
06457                if (option_verbose > 2 && !vms.starting)
06458                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
06459                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
06460                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
06461                   if (cmd == 9) {
06462                      silentexit = 1;
06463                      goto out;
06464                   } else if (cmd == ERROR_LOCK_PATH) {
06465                      res = cmd;
06466                      goto out;
06467                   }
06468                }
06469                else 
06470                   cmd = ast_play_and_wait(chan, "vm-sorry");
06471                cmd = 't';
06472                break;
06473             case '3': /* Envelope */
06474                if (vms.lastmsg > -1 && !vms.starting) {
06475                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
06476                   if (cmd == ERROR_LOCK_PATH) {
06477                      res = cmd;
06478                      goto out;
06479                   }
06480                } else
06481                   cmd = ast_play_and_wait(chan, "vm-sorry");
06482                cmd = 't';
06483                break;
06484             case '4': /* Dialout */
06485                if (!ast_strlen_zero(vmu->dialout)) {
06486                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
06487                   if (cmd == 9) {
06488                      silentexit = 1;
06489                      goto out;
06490                   }
06491                }
06492                else 
06493                   cmd = ast_play_and_wait(chan, "vm-sorry");
06494                cmd = 't';
06495                break;
06496 
06497             case '5': /* Leave VoiceMail */
06498                if (ast_test_flag(vmu, VM_SVMAIL)) {
06499                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
06500                   if (cmd == ERROR_LOCK_PATH) {
06501                      res = cmd;
06502                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
06503                      goto out;
06504                   }
06505                } else
06506                   cmd = ast_play_and_wait(chan,"vm-sorry");
06507                cmd='t';
06508                break;
06509                
06510             case '*': /* Return to main menu */
06511                cmd = 't';
06512                break;
06513 
06514             default:
06515                cmd = 0;
06516                if (!vms.starting) {
06517                   cmd = ast_play_and_wait(chan, "vm-toreply");
06518                }
06519                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
06520                   cmd = ast_play_and_wait(chan, "vm-tocallback");
06521                }
06522                if (!cmd && !vms.starting) {
06523                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
06524                }
06525                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
06526                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
06527                }
06528                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
06529                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
06530                if (!cmd)
06531                   cmd = ast_play_and_wait(chan, "vm-starmain");
06532                if (!cmd)
06533                   cmd = ast_waitfordigit(chan,6000);
06534                if (!cmd)
06535                   vms.repeats++;
06536                if (vms.repeats > 3)
06537                   cmd = 't';
06538             }
06539          }
06540          if (cmd == 't') {
06541             cmd = 0;
06542             vms.repeats = 0;
06543          }
06544          break;
06545       case '4':
06546          if (vms.curmsg > 0) {
06547             vms.curmsg--;
06548             cmd = play_message(chan, vmu, &vms);
06549          } else {
06550             cmd = ast_play_and_wait(chan, "vm-nomore");
06551          }
06552          break;
06553       case '6':
06554          if (vms.curmsg < vms.lastmsg) {
06555             vms.curmsg++;
06556             cmd = play_message(chan, vmu, &vms);
06557          } else {
06558             cmd = ast_play_and_wait(chan, "vm-nomore");
06559          }
06560          break;
06561       case '7':
06562          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
06563             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
06564             if (useadsi)
06565                adsi_delete(chan, &vms);
06566             if (vms.deleted[vms.curmsg]) {
06567                if (play_folder == 0)
06568                   vms.newmessages--;
06569                else if (play_folder == 1)
06570                   vms.oldmessages--;
06571                cmd = ast_play_and_wait(chan, "vm-deleted");
06572             }
06573             else {
06574                if (play_folder == 0)
06575                   vms.newmessages++;
06576                else if (play_folder == 1)
06577                   vms.oldmessages++;
06578                cmd = ast_play_and_wait(chan, "vm-undeleted");
06579             }
06580             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
06581                if (vms.curmsg < vms.lastmsg) {
06582                   vms.curmsg++;
06583                   cmd = play_message(chan, vmu, &vms);
06584                } else {
06585                   cmd = ast_play_and_wait(chan, "vm-nomore");
06586                }
06587             }
06588          } else /* Delete not valid if we haven't selected a message */
06589             cmd = 0;
06590 #ifdef IMAP_STORAGE
06591          deleted = 1;
06592 #endif
06593          break;
06594    
06595       case '8':
06596          if (vms.lastmsg > -1) {
06597             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
06598             if (cmd == ERROR_LOCK_PATH) {
06599                res = cmd;
06600                goto out;
06601             }
06602          } else
06603             cmd = ast_play_and_wait(chan, "vm-nomore");
06604          break;
06605       case '9':
06606          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
06607             /* No message selected */
06608             cmd = 0;
06609             break;
06610          }
06611          if (useadsi)
06612             adsi_folders(chan, 1, "Save to folder...");
06613          cmd = get_folder2(chan, "vm-savefolder", 1);
06614          box = 0; /* Shut up compiler */
06615          if (cmd == '#') {
06616             cmd = 0;
06617             break;
06618          } else if (cmd > 0) {
06619             box = cmd = cmd - '0';
06620             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
06621             if (cmd == ERROR_LOCK_PATH) {
06622                res = cmd;
06623                goto out;
06624 #ifdef IMAP_STORAGE
06625             } else if (cmd == 10) {
06626                goto out;
06627 #endif
06628             } else if (!cmd) {
06629                vms.deleted[vms.curmsg] = 1;
06630             } else {
06631                vms.deleted[vms.curmsg] = 0;
06632                vms.heard[vms.curmsg] = 0;
06633             }
06634          }
06635          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
06636          if (useadsi)
06637             adsi_message(chan, &vms);
06638          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
06639          if (!cmd) {
06640             cmd = ast_play_and_wait(chan, "vm-message");
06641             if (!cmd)
06642                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
06643             if (!cmd)
06644                cmd = ast_play_and_wait(chan, "vm-savedto");
06645             if (!cmd)
06646                cmd = vm_play_folder_name(chan, vms.fn);
06647          } else {
06648             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06649          }
06650          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
06651             if (vms.curmsg < vms.lastmsg) {
06652                vms.curmsg++;
06653                cmd = play_message(chan, vmu, &vms);
06654             } else {
06655                cmd = ast_play_and_wait(chan, "vm-nomore");
06656             }
06657          }
06658          break;
06659       case '*':
06660          if (!vms.starting) {
06661             cmd = ast_play_and_wait(chan, "vm-onefor");
06662             if (!cmd)
06663                cmd = vm_play_folder_name(chan, vms.vmbox);
06664             if (!cmd)
06665                cmd = ast_play_and_wait(chan, "vm-opts");
06666             if (!cmd)
06667                cmd = vm_instructions(chan, &vms, 1);
06668          } else
06669             cmd = 0;
06670          break;
06671       case '0':
06672          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
06673          if (useadsi)
06674             adsi_status(chan, &vms);
06675          break;
06676       default: /* Nothing */
06677          cmd = vm_instructions(chan, &vms, 0);
06678          break;
06679       }
06680    }
06681    if ((cmd == 't') || (cmd == '#')) {
06682       /* Timeout */
06683       res = 0;
06684    } else {
06685       /* Hangup */
06686       res = -1;
06687    }
06688 
06689 out:
06690    if (res > -1) {
06691       ast_stopstream(chan);
06692       adsi_goodbye(chan);
06693       if (valid) {
06694          if (silentexit)
06695             res = ast_play_and_wait(chan, "vm-dialout");
06696          else 
06697             res = ast_play_and_wait(chan, "vm-goodbye");
06698          if (res > 0)
06699             res = 0;
06700       }
06701       if (useadsi)
06702          ast_adsi_unload_session(chan);
06703    }
06704    if (vmu)
06705       close_mailbox(&vms, vmu);
06706    if (valid) {
06707       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
06708       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
06709       run_externnotify(vmu->context, vmu->mailbox);
06710    }
06711 #ifdef IMAP_STORAGE
06712    /* expunge message - use UID Expunge if supported on IMAP server*/
06713    if(option_debug > 2)
06714       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
06715    if (vmu && deleted == 1 && expungeonhangup == 1) {
06716 #ifdef HAVE_IMAP_TK2006
06717       if (LEVELUIDPLUS (vms.mailstream)) {
06718          mail_expunge_full(vms.mailstream,NIL,EX_UID);
06719       } else 
06720 #endif
06721          mail_expunge(vms.mailstream);
06722    }
06723    /*  before we delete the state, we should copy pertinent info
06724     *  back to the persistent model */
06725    vmstate_delete(&vms);
06726 #endif
06727    if (vmu)
06728       free_user(vmu);
06729    if (vms.deleted)
06730       free(vms.deleted);
06731    if (vms.heard)
06732       free(vms.heard);
06733    ast_module_user_remove(u);
06734 
06735    return res;
06736 }

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 3708 of file app_voicemail.c.

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), config_text_file_save(), ast_vm_user::mailbox, make_file(), maxsilence, silencethreshold, and STORE.

Referenced by forward_message().

03710 {
03711    int cmd = 0;
03712    int retries = 0;
03713    signed char zero_gain = 0;
03714 
03715    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
03716       if (cmd)
03717          retries = 0;
03718       switch (cmd) {
03719       case '1': 
03720          /* prepend a message to the current message, update the metadata and return */
03721       {
03722          char msgfile[PATH_MAX];
03723          char textfile[PATH_MAX];
03724          int prepend_duration = 0;
03725          struct ast_config *msg_cfg;
03726          const char *duration_str;
03727 
03728          make_file(msgfile, sizeof(msgfile), curdir, curmsg);
03729          strcpy(textfile, msgfile);
03730          strncat(textfile, ".txt", sizeof(textfile) - 1);
03731          *duration = 0;
03732 
03733          /* if we can't read the message metadata, stop now */
03734          if (!(msg_cfg = ast_config_load(textfile))) {
03735             cmd = 0;
03736             break;
03737          }
03738 
03739          if (record_gain)
03740             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
03741 
03742          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
03743          if (record_gain)
03744             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
03745 
03746          
03747          if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
03748             *duration = atoi(duration_str);
03749 
03750          if (prepend_duration) {
03751             struct ast_category *msg_cat;
03752             /* need enough space for a maximum-length message duration */
03753             char duration_str[12];
03754 
03755             *duration += prepend_duration;
03756             msg_cat = ast_category_get(msg_cfg, "message");
03757             snprintf(duration_str, 11, "%ld", *duration);
03758             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
03759                config_text_file_save(textfile, msg_cfg, "app_voicemail");
03760                STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, *duration, vms);
03761             }
03762          }
03763 
03764          ast_config_destroy(msg_cfg);
03765 
03766          break;
03767       }
03768       case '2': 
03769          cmd = 't';
03770          break;
03771       case '*':
03772          cmd = '*';
03773          break;
03774       default: 
03775          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
03776             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
03777          if (!cmd)
03778             cmd = ast_play_and_wait(chan,"vm-starmain");
03779             /* "press star to return to the main menu" */
03780          if (!cmd)
03781             cmd = ast_waitfordigit(chan,6000);
03782          if (!cmd)
03783             retries++;
03784          if (retries > 3)
03785             cmd = 't';
03786       }
03787    }
03788    if (cmd == 't' || cmd == 'S')
03789       cmd = 0;
03790    return cmd;
03791 }

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

Definition at line 5626 of file app_voicemail.c.

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

Referenced by vm_execmain().

05627 {
05628    int res = 0;
05629    /* Play instructions and wait for new command */
05630    while (!res) {
05631       if (vms->starting) {
05632          if (vms->lastmsg > -1) {
05633             res = ast_play_and_wait(chan, "vm-onefor");
05634             if (!res)
05635                res = vm_play_folder_name(chan, vms->vmbox);
05636          }
05637          if (!res)
05638             res = ast_play_and_wait(chan, "vm-opts");
05639       } else {
05640          if (vms->curmsg)
05641             res = ast_play_and_wait(chan, "vm-prev");
05642          if (!res && !skipadvanced)
05643             res = ast_play_and_wait(chan, "vm-advopts");
05644          if (!res)
05645             res = ast_play_and_wait(chan, "vm-repeat");
05646          if (!res && (vms->curmsg != vms->lastmsg))
05647             res = ast_play_and_wait(chan, "vm-next");
05648          if (!res) {
05649             if (!vms->deleted[vms->curmsg])
05650                res = ast_play_and_wait(chan, "vm-delete");
05651             else
05652                res = ast_play_and_wait(chan, "vm-undelete");
05653             if (!res)
05654                res = ast_play_and_wait(chan, "vm-toforward");
05655             if (!res)
05656                res = ast_play_and_wait(chan, "vm-savemessage");
05657          }
05658       }
05659       if (!res)
05660          res = ast_play_and_wait(chan, "vm-helpexit");
05661       if (!res)
05662          res = ast_waitfordigit(chan, 6000);
05663       if (!res) {
05664          vms->repeats++;
05665          if (vms->repeats > 2) {
05666             res = 't';
05667          }
05668       }
05669    }
05670    return res;
05671 }

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

Definition at line 5583 of file app_voicemail.c.

References ast_fileexists(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, vm_state::username, vm_intro_cz(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_ru(), vm_intro_se(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.

Referenced by vm_execmain().

05584 {
05585    char prefile[256];
05586    
05587    /* Notify the user that the temp greeting is set and give them the option to remove it */
05588    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
05589    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
05590       if (ast_fileexists(prefile, NULL, NULL) > 0)
05591          ast_play_and_wait(chan, "vm-tempgreetactive");
05592    }
05593 
05594    /* Play voicemail intro - syntax is different for different languages */
05595    if (!strcasecmp(chan->language, "de")) {  /* GERMAN syntax */
05596       return vm_intro_de(chan, vms);
05597    } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
05598       return vm_intro_es(chan, vms);
05599    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
05600       return vm_intro_it(chan, vms);
05601    } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
05602       return vm_intro_fr(chan, vms);
05603    } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
05604       return vm_intro_nl(chan, vms);
05605    } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
05606       return vm_intro_pt(chan, vms);
05607    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
05608       return vm_intro_pt_BR(chan, vms);      
05609    } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
05610       return vm_intro_cz(chan, vms);
05611    } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
05612       return vm_intro_gr(chan, vms);
05613    } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */
05614       return vm_intro_pl(chan, vms);
05615    } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
05616       return vm_intro_se(chan, vms);
05617    } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
05618       return vm_intro_no(chan, vms);
05619    } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */
05620       return vm_intro_ru(chan, vms);
05621    } else {             /* Default to ENGLISH */
05622       return vm_intro_en(chan, vms);
05623    }
05624 }

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

Definition at line 5450 of file app_voicemail.c.

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

Referenced by vm_intro().

05451 {
05452    int res;
05453    res = ast_play_and_wait(chan, "vm-youhave");
05454    if (!res) {
05455       if (vms->newmessages) {
05456          if (vms->newmessages == 1) {
05457             res = ast_play_and_wait(chan, "digits/jednu");
05458          } else {
05459             res = say_and_wait(chan, vms->newmessages, chan->language);
05460          }
05461          if (!res) {
05462             if ((vms->newmessages == 1))
05463                res = ast_play_and_wait(chan, "vm-novou");
05464             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05465                res = ast_play_and_wait(chan, "vm-nove");
05466             if (vms->newmessages > 4)
05467                res = ast_play_and_wait(chan, "vm-novych");
05468          }
05469          if (vms->oldmessages && !res)
05470             res = ast_play_and_wait(chan, "vm-and");
05471          else if (!res) {
05472             if ((vms->newmessages == 1))
05473                res = ast_play_and_wait(chan, "vm-zpravu");
05474             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05475                res = ast_play_and_wait(chan, "vm-zpravy");
05476             if (vms->newmessages > 4)
05477                res = ast_play_and_wait(chan, "vm-zprav");
05478          }
05479       }
05480       if (!res && vms->oldmessages) {
05481          res = say_and_wait(chan, vms->oldmessages, chan->language);
05482          if (!res) {
05483             if ((vms->oldmessages == 1))
05484                res = ast_play_and_wait(chan, "vm-starou");
05485             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05486                res = ast_play_and_wait(chan, "vm-stare");
05487             if (vms->oldmessages > 4)
05488                res = ast_play_and_wait(chan, "vm-starych");
05489          }
05490          if (!res) {
05491             if ((vms->oldmessages == 1))
05492                res = ast_play_and_wait(chan, "vm-zpravu");
05493             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05494                res = ast_play_and_wait(chan, "vm-zpravy");
05495             if (vms->oldmessages > 4)
05496                res = ast_play_and_wait(chan, "vm-zprav");
05497          }
05498       }
05499       if (!res) {
05500          if (!vms->oldmessages && !vms->newmessages) {
05501             res = ast_play_and_wait(chan, "vm-no");
05502             if (!res)
05503                res = ast_play_and_wait(chan, "vm-zpravy");
05504          }
05505       }
05506    }
05507    return res;
05508 }

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

Definition at line 5143 of file app_voicemail.c.

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

Referenced by vm_intro().

05144 {
05145    /* Introduce messages they have */
05146    int res;
05147    res = ast_play_and_wait(chan, "vm-youhave");
05148    if (!res) {
05149       if (vms->newmessages) {
05150          if ((vms->newmessages == 1))
05151             res = ast_play_and_wait(chan, "digits/1F");
05152          else
05153             res = say_and_wait(chan, vms->newmessages, chan->language);
05154          if (!res)
05155             res = ast_play_and_wait(chan, "vm-INBOX");
05156          if (vms->oldmessages && !res)
05157             res = ast_play_and_wait(chan, "vm-and");
05158          else if (!res) {
05159             if ((vms->newmessages == 1))
05160                res = ast_play_and_wait(chan, "vm-message");
05161             else
05162                res = ast_play_and_wait(chan, "vm-messages");
05163          }
05164             
05165       }
05166       if (!res && vms->oldmessages) {
05167          if (vms->oldmessages == 1)
05168             res = ast_play_and_wait(chan, "digits/1F");
05169          else
05170             res = say_and_wait(chan, vms->oldmessages, chan->language);
05171          if (!res)
05172             res = ast_play_and_wait(chan, "vm-Old");
05173          if (!res) {
05174             if (vms->oldmessages == 1)
05175                res = ast_play_and_wait(chan, "vm-message");
05176             else
05177                res = ast_play_and_wait(chan, "vm-messages");
05178          }
05179       }
05180       if (!res) {
05181          if (!vms->oldmessages && !vms->newmessages) {
05182             res = ast_play_and_wait(chan, "vm-no");
05183             if (!res)
05184                res = ast_play_and_wait(chan, "vm-messages");
05185          }
05186       }
05187    }
05188    return res;
05189 }

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

Definition at line 4905 of file app_voicemail.c.

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

Referenced by vm_intro().

04906 {
04907    int res;
04908 
04909    /* Introduce messages they have */
04910    res = ast_play_and_wait(chan, "vm-youhave");
04911    if (!res) {
04912       if (vms->newmessages) {
04913          res = say_and_wait(chan, vms->newmessages, chan->language);
04914          if (!res)
04915             res = ast_play_and_wait(chan, "vm-INBOX");
04916          if (vms->oldmessages && !res)
04917             res = ast_play_and_wait(chan, "vm-and");
04918          else if (!res) {
04919             if ((vms->newmessages == 1))
04920                res = ast_play_and_wait(chan, "vm-message");
04921             else
04922                res = ast_play_and_wait(chan, "vm-messages");
04923          }
04924             
04925       }
04926       if (!res && vms->oldmessages) {
04927          res = say_and_wait(chan, vms->oldmessages, chan->language);
04928          if (!res)
04929             res = ast_play_and_wait(chan, "vm-Old");
04930          if (!res) {
04931             if (vms->oldmessages == 1)
04932                res = ast_play_and_wait(chan, "vm-message");
04933             else
04934                res = ast_play_and_wait(chan, "vm-messages");
04935          }
04936       }
04937       if (!res) {
04938          if (!vms->oldmessages && !vms->newmessages) {
04939             res = ast_play_and_wait(chan, "vm-no");
04940             if (!res)
04941                res = ast_play_and_wait(chan, "vm-messages");
04942          }
04943       }
04944    }
04945    return res;
04946 }

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

Definition at line 5192 of file app_voicemail.c.

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

Referenced by vm_intro().

05193 {
05194    /* Introduce messages they have */
05195    int res;
05196    if (!vms->oldmessages && !vms->newmessages) {
05197       res = ast_play_and_wait(chan, "vm-youhaveno");
05198       if (!res)
05199          res = ast_play_and_wait(chan, "vm-messages");
05200    } else {
05201       res = ast_play_and_wait(chan, "vm-youhave");
05202    }
05203    if (!res) {
05204       if (vms->newmessages) {
05205          if (!res) {
05206             if ((vms->newmessages == 1)) {
05207                res = ast_play_and_wait(chan, "digits/1M");
05208                if (!res)
05209                   res = ast_play_and_wait(chan, "vm-message");
05210                if (!res)
05211                   res = ast_play_and_wait(chan, "vm-INBOXs");
05212             } else {
05213                res = say_and_wait(chan, vms->newmessages, chan->language);
05214                if (!res)
05215                   res = ast_play_and_wait(chan, "vm-messages");
05216                if (!res)
05217                   res = ast_play_and_wait(chan, "vm-INBOX");
05218             }
05219          }
05220          if (vms->oldmessages && !res)
05221             res = ast_play_and_wait(chan, "vm-and");
05222       }
05223       if (vms->oldmessages) {
05224          if (!res) {
05225             if (vms->oldmessages == 1) {
05226                res = ast_play_and_wait(chan, "digits/1M");
05227                if (!res)
05228                   res = ast_play_and_wait(chan, "vm-message");
05229                if (!res)
05230                   res = ast_play_and_wait(chan, "vm-Olds");
05231             } else {
05232                res = say_and_wait(chan, vms->oldmessages, chan->language);
05233                if (!res)
05234                   res = ast_play_and_wait(chan, "vm-messages");
05235                if (!res)
05236                   res = ast_play_and_wait(chan, "vm-Old");
05237             }
05238          }
05239       }
05240    }
05241 return res;
05242 }

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

Definition at line 5293 of file app_voicemail.c.

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

Referenced by vm_intro().

05294 {
05295    /* Introduce messages they have */
05296    int res;
05297    res = ast_play_and_wait(chan, "vm-youhave");
05298    if (!res) {
05299       if (vms->newmessages) {
05300          res = say_and_wait(chan, vms->newmessages, chan->language);
05301          if (!res)
05302             res = ast_play_and_wait(chan, "vm-INBOX");
05303          if (vms->oldmessages && !res)
05304             res = ast_play_and_wait(chan, "vm-and");
05305          else if (!res) {
05306             if ((vms->newmessages == 1))
05307                res = ast_play_and_wait(chan, "vm-message");
05308             else
05309                res = ast_play_and_wait(chan, "vm-messages");
05310          }
05311             
05312       }
05313       if (!res && vms->oldmessages) {
05314          res = say_and_wait(chan, vms->oldmessages, chan->language);
05315          if (!res)
05316             res = ast_play_and_wait(chan, "vm-Old");
05317          if (!res) {
05318             if (vms->oldmessages == 1)
05319                res = ast_play_and_wait(chan, "vm-message");
05320             else
05321                res = ast_play_and_wait(chan, "vm-messages");
05322          }
05323       }
05324       if (!res) {
05325          if (!vms->oldmessages && !vms->newmessages) {
05326             res = ast_play_and_wait(chan, "vm-no");
05327             if (!res)
05328                res = ast_play_and_wait(chan, "vm-messages");
05329          }
05330       }
05331    }
05332    return res;
05333 }

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

Definition at line 4867 of file app_voicemail.c.

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

Referenced by vm_intro().

04868 {
04869    int res = 0;
04870 
04871    if (vms->newmessages) {
04872       res = ast_play_and_wait(chan, "vm-youhave");
04873       if (!res) 
04874          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
04875       if (!res) {
04876          if ((vms->newmessages == 1)) {
04877             res = ast_play_and_wait(chan, "vm-INBOX");
04878             if (!res)
04879                res = ast_play_and_wait(chan, "vm-message");
04880          } else {
04881             res = ast_play_and_wait(chan, "vm-INBOXs");
04882             if (!res)
04883                res = ast_play_and_wait(chan, "vm-messages");
04884          }
04885       }
04886    } else if (vms->oldmessages){
04887       res = ast_play_and_wait(chan, "vm-youhave");
04888       if (!res)
04889          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
04890       if ((vms->oldmessages == 1)){
04891          res = ast_play_and_wait(chan, "vm-Old");
04892          if (!res)
04893             res = ast_play_and_wait(chan, "vm-message");
04894       } else {
04895          res = ast_play_and_wait(chan, "vm-Olds");
04896          if (!res)
04897             res = ast_play_and_wait(chan, "vm-messages");
04898       }
04899    } else if (!vms->oldmessages && !vms->newmessages) 
04900       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
04901    return res;
04902 }

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

Definition at line 4949 of file app_voicemail.c.

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

Referenced by vm_intro().

04950 {
04951    /* Introduce messages they have */
04952    int res;
04953    if (!vms->oldmessages && !vms->newmessages)
04954       res = ast_play_and_wait(chan, "vm-no") ||
04955          ast_play_and_wait(chan, "vm-message");
04956    else
04957       res = ast_play_and_wait(chan, "vm-youhave");
04958    if (!res && vms->newmessages) {
04959       res = (vms->newmessages == 1) ?
04960          ast_play_and_wait(chan, "digits/un") ||
04961          ast_play_and_wait(chan, "vm-nuovo") ||
04962          ast_play_and_wait(chan, "vm-message") :
04963          /* 2 or more new messages */
04964          say_and_wait(chan, vms->newmessages, chan->language) ||
04965          ast_play_and_wait(chan, "vm-nuovi") ||
04966          ast_play_and_wait(chan, "vm-messages");
04967       if (!res && vms->oldmessages)
04968          res = ast_play_and_wait(chan, "vm-and");
04969    }
04970    if (!res && vms->oldmessages) {
04971       res = (vms->oldmessages == 1) ?
04972          ast_play_and_wait(chan, "digits/un") ||
04973          ast_play_and_wait(chan, "vm-vecchio") ||
04974          ast_play_and_wait(chan, "vm-message") :
04975          /* 2 or more old messages */
04976          say_and_wait(chan, vms->oldmessages, chan->language) ||
04977          ast_play_and_wait(chan, "vm-vecchi") ||
04978          ast_play_and_wait(chan, "vm-messages");
04979    }
04980    return res ? -1 : 0;
04981 }

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

Definition at line 5336 of file app_voicemail.c.

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

Referenced by vm_intro().

05337 {
05338    /* Introduce messages they have */
05339    int res;
05340    res = ast_play_and_wait(chan, "vm-youhave");
05341    if (!res) {
05342       if (vms->newmessages) {
05343          res = say_and_wait(chan, vms->newmessages, chan->language);
05344          if (!res) {
05345             if (vms->newmessages == 1)
05346                res = ast_play_and_wait(chan, "vm-INBOXs");
05347             else
05348                res = ast_play_and_wait(chan, "vm-INBOX");
05349          }
05350          if (vms->oldmessages && !res)
05351             res = ast_play_and_wait(chan, "vm-and");
05352          else if (!res) {
05353             if ((vms->newmessages == 1))
05354                res = ast_play_and_wait(chan, "vm-message");
05355             else
05356                res = ast_play_and_wait(chan, "vm-messages");
05357          }
05358             
05359       }
05360       if (!res && vms->oldmessages) {
05361          res = say_and_wait(chan, vms->oldmessages, chan->language);
05362          if (!res) {
05363             if (vms->oldmessages == 1)
05364                res = ast_play_and_wait(chan, "vm-Olds");
05365             else
05366                res = ast_play_and_wait(chan, "vm-Old");
05367          }
05368          if (!res) {
05369             if (vms->oldmessages == 1)
05370                res = ast_play_and_wait(chan, "vm-message");
05371             else
05372                res = ast_play_and_wait(chan, "vm-messages");
05373          }
05374       }
05375       if (!res) {
05376          if (!vms->oldmessages && !vms->newmessages) {
05377             res = ast_play_and_wait(chan, "vm-no");
05378             if (!res)
05379                res = ast_play_and_wait(chan, "vm-messages");
05380          }
05381       }
05382    }
05383    return res;
05384 }

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

Definition at line 5099 of file app_voicemail.c.

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

Referenced by vm_intro().

05100 {
05101    /* Introduce messages they have */
05102    int res;
05103 
05104    res = ast_play_and_wait(chan, "vm-youhave");
05105    if (res)
05106       return res;
05107 
05108    if (!vms->oldmessages && !vms->newmessages) {
05109       res = ast_play_and_wait(chan, "vm-no");
05110       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05111       return res;
05112    }
05113 
05114    if (vms->newmessages) {
05115       if ((vms->newmessages == 1)) {
05116          res = ast_play_and_wait(chan, "digits/1");
05117          res = res ? res : ast_play_and_wait(chan, "vm-ny");
05118          res = res ? res : ast_play_and_wait(chan, "vm-message");
05119       } else {
05120          res = say_and_wait(chan, vms->newmessages, chan->language);
05121          res = res ? res : ast_play_and_wait(chan, "vm-nye");
05122          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05123       }
05124       if (!res && vms->oldmessages)
05125          res = ast_play_and_wait(chan, "vm-and");
05126    }
05127    if (!res && vms->oldmessages) {
05128       if (vms->oldmessages == 1) {
05129          res = ast_play_and_wait(chan, "digits/1");
05130          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
05131          res = res ? res : ast_play_and_wait(chan, "vm-message");
05132       } else {
05133          res = say_and_wait(chan, vms->oldmessages, chan->language);
05134          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
05135          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05136       }
05137    }
05138 
05139    return res;
05140 }

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

Definition at line 4984 of file app_voicemail.c.

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

Referenced by vm_intro().

04985 {
04986    /* Introduce messages they have */
04987    int res;
04988    div_t num;
04989 
04990    if (!vms->oldmessages && !vms->newmessages) {
04991       res = ast_play_and_wait(chan, "vm-no");
04992       res = res ? res : ast_play_and_wait(chan, "vm-messages");
04993       return res;
04994    } else {
04995       res = ast_play_and_wait(chan, "vm-youhave");
04996    }
04997 
04998    if (vms->newmessages) {
04999       num = div(vms->newmessages, 10);
05000       if (vms->newmessages == 1) {
05001          res = ast_play_and_wait(chan, "digits/1-a");
05002          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
05003          res = res ? res : ast_play_and_wait(chan, "vm-message");
05004       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05005          if (num.rem == 2) {
05006             if (!num.quot) {
05007                res = ast_play_and_wait(chan, "digits/2-ie");
05008             } else {
05009                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
05010                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05011             }
05012          } else {
05013             res = say_and_wait(chan, vms->newmessages, chan->language);
05014          }
05015          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
05016          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05017       } else {
05018          res = say_and_wait(chan, vms->newmessages, chan->language);
05019          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
05020          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05021       }
05022       if (!res && vms->oldmessages)
05023          res = ast_play_and_wait(chan, "vm-and");
05024    }
05025    if (!res && vms->oldmessages) {
05026       num = div(vms->oldmessages, 10);
05027       if (vms->oldmessages == 1) {
05028          res = ast_play_and_wait(chan, "digits/1-a");
05029          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
05030          res = res ? res : ast_play_and_wait(chan, "vm-message");
05031       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05032          if (num.rem == 2) {
05033             if (!num.quot) {
05034                res = ast_play_and_wait(chan, "digits/2-ie");
05035             } else {
05036                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
05037                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05038             }
05039          } else {
05040             res = say_and_wait(chan, vms->oldmessages, chan->language);
05041          }
05042          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
05043          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05044       } else {
05045          res = say_and_wait(chan, vms->oldmessages, chan->language);
05046          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
05047          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05048       }
05049    }
05050 
05051    return res;
05052 }

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

Definition at line 5387 of file app_voicemail.c.

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

Referenced by vm_intro().

05388 {
05389    /* Introduce messages they have */
05390    int res;
05391    res = ast_play_and_wait(chan, "vm-youhave");
05392    if (!res) {
05393       if (vms->newmessages) {
05394          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05395          if (!res) {
05396             if ((vms->newmessages == 1)) {
05397                res = ast_play_and_wait(chan, "vm-message");
05398                if (!res)
05399                   res = ast_play_and_wait(chan, "vm-INBOXs");
05400             } else {
05401                res = ast_play_and_wait(chan, "vm-messages");
05402                if (!res)
05403                   res = ast_play_and_wait(chan, "vm-INBOX");
05404             }
05405          }
05406          if (vms->oldmessages && !res)
05407             res = ast_play_and_wait(chan, "vm-and");
05408       }
05409       if (!res && vms->oldmessages) {
05410          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05411          if (!res) {
05412             if (vms->oldmessages == 1) {
05413                res = ast_play_and_wait(chan, "vm-message");
05414                if (!res)
05415                   res = ast_play_and_wait(chan, "vm-Olds");
05416             } else {
05417                res = ast_play_and_wait(chan, "vm-messages");
05418                if (!res)
05419                   res = ast_play_and_wait(chan, "vm-Old");
05420             }
05421          }
05422       }
05423       if (!res) {
05424          if (!vms->oldmessages && !vms->newmessages) {
05425             res = ast_play_and_wait(chan, "vm-no");
05426             if (!res)
05427                res = ast_play_and_wait(chan, "vm-messages");
05428          }
05429       }
05430    }
05431    return res;
05432 }

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

Definition at line 5245 of file app_voicemail.c.

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

Referenced by vm_intro().

05245                                                                          {
05246    /* Introduce messages they have */
05247    int res;
05248    if (!vms->oldmessages && !vms->newmessages) {
05249       res = ast_play_and_wait(chan, "vm-nomessages");
05250       return res;
05251    }
05252    else {
05253       res = ast_play_and_wait(chan, "vm-youhave");
05254    }
05255    if (vms->newmessages) {
05256       if (!res)
05257          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05258       if ((vms->newmessages == 1)) {
05259          if (!res)
05260             res = ast_play_and_wait(chan, "vm-message");
05261          if (!res)
05262             res = ast_play_and_wait(chan, "vm-INBOXs");
05263       }
05264       else {
05265          if (!res)
05266             res = ast_play_and_wait(chan, "vm-messages");
05267          if (!res)
05268             res = ast_play_and_wait(chan, "vm-INBOX");
05269       }
05270       if (vms->oldmessages && !res)
05271          res = ast_play_and_wait(chan, "vm-and");
05272    }
05273    if (vms->oldmessages) {
05274       if (!res)
05275          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05276       if (vms->oldmessages == 1) {
05277          if (!res)
05278             res = ast_play_and_wait(chan, "vm-message");
05279          if (!res)
05280             res = ast_play_and_wait(chan, "vm-Olds");
05281       }
05282       else {
05283          if (!res)
05284       res = ast_play_and_wait(chan, "vm-messages");
05285          if (!res)
05286             res = ast_play_and_wait(chan, "vm-Old");
05287       }
05288    }
05289    return res;
05290 }

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

Definition at line 5516 of file app_voicemail.c.

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

Referenced by vm_intro().

05517 {
05518    int res;
05519    int lastnum = 0;
05520    int dcnum;
05521 
05522    res = ast_play_and_wait(chan, "vm-youhave");
05523    if (!res && vms->newmessages) {
05524       lastnum = get_lastdigits(vms->newmessages);
05525       dcnum = vms->newmessages - lastnum;
05526       if (dcnum)
05527          res = say_and_wait(chan, dcnum, chan->language);
05528       if (!res && lastnum) {
05529          if (lastnum == 1) 
05530             res = ast_play_and_wait(chan, "digits/ru/odno");
05531          else
05532             res = say_and_wait(chan, lastnum, chan->language);
05533       }
05534 
05535       if (!res)
05536          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-novoe" : "vm-novyh");
05537 
05538       if (!res && vms->oldmessages)
05539          res = ast_play_and_wait(chan, "vm-and");
05540    }
05541 
05542    if (!res && vms->oldmessages) {
05543       lastnum = get_lastdigits(vms->oldmessages);
05544       dcnum = vms->newmessages - lastnum;
05545       if (dcnum)
05546          res = say_and_wait(chan, dcnum, chan->language);
05547       if (!res && lastnum) {
05548          if (lastnum == 1) 
05549             res = ast_play_and_wait(chan, "digits/ru/odno");
05550          else
05551             res = say_and_wait(chan, lastnum, chan->language);
05552       }
05553 
05554       if (!res)
05555          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-staroe" : "vm-staryh");
05556    }
05557 
05558    if (!res && !vms->newmessages && !vms->oldmessages) {
05559       lastnum = 0;
05560       res = ast_play_and_wait(chan, "vm-no");
05561    }
05562 
05563    if (!res) {
05564       switch (lastnum) {
05565       case 1:
05566          res = ast_play_and_wait(chan, "vm-soobshenie");
05567          break;
05568       case 2:
05569       case 3:
05570       case 4:
05571          res = ast_play_and_wait(chan, "vm-soobsheniya");
05572          break;
05573       default:
05574          res = ast_play_and_wait(chan, "vm-soobsheniy");
05575          break;
05576       }
05577    }
05578 
05579    return res;
05580 }

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

Definition at line 5055 of file app_voicemail.c.

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

Referenced by vm_intro().

05056 {
05057    /* Introduce messages they have */
05058    int res;
05059 
05060    res = ast_play_and_wait(chan, "vm-youhave");
05061    if (res)
05062       return res;
05063 
05064    if (!vms->oldmessages && !vms->newmessages) {
05065       res = ast_play_and_wait(chan, "vm-no");
05066       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05067       return res;
05068    }
05069 
05070    if (vms->newmessages) {
05071       if ((vms->newmessages == 1)) {
05072          res = ast_play_and_wait(chan, "digits/ett");
05073          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
05074          res = res ? res : ast_play_and_wait(chan, "vm-message");
05075       } else {
05076          res = say_and_wait(chan, vms->newmessages, chan->language);
05077          res = res ? res : ast_play_and_wait(chan, "vm-nya");
05078          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05079       }
05080       if (!res && vms->oldmessages)
05081          res = ast_play_and_wait(chan, "vm-and");
05082    }
05083    if (!res && vms->oldmessages) {
05084       if (vms->oldmessages == 1) {
05085          res = ast_play_and_wait(chan, "digits/ett");
05086          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
05087          res = res ? res : ast_play_and_wait(chan, "vm-message");
05088       } else {
05089          res = say_and_wait(chan, vms->oldmessages, chan->language);
05090          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
05091          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05092       }
05093    }
05094 
05095    return res;
05096 }

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

Definition at line 935 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().

00936 {
00937    switch (ast_lock_path(path)) {
00938    case AST_LOCK_TIMEOUT:
00939       return -1;
00940    default:
00941       return 0;
00942    }
00943 }

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

Definition at line 1747 of file app_voicemail.c.

References my_umask, and VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

01748 {
01749    FILE *p = NULL;
01750    int pfd = mkstemp(template);
01751    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
01752    if (pfd > -1) {
01753       p = fdopen(pfd, "w+");
01754       if (!p) {
01755          close(pfd);
01756          pfd = -1;
01757       }
01758    }
01759    return p;
01760 }

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 5673 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, ast_vm_user::context, ext_pass_cmd, LOG_DEBUG, LOG_NOTICE, maxgreet, option_debug, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, and VM_SPOOL_DIR.

Referenced by vm_execmain().

05674 {
05675    int cmd = 0;
05676    int duration = 0;
05677    int tries = 0;
05678    char newpassword[80] = "";
05679    char newpassword2[80] = "";
05680    char prefile[PATH_MAX] = "";
05681    unsigned char buf[256];
05682    int bytes=0;
05683 
05684    if (ast_adsi_available(chan)) {
05685       bytes += adsi_logo(buf + bytes);
05686       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
05687       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05688       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05689       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05690       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05691    }
05692 
05693    /* First, have the user change their password 
05694       so they won't get here again */
05695    for (;;) {
05696       newpassword[1] = '\0';
05697       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
05698       if (cmd == '#')
05699          newpassword[0] = '\0';
05700       if (cmd < 0 || cmd == 't' || cmd == '#')
05701          return cmd;
05702       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
05703       if (cmd < 0 || cmd == 't' || cmd == '#')
05704          return cmd;
05705       newpassword2[1] = '\0';
05706       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
05707       if (cmd == '#')
05708          newpassword2[0] = '\0';
05709       if (cmd < 0 || cmd == 't' || cmd == '#')
05710          return cmd;
05711       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
05712       if (cmd < 0 || cmd == 't' || cmd == '#')
05713          return cmd;
05714       if (!strcmp(newpassword, newpassword2))
05715          break;
05716       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
05717       cmd = ast_play_and_wait(chan, "vm-mismatch");
05718       if (++tries == 3)
05719          return -1;
05720    }
05721    if (ast_strlen_zero(ext_pass_cmd)) 
05722       vm_change_password(vmu,newpassword);
05723    else 
05724       vm_change_password_shell(vmu,newpassword);
05725    if (option_debug > 2)
05726       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
05727    cmd = ast_play_and_wait(chan,"vm-passchanged");
05728 
05729    /* If forcename is set, have the user record their name */  
05730    if (ast_test_flag(vmu, VM_FORCENAME)) {
05731       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
05732       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05733 #ifndef IMAP_STORAGE
05734          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05735 #else
05736          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05737 #endif
05738          if (cmd < 0 || cmd == 't' || cmd == '#')
05739             return cmd;
05740       }
05741    }
05742 
05743    /* If forcegreetings is set, have the user record their greetings */
05744    if (ast_test_flag(vmu, VM_FORCEGREET)) {
05745       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
05746       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05747 #ifndef IMAP_STORAGE
05748          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05749 #else
05750          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05751 #endif
05752          if (cmd < 0 || cmd == 't' || cmd == '#')
05753             return cmd;
05754       }
05755 
05756       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
05757       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05758 #ifndef IMAP_STORAGE
05759          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05760 #else
05761          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05762 #endif
05763          if (cmd < 0 || cmd == 't' || cmd == '#')
05764             return cmd;
05765       }
05766    }
05767 
05768    return cmd;
05769 }

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 5771 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_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_waitfordigit(), ast_vm_user::context, ext_pass_cmd, LOG_DEBUG, LOG_NOTICE, maxgreet, option_debug, ast_vm_user::password, play_record_review(), vm_state::username, vm_change_password(), vm_change_password_shell(), VM_SPOOL_DIR, and vm_tempgreeting().

Referenced by vm_execmain().

05772 {
05773    int cmd = 0;
05774    int retries = 0;
05775    int duration = 0;
05776    char newpassword[80] = "";
05777    char newpassword2[80] = "";
05778    char prefile[PATH_MAX] = "";
05779    unsigned char buf[256];
05780    int bytes=0;
05781 
05782    if (ast_adsi_available(chan))
05783    {
05784       bytes += adsi_logo(buf + bytes);
05785       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
05786       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05787       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05788       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05789       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05790    }
05791    while ((cmd >= 0) && (cmd != 't')) {
05792       if (cmd)
05793          retries = 0;
05794       switch (cmd) {
05795       case '1':
05796          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
05797 #ifndef IMAP_STORAGE
05798          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05799 #else
05800          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05801 #endif
05802          break;
05803       case '2': 
05804          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
05805 #ifndef IMAP_STORAGE
05806          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05807 #else
05808          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05809 #endif
05810          break;
05811       case '3': 
05812          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
05813 #ifndef IMAP_STORAGE
05814          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05815 #else
05816          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05817 #endif
05818          break;
05819       case '4': 
05820          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
05821          break;
05822       case '5':
05823          if (vmu->password[0] == '-') {
05824             cmd = ast_play_and_wait(chan, "vm-no");
05825             break;
05826          }
05827          newpassword[1] = '\0';
05828          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
05829          if (cmd == '#')
05830             newpassword[0] = '\0';
05831          else {
05832             if (cmd < 0)
05833                break;
05834             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
05835                break;
05836             }
05837          }
05838          newpassword2[1] = '\0';
05839          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
05840          if (cmd == '#')
05841             newpassword2[0] = '\0';
05842          else {
05843             if (cmd < 0)
05844                break;
05845 
05846             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
05847                break;
05848             }
05849          }
05850          if (strcmp(newpassword, newpassword2)) {
05851             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
05852             cmd = ast_play_and_wait(chan, "vm-mismatch");
05853             break;
05854          }
05855          if (ast_strlen_zero(ext_pass_cmd)) 
05856             vm_change_password(vmu,newpassword);
05857          else 
05858             vm_change_password_shell(vmu,newpassword);
05859          if (option_debug > 2)
05860             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
05861          cmd = ast_play_and_wait(chan,"vm-passchanged");
05862          break;
05863       case '*': 
05864          cmd = 't';
05865          break;
05866       default: 
05867          cmd = ast_play_and_wait(chan,"vm-options");
05868          if (!cmd)
05869             cmd = ast_waitfordigit(chan,6000);
05870          if (!cmd)
05871             retries++;
05872          if (retries > 3)
05873             cmd = 't';
05874       }
05875    }
05876    if (cmd == 't')
05877       cmd = 0;
05878    return cmd;
05879 }

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

Definition at line 4838 of file app_voicemail.c.

References ast_play_and_wait(), vm_play_folder_name_gr(), and vm_play_folder_name_pl().

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

04839 {
04840    int cmd;
04841 
04842    if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
04843       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
04844       return cmd ? cmd : ast_play_and_wait(chan, mbox);
04845    } else if (!strcasecmp(chan->language, "gr")){
04846       return vm_play_folder_name_gr(chan, mbox);
04847    } else if (!strcasecmp(chan->language, "pl")){
04848       return vm_play_folder_name_pl(chan, mbox);
04849    } else {  /* Default English */
04850       cmd = ast_play_and_wait(chan, mbox);
04851       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
04852    }
04853 }

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

Definition at line 4804 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

04805 {
04806    int cmd;
04807    char *buf;
04808 
04809    buf = alloca(strlen(mbox)+2); 
04810    strcpy(buf, mbox);
04811    strcat(buf,"s");
04812 
04813    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
04814       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
04815       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04816    } else {
04817       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04818       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
04819    }
04820 }

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

Definition at line 4822 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

04823 {
04824    int cmd;
04825 
04826    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
04827       if (!strcasecmp(mbox, "vm-INBOX"))
04828          cmd = ast_play_and_wait(chan, "vm-new-e");
04829       else
04830          cmd = ast_play_and_wait(chan, "vm-old-e");
04831       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
04832    } else {
04833       cmd = ast_play_and_wait(chan, "vm-messages");
04834       return cmd ? cmd : ast_play_and_wait(chan, mbox);
04835    }
04836 }

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 5881 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, LOG_WARNING, maxgreet, play_record_review(), RETRIEVE, vm_state::username, and VM_SPOOL_DIR.

Referenced by vm_options().

05882 {
05883    int res;
05884    int cmd = 0;
05885    int retries = 0;
05886    int duration = 0;
05887    char prefile[PATH_MAX] = "";
05888    unsigned char buf[256];
05889    char dest[PATH_MAX];
05890    int bytes = 0;
05891 
05892    if (ast_adsi_available(chan)) {
05893       bytes += adsi_logo(buf + bytes);
05894       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
05895       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05896       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05897       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05898       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05899    }
05900 
05901    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
05902    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
05903       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
05904       return -1;
05905    }
05906    while((cmd >= 0) && (cmd != 't')) {
05907       if (cmd)
05908          retries = 0;
05909       RETRIEVE(prefile, -1);
05910       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
05911 #ifndef IMAP_STORAGE
05912          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05913 #else
05914          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05915 #endif
05916          cmd = 't';  
05917       } else {
05918          switch (cmd) {
05919          case '1':
05920 #ifndef IMAP_STORAGE
05921             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
05922 #else
05923             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
05924 #endif
05925             break;
05926          case '2':
05927             DELETE(prefile, -1, prefile);
05928             ast_play_and_wait(chan, "vm-tempremoved");
05929             cmd = 't';  
05930             break;
05931          case '*': 
05932             cmd = 't';
05933             break;
05934          default:
05935             cmd = ast_play_and_wait(chan,
05936                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
05937                   "vm-tempgreeting2" : "vm-tempgreeting");
05938             if (!cmd)
05939                cmd = ast_waitfordigit(chan,6000);
05940             if (!cmd)
05941                retries++;
05942             if (retries > 3)
05943                cmd = 't';
05944          }
05945       }
05946       DISPOSE(prefile, -1);
05947    }
05948    if (cmd == 't')
05949       cmd = 0;
05950    return cmd;
05951 }

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

Definition at line 6928 of file app_voicemail.c.

References 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, strsep(), and vm_authenticate().

Referenced by load_module().

06929 {
06930    struct ast_module_user *u;
06931    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
06932    struct ast_vm_user vmus;
06933    char *options = NULL;
06934    int silent = 0, skipuser = 0;
06935    int res = -1;
06936 
06937    u = ast_module_user_add(chan);
06938    
06939    if (s) {
06940       s = ast_strdupa(s);
06941       user = strsep(&s, "|");
06942       options = strsep(&s, "|");
06943       if (user) {
06944          s = user;
06945          user = strsep(&s, "@");
06946          context = strsep(&s, "");
06947          if (!ast_strlen_zero(user))
06948             skipuser++;
06949          ast_copy_string(mailbox, user, sizeof(mailbox));
06950       }
06951    }
06952 
06953    if (options) {
06954       silent = (strchr(options, 's')) != NULL;
06955    }
06956 
06957    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
06958       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
06959       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
06960       ast_play_and_wait(chan, "auth-thankyou");
06961       res = 0;
06962    }
06963 
06964    ast_module_user_remove(u);
06965    return res;
06966 }

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

Definition at line 1727 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), t, and ast_vm_user::zonetag.

Referenced by make_email_file(), and sendpage().

01728 {
01729    const struct vm_zone *z = NULL;
01730    time_t t = time(NULL);
01731 
01732    /* Does this user have a timezone specified? */
01733    if (!ast_strlen_zero(vmu->zonetag)) {
01734       /* Find the zone in the list */
01735       AST_LIST_LOCK(&zones);
01736       AST_LIST_TRAVERSE(&zones, z, list) {
01737          if (!strcmp(z->name, vmu->zonetag))
01738             break;
01739       }
01740       AST_LIST_UNLOCK(&zones);
01741    }
01742    ast_localtime(&t, tm, z ? z->timezone : NULL);
01743    return tm;
01744 }

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

Definition at line 4114 of file app_voicemail.c.

References ast_control_streamfile(), and skipms.

04115 {
04116    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
04117 }

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

Definition at line 4106 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_log(), ast_stream_and_wait(), and LOG_WARNING.

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

04107 {
04108    int res;
04109    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
04110       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
04111    return res;
04112 }


Variable Documentation

char* addesc = "Comedian Mail" [static]

Definition at line 427 of file app_voicemail.c.

Referenced by adsi_load_vmail().

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

Definition at line 547 of file app_voicemail.c.

Referenced by adsi_begin(), adsi_load_vmail(), and load_config().

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

Definition at line 548 of file app_voicemail.c.

Referenced by adsi_load_vmail(), and load_config().

int adsiver = 1 [static]

Definition at line 549 of file app_voicemail.c.

Referenced by adsi_begin(), adsi_load_vmail(), and load_config().

char* app = "VoiceMail" [static]

Definition at line 502 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 505 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 507 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 508 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 532 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

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

Definition at line 545 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 535 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

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 7070 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 7075 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 7080 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 432 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vm_box_exists [static]

Definition at line 477 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vmain [static]

Definition at line 459 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vmauthenticate [static]

Definition at line 491 of file app_voicemail.c.

Referenced by load_module().

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 531 of file app_voicemail.c.

Referenced by directory_exec(), load_config(), and populate_defaults().

char* emailbody = NULL [static]

Definition at line 538 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

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

Definition at line 550 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char* emailsubject = NULL [static]

Definition at line 539 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char emailtitle[100] [static]

Definition at line 544 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 533 of file app_voicemail.c.

Referenced by conf_run(), load_config(), and populate_defaults().

char ext_pass_cmd[128] [static]

Definition at line 413 of file app_voicemail.c.

Referenced by load_config(), vm_change_password_shell(), vm_newuser(), and vm_options().

char externnotify[160] [static]

Definition at line 517 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char fromstring[100] [static]

Definition at line 542 of file app_voicemail.c.

Referenced by load_config(), make_email_file(), and sendpage().

struct ast_flags globalflags = {0} [static]

Definition at line 527 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 516 of file app_voicemail.c.

int maxgreet [static]

Definition at line 523 of file app_voicemail.c.

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

int maxlogins [static]

Definition at line 525 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

int maxmsg [static]

Definition at line 513 of file app_voicemail.c.

int maxsilence [static]

Definition at line 512 of file app_voicemail.c.

Referenced by ast_record_review(), load_config(), play_record_review(), and vm_forwardoptions().

int my_umask

Definition at line 415 of file app_voicemail.c.

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

char* pagerbody = NULL [static]

Definition at line 540 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char pagerfromstring[100] [static]

Definition at line 543 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char* pagersubject = NULL [static]

Definition at line 541 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

int saydurationminfo [static]

Definition at line 529 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

char serveremail[80] [static]

Definition at line 515 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 514 of file app_voicemail.c.

int skipms [static]

Definition at line 524 of file app_voicemail.c.

Referenced by controlplayback_exec(), handle_controlstreamfile(), load_config(), and wait_file().

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 518 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 429 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 474 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 456 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 488 of file app_voicemail.c.

Referenced by load_module().

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

Definition at line 425 of file app_voicemail.c.

Referenced by load_config().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 411 of file app_voicemail.c.

Referenced by __has_voicemail(), forward_message(), invent_message(), leave_voicemail(), load_module(), make_dir(), play_message_callerid(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

char vmfmts[80] [static]

Definition at line 519 of file app_voicemail.c.

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

int vmmaxmessage [static]

Definition at line 522 of file app_voicemail.c.

Referenced by leave_voicemail(), and load_config().

int vmminmessage [static]

Definition at line 521 of file app_voicemail.c.

Referenced by leave_voicemail(), and load_config().

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 6968 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 6972 of file app_voicemail.c.

double volgain [static]

Definition at line 520 of file app_voicemail.c.


Generated on Wed Aug 15 01:24:42 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3