Mon Nov 24 15:34:25 2008

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

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

Go to the source code of this file.

Data Structures

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

Enumerations

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

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
static void 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 int copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
static void copy_plain_file (char *frompath, char *topath)
static int count_messages (struct ast_vm_user *vmu, char *dir)
static int create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder)
 basically mkdir -p $dest/$context/$ext/$folder
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static struct ast_vm_userfind_or_create (char *context, char *mbox)
static struct ast_vm_userfind_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static struct ast_vm_userfind_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static int forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
static void free_user (struct ast_vm_user *vmu)
static void free_vm_users (void)
static void free_zone (struct vm_zone *z)
static int get_date (char *s, int len)
static int get_folder (struct ast_channel *chan, int start)
static int get_folder2 (struct ast_channel *chan, char *fn, int start)
static int 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, struct ast_vm_user *vmu, char *ext, int busy, char *ecodes)
static int last_message_index (struct ast_vm_user *vmu, char *dir)
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
static int load_config (void)
static int load_module (void)
static int make_dir (char *dest, int len, const char *context, const char *ext, const char *folder)
static void make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
static int make_file (char *dest, const int len, const char *dir, const int num)
static char * mbox (int id)
static int messagecount (const char *context, const char *mailbox, const char *folder)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static int ochar (struct baseio *bio, int c, FILE *so)
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int play_greeting (struct ast_channel *chan, struct ast_vm_user *vmu, char *filename, char *ecodes)
static int play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
static int play_message_category (struct ast_channel *chan, const char *category)
static int play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
static int play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
static int play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, const char *unlockdir, signed char record_gain, struct vm_state *vms)
static void populate_defaults (struct ast_vm_user *vmu)
static void prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category)
static char * quote (const char *from, char *to, size_t len)
static int reload (void)
static void rename_file (char *sfn, char *dfn)
static int resequence_mailbox (struct ast_vm_user *vmu, char *dir)
static int reset_user_pw (const char *context, const char *mailbox, const char *newpass)
static void run_externnotify (char *context, char *extension)
static int save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
static int say_and_wait (struct ast_channel *chan, int num, const char *language)
static int sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category)
static int sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category)
static char * strip_control (const char *input, char *buf, size_t buflen)
static int unload_module (void)
static int vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
static int vm_box_exists (struct ast_channel *chan, void *data)
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_latin (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static void vm_change_password (struct ast_vm_user *vmu, const char *newpassword)
static void vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword)
static int vm_delete (char *file)
static int vm_exec (struct ast_channel *chan, void *data)
static int vm_execmain (struct ast_channel *chan, void *data)
static int vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts, char *context, signed char record_gain, long *duration, struct vm_state *vms)
static int vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_intro_cz (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_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_intro_ua (struct ast_channel *chan, struct vm_state *vms)
static int vm_lock_path (const char *path)
static FILE * vm_mkftemp (char *template)
static int vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_play_folder_name (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_gr (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_pl (struct ast_channel *chan, char *mbox)
static int vm_play_folder_name_ua (struct ast_channel *chan, char *mbox)
static int vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vmauthenticate (struct ast_channel *chan, void *data)
static struct tm * vmu_tm (const struct ast_vm_user *vmu, struct tm *tm)
static int wait_file (struct ast_channel *chan, struct vm_state *vms, char *file)
static int wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file)

Variables

static 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_interfacesmdi_iface = NULL
static char * synopsis_vm
static char * synopsis_vm_box_exists
static char * synopsis_vmain
static char * synopsis_vmauthenticate
static char userscontext [AST_MAX_EXTENSION] = "default"
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 164 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 180 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 181 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 181 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 161 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 157 of file app_voicemail.c.

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

Definition at line 426 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 427 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 422 of file app_voicemail.c.

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

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 182 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 203 of file app_voicemail.c.

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

#define ERROR_MAILBOX_FULL   -200

Definition at line 204 of file app_voicemail.c.

Referenced by save_to_folder().

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

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

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 184 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 185 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 172 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

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

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
b,
 ) 

Definition at line 421 of file app_voicemail.c.

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

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

Definition at line 168 of file app_voicemail.c.

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 155 of file app_voicemail.c.

Referenced by run_externnotify().

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

Definition at line 423 of file app_voicemail.c.

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

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 442 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 200 of file app_voicemail.c.

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

#define VM_ATTACH   (1 << 11)

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

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 197 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

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

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

#define VM_OPERATOR   (1 << 1)

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

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 187 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 189 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 192 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

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

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

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

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 163 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 159 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

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

00207      {
00208    OPT_SILENT =           (1 << 0),
00209    OPT_BUSY_GREETING =    (1 << 1),
00210    OPT_UNAVAIL_GREETING = (1 << 2),
00211    OPT_RECORDGAIN =       (1 << 3),
00212    OPT_PREPEND_MAILBOX =  (1 << 4),
00213    OPT_PRIORITY_JUMP =    (1 << 5),
00214    OPT_AUTOPLAY =         (1 << 6),
00215 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 217 of file app_voicemail.c.

00217      {
00218    OPT_ARG_RECORDGAIN = 0,
00219    OPT_ARG_PLAYFOLDER = 1,
00220    /* This *must* be the last value in this enum! */
00221    OPT_ARG_ARRAY_SIZE = 2,
00222 } vm_option_args;


Function Documentation

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

Definition at line 3554 of file app_voicemail.c.

References ast_strlen_zero(), and VM_SPOOL_DIR.

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

03555 {
03556    DIR *dir;
03557    struct dirent *de;
03558    char fn[256];
03559    int ret = 0;
03560    if (!folder)
03561       folder = "INBOX";
03562    /* If no mailbox, return immediately */
03563    if (ast_strlen_zero(mailbox))
03564       return 0;
03565    if (!context)
03566       context = "default";
03567    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
03568    dir = opendir(fn);
03569    if (!dir)
03570       return 0;
03571    while ((de = readdir(dir))) {
03572       if (!strncasecmp(de->d_name, "msg", 3)) {
03573          if (shortcircuit) {
03574             ret = 1;
03575             break;
03576          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
03577             ret++;
03578       }
03579    }
03580    closedir(dir);
03581    return ret;
03582 }

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

Definition at line 4305 of file app_voicemail.c.

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

Referenced by vm_authenticate(), and vm_execmain().

04306 {
04307    int x;
04308    if (!ast_adsi_available(chan))
04309       return;
04310    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04311    if (x < 0)
04312       return;
04313    if (!x) {
04314       if (adsi_load_vmail(chan, useadsi)) {
04315          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04316          return;
04317       }
04318    } else
04319       *useadsi = 1;
04320 }

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

Definition at line 4492 of file app_voicemail.c.

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

Referenced by vm_execmain().

04493 {
04494    int bytes=0;
04495    unsigned char buf[256];
04496    unsigned char keys[8];
04497 
04498    int x;
04499 
04500    if (!ast_adsi_available(chan))
04501       return;
04502 
04503    /* New meaning for keys */
04504    for (x=0;x<5;x++)
04505       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04506 
04507    keys[6] = 0x0;
04508    keys[7] = 0x0;
04509 
04510    if (!vms->curmsg) {
04511       /* No prev key, provide "Folder" instead */
04512       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04513    }
04514    if (vms->curmsg >= vms->lastmsg) {
04515       /* If last message ... */
04516       if (vms->curmsg) {
04517          /* but not only message, provide "Folder" instead */
04518          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04519       } else {
04520          /* Otherwise if only message, leave blank */
04521          keys[3] = 1;
04522       }
04523    }
04524 
04525    /* If deleted, show "undeleted" */
04526    if (vms->deleted[vms->curmsg]) 
04527       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04528 
04529    /* Except "Exit" */
04530    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04531    bytes += ast_adsi_set_keys(buf + bytes, keys);
04532    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04533 
04534    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04535 }

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

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

04371 {
04372    unsigned char buf[256];
04373    int bytes=0;
04374    unsigned char keys[8];
04375    int x,y;
04376 
04377    if (!ast_adsi_available(chan))
04378       return;
04379 
04380    for (x=0;x<5;x++) {
04381       y = ADSI_KEY_APPS + 12 + start + x;
04382       if (y > ADSI_KEY_APPS + 12 + 4)
04383          y = 0;
04384       keys[x] = ADSI_KEY_SKT | y;
04385    }
04386    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
04387    keys[6] = 0;
04388    keys[7] = 0;
04389 
04390    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
04391    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
04392    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04393    bytes += ast_adsi_set_keys(buf + bytes, keys);
04394    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04395 
04396    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04397 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

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

04641 {
04642    unsigned char buf[256];
04643    int bytes=0;
04644 
04645    if (!ast_adsi_available(chan))
04646       return;
04647    bytes += adsi_logo(buf + bytes);
04648    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
04649    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
04650    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04651    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04652 
04653    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04654 }

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

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

04175 {
04176    unsigned char buf[256];
04177    int bytes=0;
04178    int x;
04179    char num[5];
04180 
04181    *useadsi = 0;
04182    bytes += ast_adsi_data_mode(buf + bytes);
04183    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04184 
04185    bytes = 0;
04186    bytes += adsi_logo(buf);
04187    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04188 #ifdef DISPLAY
04189    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04190 #endif
04191    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04192    bytes += ast_adsi_data_mode(buf + bytes);
04193    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04194 
04195    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04196       bytes = 0;
04197       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04198       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04199       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04200       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04201       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04202       return 0;
04203    }
04204 
04205 #ifdef DISPLAY
04206    /* Add a dot */
04207    bytes = 0;
04208    bytes += ast_adsi_logo(buf);
04209    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04210    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04211    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04212    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04213 #endif
04214    bytes = 0;
04215    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04216    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04217    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04218    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04219    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04220    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04221    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04222 
04223 #ifdef DISPLAY
04224    /* Add another dot */
04225    bytes = 0;
04226    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04227    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04228 
04229    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04230    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04231 #endif
04232 
04233    bytes = 0;
04234    /* These buttons we load but don't use yet */
04235    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04236    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04237    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04238    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04239    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04240    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04241    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04242 
04243 #ifdef DISPLAY
04244    /* Add another dot */
04245    bytes = 0;
04246    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04247    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04248    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04249 #endif
04250 
04251    bytes = 0;
04252    for (x=0;x<5;x++) {
04253       snprintf(num, sizeof(num), "%d", x);
04254       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04255    }
04256    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04257    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04258 
04259 #ifdef DISPLAY
04260    /* Add another dot */
04261    bytes = 0;
04262    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04263    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04264    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04265 #endif
04266 
04267    if (ast_adsi_end_download(chan)) {
04268       bytes = 0;
04269       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04270       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04271       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04272       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04273       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04274       return 0;
04275    }
04276    bytes = 0;
04277    bytes += ast_adsi_download_disconnect(buf + bytes);
04278    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04279    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04280 
04281    if (option_debug)
04282       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
04283 
04284 #ifdef DISPLAY
04285    /* Add last dot */
04286    bytes = 0;
04287    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04288    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04289 #endif
04290    if (option_debug)
04291       ast_log(LOG_DEBUG, "Restarting session...\n");
04292 
04293    bytes = 0;
04294    /* Load the session now */
04295    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04296       *useadsi = 1;
04297       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04298    } else
04299       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04300 
04301    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04302    return 0;
04303 }

static void adsi_login ( struct ast_channel chan  )  [static]

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

04323 {
04324    unsigned char buf[256];
04325    int bytes=0;
04326    unsigned char keys[8];
04327    int x;
04328    if (!ast_adsi_available(chan))
04329       return;
04330 
04331    for (x=0;x<8;x++)
04332       keys[x] = 0;
04333    /* Set one key for next */
04334    keys[3] = ADSI_KEY_APPS + 3;
04335 
04336    bytes += adsi_logo(buf + bytes);
04337    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04338    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04339    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04340    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04341    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
04342    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
04343    bytes += ast_adsi_set_keys(buf + bytes, keys);
04344    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04345    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04346 }

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

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

04167 {
04168    int bytes = 0;
04169    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04170    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04171    return bytes;
04172 }

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

Definition at line 4399 of file app_voicemail.c.

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

Referenced by play_message(), and vm_execmain().

04400 {
04401    int bytes=0;
04402    unsigned char buf[256]; 
04403    char buf1[256], buf2[256];
04404    char fn2[PATH_MAX];
04405 
04406    char cid[256]="";
04407    char *val;
04408    char *name, *num;
04409    char datetime[21]="";
04410    FILE *f;
04411 
04412    unsigned char keys[8];
04413 
04414    int x;
04415 
04416    if (!ast_adsi_available(chan))
04417       return;
04418 
04419    /* Retrieve important info */
04420    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
04421    f = fopen(fn2, "r");
04422    if (f) {
04423       while (!feof(f)) {   
04424          fgets((char *)buf, sizeof(buf), f);
04425          if (!feof(f)) {
04426             char *stringp=NULL;
04427             stringp = (char *)buf;
04428             strsep(&stringp, "=");
04429             val = strsep(&stringp, "=");
04430             if (!ast_strlen_zero(val)) {
04431                if (!strcmp((char *)buf, "callerid"))
04432                   ast_copy_string(cid, val, sizeof(cid));
04433                if (!strcmp((char *)buf, "origdate"))
04434                   ast_copy_string(datetime, val, sizeof(datetime));
04435             }
04436          }
04437       }
04438       fclose(f);
04439    }
04440    /* New meaning for keys */
04441    for (x=0;x<5;x++)
04442       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04443    keys[6] = 0x0;
04444    keys[7] = 0x0;
04445 
04446    if (!vms->curmsg) {
04447       /* No prev key, provide "Folder" instead */
04448       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04449    }
04450    if (vms->curmsg >= vms->lastmsg) {
04451       /* If last message ... */
04452       if (vms->curmsg) {
04453          /* but not only message, provide "Folder" instead */
04454          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04455          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04456 
04457       } else {
04458          /* Otherwise if only message, leave blank */
04459          keys[3] = 1;
04460       }
04461    }
04462 
04463    if (!ast_strlen_zero(cid)) {
04464       ast_callerid_parse(cid, &name, &num);
04465       if (!name)
04466          name = num;
04467    } else
04468       name = "Unknown Caller";
04469 
04470    /* If deleted, show "undeleted" */
04471 
04472    if (vms->deleted[vms->curmsg])
04473       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04474 
04475    /* Except "Exit" */
04476    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04477    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
04478       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
04479    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
04480 
04481    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04482    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04483    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
04484    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
04485    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04486    bytes += ast_adsi_set_keys(buf + bytes, keys);
04487    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04488 
04489    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04490 }

static void adsi_password ( struct ast_channel chan  )  [static]

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

04349 {
04350    unsigned char buf[256];
04351    int bytes=0;
04352    unsigned char keys[8];
04353    int x;
04354    if (!ast_adsi_available(chan))
04355       return;
04356 
04357    for (x=0;x<8;x++)
04358       keys[x] = 0;
04359    /* Set one key for next */
04360    keys[3] = ADSI_KEY_APPS + 3;
04361 
04362    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04363    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
04364    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
04365    bytes += ast_adsi_set_keys(buf + bytes, keys);
04366    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04367    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04368 }

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

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

04538 {
04539    unsigned char buf[256] = "";
04540    char buf1[256] = "", buf2[256] = "";
04541    int bytes=0;
04542    unsigned char keys[8];
04543    int x;
04544 
04545    char *newm = (vms->newmessages == 1) ? "message" : "messages";
04546    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
04547    if (!ast_adsi_available(chan))
04548       return;
04549    if (vms->newmessages) {
04550       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
04551       if (vms->oldmessages) {
04552          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
04553          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
04554       } else {
04555          snprintf(buf2, sizeof(buf2), "%s.", newm);
04556       }
04557    } else if (vms->oldmessages) {
04558       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
04559       snprintf(buf2, sizeof(buf2), "%s.", oldm);
04560    } else {
04561       strcpy(buf1, "You have no messages.");
04562       buf2[0] = ' ';
04563       buf2[1] = '\0';
04564    }
04565    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04566    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04567    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04568 
04569    for (x=0;x<6;x++)
04570       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04571    keys[6] = 0;
04572    keys[7] = 0;
04573 
04574    /* Don't let them listen if there are none */
04575    if (vms->lastmsg < 0)
04576       keys[0] = 1;
04577    bytes += ast_adsi_set_keys(buf + bytes, keys);
04578 
04579    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04580 
04581    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04582 }

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

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

04585 {
04586    unsigned char buf[256] = "";
04587    char buf1[256] = "", buf2[256] = "";
04588    int bytes=0;
04589    unsigned char keys[8];
04590    int x;
04591 
04592    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
04593 
04594    if (!ast_adsi_available(chan))
04595       return;
04596 
04597    /* Original command keys */
04598    for (x=0;x<6;x++)
04599       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04600 
04601    keys[6] = 0;
04602    keys[7] = 0;
04603 
04604    if ((vms->lastmsg + 1) < 1)
04605       keys[0] = 0;
04606 
04607    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
04608       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
04609 
04610    if (vms->lastmsg + 1)
04611       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
04612    else
04613       strcpy(buf2, "no messages.");
04614    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04615    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04616    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
04617    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04618    bytes += ast_adsi_set_keys(buf + bytes, keys);
04619 
04620    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04621 
04622    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04623    
04624 }

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

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

Referenced by vm_execmain().

08516 {
08517    int res = 0;
08518    char filename[PATH_MAX];
08519    struct ast_config *msg_cfg = NULL;
08520    const char *origtime, *context;
08521    char *cid, *name, *num;
08522    int retries = 0;
08523 
08524    vms->starting = 0; 
08525    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08526 
08527    /* Retrieve info from VM attribute file */
08528    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08529    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08530    RETRIEVE(vms->curdir, vms->curmsg, vmu);
08531    msg_cfg = ast_config_load(filename);
08532    DISPOSE(vms->curdir, vms->curmsg);
08533    if (!msg_cfg) {
08534       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08535       return 0;
08536    }
08537 
08538    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08539       ast_config_destroy(msg_cfg);
08540       return 0;
08541    }
08542 
08543    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08544 
08545    context = ast_variable_retrieve(msg_cfg, "message", "context");
08546    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08547       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08548    switch (option) {
08549    case 3:
08550       if (!res)
08551          res = play_message_datetime(chan, vmu, origtime, filename);
08552       if (!res)
08553          res = play_message_callerid(chan, vms, cid, context, 0);
08554 
08555       res = 't';
08556       break;
08557 
08558    case 2:  /* Call back */
08559 
08560       if (ast_strlen_zero(cid))
08561          break;
08562 
08563       ast_callerid_parse(cid, &name, &num);
08564       while ((res > -1) && (res != 't')) {
08565          switch (res) {
08566          case '1':
08567             if (num) {
08568                /* Dial the CID number */
08569                res = dialout(chan, vmu, num, vmu->callback);
08570                if (res) {
08571                   ast_config_destroy(msg_cfg);
08572                   return 9;
08573                }
08574             } else {
08575                res = '2';
08576             }
08577             break;
08578 
08579          case '2':
08580             /* Want to enter a different number, can only do this if there's a dialout context for this user */
08581             if (!ast_strlen_zero(vmu->dialout)) {
08582                res = dialout(chan, vmu, NULL, vmu->dialout);
08583                if (res) {
08584                   ast_config_destroy(msg_cfg);
08585                   return 9;
08586                }
08587             } else {
08588                if (option_verbose > 2)
08589                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
08590                res = ast_play_and_wait(chan, "vm-sorry");
08591             }
08592             ast_config_destroy(msg_cfg);
08593             return res;
08594          case '*':
08595             res = 't';
08596             break;
08597          case '3':
08598          case '4':
08599          case '5':
08600          case '6':
08601          case '7':
08602          case '8':
08603          case '9':
08604          case '0':
08605 
08606             res = ast_play_and_wait(chan, "vm-sorry");
08607             retries++;
08608             break;
08609          default:
08610             if (num) {
08611                if (option_verbose > 2)
08612                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
08613                res = ast_play_and_wait(chan, "vm-num-i-have");
08614                if (!res)
08615                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
08616                if (!res)
08617                   res = ast_play_and_wait(chan, "vm-tocallnum");
08618                /* Only prompt for a caller-specified number if there is a dialout context specified */
08619                if (!ast_strlen_zero(vmu->dialout)) {
08620                   if (!res)
08621                      res = ast_play_and_wait(chan, "vm-calldiffnum");
08622                }
08623             } else {
08624                res = ast_play_and_wait(chan, "vm-nonumber");
08625                if (!ast_strlen_zero(vmu->dialout)) {
08626                   if (!res)
08627                      res = ast_play_and_wait(chan, "vm-toenternumber");
08628                }
08629             }
08630             if (!res)
08631                res = ast_play_and_wait(chan, "vm-star-cancel");
08632             if (!res)
08633                res = ast_waitfordigit(chan, 6000);
08634             if (!res) {
08635                retries++;
08636                if (retries > 3)
08637                   res = 't';
08638             }
08639             break; 
08640             
08641          }
08642          if (res == 't')
08643             res = 0;
08644          else if (res == '*')
08645             res = -1;
08646       }
08647       break;
08648       
08649    case 1:  /* Reply */
08650       /* Send reply directly to sender */
08651       if (ast_strlen_zero(cid))
08652          break;
08653 
08654       ast_callerid_parse(cid, &name, &num);
08655       if (!num) {
08656          if (option_verbose > 2)
08657             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
08658          if (!res)
08659             res = ast_play_and_wait(chan, "vm-nonumber");
08660          ast_config_destroy(msg_cfg);
08661          return res;
08662       } else {
08663          struct ast_vm_user vmu2;
08664          if (find_user(&vmu2, vmu->context, num)) {
08665             struct leave_vm_options leave_options;
08666             char mailbox[AST_MAX_EXTENSION * 2 + 2];
08667             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
08668 
08669             if (option_verbose > 2)
08670                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
08671             
08672             memset(&leave_options, 0, sizeof(leave_options));
08673             leave_options.record_gain = record_gain;
08674             res = leave_voicemail(chan, mailbox, &leave_options);
08675             if (!res)
08676                res = 't';
08677             ast_config_destroy(msg_cfg);
08678             return res;
08679          } else {
08680             /* Sender has no mailbox, can't reply */
08681             if (option_verbose > 2)
08682                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
08683             ast_play_and_wait(chan, "vm-nobox");
08684             res = 't';
08685             ast_config_destroy(msg_cfg);
08686             return res;
08687          }
08688       } 
08689       res = 0;
08690 
08691       break;
08692    }
08693 
08694 #ifndef IMAP_STORAGE
08695    ast_config_destroy(msg_cfg);
08696 
08697    if (!res) {
08698       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08699       vms->heard[msg] = 1;
08700       res = wait_file(chan, vms, vms->fn);
08701    }
08702 #endif
08703    return res;
08704 }

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

Definition at line 7576 of file app_voicemail.c.

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

Referenced by load_config().

07577 {
07578    /* Assumes lock is already held */
07579    char *tmp;
07580    char *stringp;
07581    char *s;
07582    struct ast_vm_user *vmu;
07583 
07584    tmp = ast_strdupa(data);
07585 
07586    if ((vmu = find_or_create(context, mbox))) {
07587       populate_defaults(vmu);
07588 
07589       stringp = tmp;
07590       if ((s = strsep(&stringp, ","))) 
07591          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07592       if (stringp && (s = strsep(&stringp, ","))) 
07593          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
07594       if (stringp && (s = strsep(&stringp, ","))) 
07595          ast_copy_string(vmu->email, s, sizeof(vmu->email));
07596       if (stringp && (s = strsep(&stringp, ","))) 
07597          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
07598       if (stringp && (s = strsep(&stringp, ","))) 
07599          apply_options(vmu, s);
07600    }
07601    return 0;
07602 }

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

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

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

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

Definition at line 686 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00687 {  /* Destructively Parse options and apply */
00688    char *stringp;
00689    char *s;
00690    char *var, *value;
00691    stringp = ast_strdupa(options);
00692    while ((s = strsep(&stringp, "|"))) {
00693       value = s;
00694       if ((var = strsep(&value, "=")) && value) {
00695          apply_option(vmu, var, value);
00696       }
00697    }  
00698 }

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

Definition at line 700 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, ast_variable::value, and var.

Referenced by find_user_realtime(), and load_config().

00701 {
00702    struct ast_variable *tmp;
00703    tmp = var;
00704    while (tmp) {
00705       if (!strcasecmp(tmp->name, "vmsecret")) {
00706          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00707       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00708          if (ast_strlen_zero(retval->password))
00709             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00710       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00711          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00712       } else if (!strcasecmp(tmp->name, "pager")) {
00713          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00714       } else if (!strcasecmp(tmp->name, "email")) {
00715          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00716       } else if (!strcasecmp(tmp->name, "fullname")) {
00717          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00718       } else if (!strcasecmp(tmp->name, "context")) {
00719          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00720 #ifdef IMAP_STORAGE
00721       } else if (!strcasecmp(tmp->name, "imapuser")) {
00722          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00723       } else if (!strcasecmp(tmp->name, "imappassword")) {
00724          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00725 #endif
00726       } else
00727          apply_option(retval, tmp->name, tmp->value);
00728       tmp = tmp->next;
00729    } 
00730 }

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

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

Referenced by make_email_file().

02847 {
02848    unsigned char dtable[BASEMAXINLINE];
02849    int i,hiteof= 0;
02850    FILE *fi;
02851    struct baseio bio;
02852 
02853    memset(&bio, 0, sizeof(bio));
02854    bio.iocp = BASEMAXINLINE;
02855 
02856    if (!(fi = fopen(filename, "rb"))) {
02857       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
02858       return -1;
02859    }
02860 
02861    for (i= 0;i<9;i++) {
02862       dtable[i]= 'A'+i;
02863       dtable[i+9]= 'J'+i;
02864       dtable[26+i]= 'a'+i;
02865       dtable[26+i+9]= 'j'+i;
02866    }
02867    for (i= 0;i<8;i++) {
02868       dtable[i+18]= 'S'+i;
02869       dtable[26+i+18]= 's'+i;
02870    }
02871    for (i= 0;i<10;i++) {
02872       dtable[52+i]= '0'+i;
02873    }
02874    dtable[62]= '+';
02875    dtable[63]= '/';
02876 
02877    while (!hiteof){
02878       unsigned char igroup[3],ogroup[4];
02879       int c,n;
02880 
02881       igroup[0]= igroup[1]= igroup[2]= 0;
02882 
02883       for (n= 0;n<3;n++) {
02884          if ((c = inchar(&bio, fi)) == EOF) {
02885             hiteof= 1;
02886             break;
02887          }
02888 
02889          igroup[n]= (unsigned char)c;
02890       }
02891 
02892       if (n> 0) {
02893          ogroup[0]= dtable[igroup[0]>>2];
02894          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
02895          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
02896          ogroup[3]= dtable[igroup[2]&0x3F];
02897 
02898          if (n<3) {
02899             ogroup[3]= '=';
02900 
02901             if (n<2)
02902                ogroup[2]= '=';
02903          }
02904 
02905          for (i= 0;i<4;i++)
02906             ochar(&bio, ogroup[i], so);
02907       }
02908    }
02909 
02910    fclose(fi);
02911    
02912    if (fputs(eol,so)==EOF)
02913       return 0;
02914 
02915    return 1;
02916 }

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

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

00671 {
00672    int res;
00673    if (!ast_strlen_zero(vmu->uniqueid)) {
00674       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00675       if (res > 0) {
00676          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00677          res = 0;
00678       } else if (!res) {
00679          res = -1;
00680       }
00681       return res;
00682    }
00683    return -1;
00684 }

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

Definition at line 5444 of file app_voicemail.c.

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

Referenced by vm_execmain().

05445 {
05446    int x = 0;
05447 #ifndef IMAP_STORAGE
05448    int res = 0, nummsg;
05449 #endif
05450 
05451    if (vms->lastmsg <= -1)
05452       goto done;
05453 
05454    vms->curmsg = -1; 
05455 #ifndef IMAP_STORAGE
05456    /* Get the deleted messages fixed */ 
05457    if (vm_lock_path(vms->curdir))
05458       return ERROR_LOCK_PATH;
05459     
05460    for (x = 0; x < vmu->maxmsg; x++) { 
05461       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
05462          /* Save this message.  It's not in INBOX or hasn't been heard */ 
05463          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
05464          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
05465             break;
05466          vms->curmsg++; 
05467          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
05468          if (strcmp(vms->fn, vms->fn2)) { 
05469             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
05470          } 
05471       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
05472          /* Move to old folder before deleting */ 
05473          res = save_to_folder(vmu, vms, x, 1);
05474          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
05475             /* If save failed do not delete the message */
05476             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
05477             vms->deleted[x] = 0;
05478             vms->heard[x] = 0;
05479             --x;
05480          } 
05481       } 
05482    } 
05483 
05484    /* Delete ALL remaining messages */
05485    nummsg = x - 1;
05486    for (x = vms->curmsg + 1; x <= nummsg; x++) {
05487       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
05488       if (EXISTS(vms->curdir, x, vms->fn, NULL))
05489          DELETE(vms->curdir, x, vms->fn, vmu);
05490    }
05491    ast_unlock_path(vms->curdir);
05492 #else
05493    if (vms->deleted) {
05494       for (x=0;x < vmu->maxmsg;x++) { 
05495          if (vms->deleted[x]) { 
05496             if (option_debug > 2)
05497                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
05498             DELETE(vms->curdir, x, vms->fn, vmu);
05499          }
05500       }
05501    }
05502 #endif
05503 
05504 done:
05505    if (vms->deleted)
05506       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
05507    if (vms->heard)
05508       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
05509 
05510    return 0;
05511 }

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

Definition at line 7765 of file app_voicemail.c.

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

07766 {
07767    int which = 0;
07768    int wordlen;
07769    struct ast_vm_user *vmu;
07770    const char *context = "";
07771 
07772    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
07773    if (pos > 4)
07774       return NULL;
07775    if (pos == 3)
07776       return (state == 0) ? ast_strdup("for") : NULL;
07777    wordlen = strlen(word);
07778    AST_LIST_TRAVERSE(&users, vmu, list) {
07779       if (!strncasecmp(word, vmu->context, wordlen)) {
07780          if (context && strcmp(context, vmu->context) && ++which > state)
07781             return ast_strdup(vmu->context);
07782          /* ignore repeated contexts ? */
07783          context = vmu->context;
07784       }
07785    }
07786    return NULL;
07787 }

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

Definition at line 2724 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

02725 {
02726    int ifd;
02727    int ofd;
02728    int res;
02729    int len;
02730    char buf[4096];
02731 
02732 #ifdef HARDLINK_WHEN_POSSIBLE
02733    /* Hard link if possible; saves disk space & is faster */
02734    if (link(infile, outfile)) {
02735 #endif
02736       if ((ifd = open(infile, O_RDONLY)) < 0) {
02737          ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
02738          return -1;
02739       }
02740       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
02741          ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
02742          close(ifd);
02743          return -1;
02744       }
02745       do {
02746          len = read(ifd, buf, sizeof(buf));
02747          if (len < 0) {
02748             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
02749             close(ifd);
02750             close(ofd);
02751             unlink(outfile);
02752          }
02753          if (len) {
02754             res = write(ofd, buf, len);
02755             if (errno == ENOMEM || errno == ENOSPC || res != len) {
02756                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
02757                close(ifd);
02758                close(ofd);
02759                unlink(outfile);
02760             }
02761          }
02762       } while (len);
02763       close(ifd);
02764       close(ofd);
02765       return 0;
02766 #ifdef HARDLINK_WHEN_POSSIBLE
02767    } else {
02768       /* Hard link succeeded */
02769       return 0;
02770    }
02771 #endif
02772 }

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 3498 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, copy_plain_file(), 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, STORE, vm_delete(), and vm_lock_path().

Referenced by forward_message(), and leave_voicemail().

03499 {
03500    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
03501    const char *frombox = mbox(imbox);
03502    int recipmsgnum;
03503 
03504    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
03505 
03506    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
03507    
03508    if (!dir)
03509       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
03510    else
03511       ast_copy_string(fromdir, dir, sizeof(fromdir));
03512 
03513    make_file(frompath, sizeof(frompath), fromdir, msgnum);
03514 
03515    if (vm_lock_path(todir))
03516       return ERROR_LOCK_PATH;
03517 
03518    recipmsgnum = 0;
03519    do {
03520       make_file(topath, sizeof(topath), todir, recipmsgnum);
03521       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
03522          break;
03523       recipmsgnum++;
03524    } while (recipmsgnum < recip->maxmsg);
03525    if (recipmsgnum < recip->maxmsg) {
03526       if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
03527          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
03528       } else {
03529          /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL
03530           * copy will fail. Instead, we need to create a local copy, store it, and delete the local
03531           * copy. We don't have to #ifdef this because if file storage reaches this point, there's a
03532           * much worse problem happening and IMAP storage doesn't call this function
03533           */
03534          copy_plain_file(frompath, topath);
03535          STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL);
03536          vm_delete(topath);
03537       }
03538    } else {
03539       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
03540    }
03541    ast_unlock_path(todir);
03542    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03543    
03544    return 0;
03545 }

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

Definition at line 2774 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message(), and forward_message().

02775 {
02776    char frompath2[PATH_MAX], topath2[PATH_MAX];
02777    ast_filecopy(frompath, topath, NULL);
02778    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
02779    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
02780    copy(frompath2, topath2);
02781 }

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

Definition at line 2640 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

02641 {
02642    /* Find all .txt files - even if they are not in sequence from 0000 */
02643 
02644    int vmcount = 0;
02645    DIR *vmdir = NULL;
02646    struct dirent *vment = NULL;
02647 
02648    if (vm_lock_path(dir))
02649       return ERROR_LOCK_PATH;
02650 
02651    if ((vmdir = opendir(dir))) {
02652       while ((vment = readdir(vmdir))) {
02653          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02654             vmcount++;
02655       }
02656       closedir(vmdir);
02657    }
02658    ast_unlock_path(dir);
02659    
02660    return vmcount;
02661 }

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

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

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

00929 {
00930    mode_t   mode = VOICEMAIL_DIR_MODE;
00931 
00932    if (!ast_strlen_zero(context)) {
00933       make_dir(dest, len, context, "", "");
00934       if (mkdir(dest, mode) && errno != EEXIST) {
00935          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00936          return -1;
00937       }
00938    }
00939    if (!ast_strlen_zero(ext)) {
00940       make_dir(dest, len, context, ext, "");
00941       if (mkdir(dest, mode) && errno != EEXIST) {
00942          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00943          return -1;
00944       }
00945    }
00946    if (!ast_strlen_zero(folder)) {
00947       make_dir(dest, len, context, ext, folder);
00948       if (mkdir(dest, mode) && errno != EEXIST) {
00949          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00950          return -1;
00951       }
00952    }
00953    return 0;
00954 }

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

Definition at line 8454 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.

Referenced by advanced_options(), and vm_execmain().

08455 {
08456    int cmd = 0;
08457    char destination[80] = "";
08458    int retries = 0;
08459 
08460    if (!num) {
08461       if (option_verbose > 2)
08462          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
08463       while (retries < 3 && cmd != 't') {
08464          destination[1] = '\0';
08465          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
08466          if (!cmd)
08467             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
08468          if (!cmd)
08469             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
08470          if (!cmd) {
08471             cmd = ast_waitfordigit(chan, 6000);
08472             if (cmd)
08473                destination[0] = cmd;
08474          }
08475          if (!cmd) {
08476             retries++;
08477          } else {
08478 
08479             if (cmd < 0)
08480                return 0;
08481             if (cmd == '*') {
08482                if (option_verbose > 2)
08483                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
08484                return 0;
08485             }
08486             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08487                retries++;
08488             else
08489                cmd = 't';
08490          }
08491       }
08492       if (retries >= 3) {
08493          return 0;
08494       }
08495       
08496    } else {
08497       if (option_verbose > 2)
08498          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08499       ast_copy_string(destination, num, sizeof(destination));
08500    }
08501 
08502    if (!ast_strlen_zero(destination)) {
08503       if (destination[strlen(destination) -1 ] == '*')
08504          return 0; 
08505       if (option_verbose > 2)
08506          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08507       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08508       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08509       chan->priority = 0;
08510       return 9;
08511    }
08512    return 0;
08513 }

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

Definition at line 7556 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, users, and VM_SEARCH.

Referenced by append_mailbox(), and load_config().

07557 {
07558    struct ast_vm_user *vmu;
07559    AST_LIST_TRAVERSE(&users, vmu, list) {
07560       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
07561          break;
07562       if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
07563          break;
07564    }
07565    
07566    if (!vmu) {
07567       if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07568          ast_copy_string(vmu->context, context, sizeof(vmu->context));
07569          ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07570          AST_LIST_INSERT_TAIL(&users, vmu, list);
07571       }
07572    }
07573    return vmu;
07574 }

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

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

00762 {
00763    /* This function could be made to generate one from a database, too */
00764    struct ast_vm_user *vmu=NULL, *cur;
00765    AST_LIST_LOCK(&users);
00766 
00767    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00768       context = "default";
00769 
00770    AST_LIST_TRAVERSE(&users, cur, list) {
00771       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00772          break;
00773       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00774          break;
00775    }
00776    if (cur) {
00777       /* Make a copy, so that on a reload, we have no race */
00778       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00779          memcpy(vmu, cur, sizeof(*vmu));
00780          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00781          AST_LIST_NEXT(vmu, list) = NULL;
00782       }
00783    } else
00784       vmu = find_user_realtime(ivm, context, mailbox);
00785    AST_LIST_UNLOCK(&users);
00786    return vmu;
00787 }

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

Definition at line 732 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, populate_defaults(), var, VM_ALLOCED, and VM_SEARCH.

Referenced by find_user().

00733 {
00734    struct ast_variable *var;
00735    struct ast_vm_user *retval;
00736 
00737    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00738       if (!ivm)
00739          ast_set_flag(retval, VM_ALLOCED);   
00740       else
00741          memset(retval, 0, sizeof(*retval));
00742       if (mailbox) 
00743          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00744       populate_defaults(retval);
00745       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00746          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00747       else
00748          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00749       if (var) {
00750          apply_options_full(retval, var);
00751          ast_variables_destroy(var);
00752       } else { 
00753          if (!ivm) 
00754             free(retval);
00755          retval = NULL;
00756       }  
00757    } 
00758    return retval;
00759 }

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 4862 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_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), copy_plain_file(), create_dirpath(), vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, leave_voicemail(), LOG_ERROR, ast_vm_user::mailbox, make_file(), pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), serveremail, STORE, strsep(), username, VM_ATTACH, vm_delete(), VM_DIRECFORWARD, vm_forwardoptions(), and vmfmts.

Referenced by vm_execmain().

04863 {
04864 #ifdef IMAP_STORAGE
04865    int todircount=0;
04866    struct vm_state *dstvms;
04867 #endif
04868    char username[70]="";
04869    int res = 0, cmd = 0;
04870    struct ast_vm_user *receiver = NULL, *vmtmp;
04871    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
04872    char *stringp;
04873    const char *s;
04874    int saved_messages = 0, found = 0;
04875    int valid_extensions = 0;
04876    char *dir;
04877    int curmsg;
04878 
04879    if (vms == NULL) return -1;
04880    dir = vms->curdir;
04881    curmsg = vms->curmsg;
04882    
04883    while (!res && !valid_extensions) {
04884       int use_directory = 0;
04885       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
04886          int done = 0;
04887          int retries = 0;
04888          cmd=0;
04889          while ((cmd >= 0) && !done ){
04890             if (cmd)
04891                retries = 0;
04892             switch (cmd) {
04893             case '1': 
04894                use_directory = 0;
04895                done = 1;
04896                break;
04897             case '2': 
04898                use_directory = 1;
04899                done=1;
04900                break;
04901             case '*': 
04902                cmd = 't';
04903                done = 1;
04904                break;
04905             default: 
04906                /* Press 1 to enter an extension press 2 to use the directory */
04907                cmd = ast_play_and_wait(chan,"vm-forward");
04908                if (!cmd)
04909                   cmd = ast_waitfordigit(chan,3000);
04910                if (!cmd)
04911                   retries++;
04912                if (retries > 3)
04913                {
04914                   cmd = 't';
04915                   done = 1;
04916                }
04917                
04918             }
04919          }
04920          if (cmd < 0 || cmd == 't')
04921             break;
04922       }
04923       
04924       if (use_directory) {
04925          /* use app_directory */
04926          
04927          char old_context[sizeof(chan->context)];
04928          char old_exten[sizeof(chan->exten)];
04929          int old_priority;
04930          struct ast_app* app;
04931 
04932          
04933          app = pbx_findapp("Directory");
04934          if (app) {
04935             char vmcontext[256];
04936             /* make backup copies */
04937             memcpy(old_context, chan->context, sizeof(chan->context));
04938             memcpy(old_exten, chan->exten, sizeof(chan->exten));
04939             old_priority = chan->priority;
04940             
04941             /* call the the Directory, changes the channel */
04942             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
04943             res = pbx_exec(chan, app, vmcontext);
04944             
04945             ast_copy_string(username, chan->exten, sizeof(username));
04946             
04947             /* restore the old context, exten, and priority */
04948             memcpy(chan->context, old_context, sizeof(chan->context));
04949             memcpy(chan->exten, old_exten, sizeof(chan->exten));
04950             chan->priority = old_priority;
04951             
04952          } else {
04953             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
04954             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
04955          }
04956       } else {
04957          /* Ask for an extension */
04958          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
04959          if (res)
04960             break;
04961          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
04962             break;
04963       }
04964       
04965       /* start all over if no username */
04966       if (ast_strlen_zero(username))
04967          continue;
04968       stringp = username;
04969       s = strsep(&stringp, "*");
04970       /* start optimistic */
04971       valid_extensions = 1;
04972       while (s) {
04973          /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1).  find_user is going to malloc since we have a NULL as first argument */
04974          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
04975             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
04976             found++;
04977          } else {
04978             valid_extensions = 0;
04979             break;
04980          }
04981          s = strsep(&stringp, "*");
04982       }
04983       /* break from the loop of reading the extensions */
04984       if (valid_extensions)
04985          break;
04986       /* "I am sorry, that's not a valid extension.  Please try again." */
04987       res = ast_play_and_wait(chan, "pbx-invalid");
04988    }
04989    /* check if we're clear to proceed */
04990    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
04991       return res;
04992    if (flag==1) {
04993       struct leave_vm_options leave_options;
04994       char mailbox[AST_MAX_EXTENSION * 2 + 2];
04995       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
04996       if (context)
04997          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
04998       else
04999          ast_copy_string(mailbox, username, sizeof(mailbox));
05000 
05001       /* Send VoiceMail */
05002       memset(&leave_options, 0, sizeof(leave_options));
05003       leave_options.record_gain = record_gain;
05004       cmd = leave_voicemail(chan, mailbox, &leave_options);
05005    } else {
05006       /* Forward VoiceMail */
05007       long duration = 0;
05008       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
05009       struct vm_state vmstmp;
05010 
05011       memcpy(&vmstmp, vms, sizeof(vmstmp));
05012 
05013       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
05014       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
05015       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
05016 
05017       RETRIEVE(dir, curmsg, sender);
05018 
05019       /* Alter a surrogate file, only */
05020       copy_plain_file(origmsgfile, msgfile);
05021 
05022       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05023       if (!cmd) {
05024          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05025 #ifdef IMAP_STORAGE
05026             char *myserveremail;
05027             int attach_user_voicemail;
05028             /* get destination mailbox */
05029             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
05030             if (!dstvms) {
05031                dstvms = create_vm_state_from_user(vmtmp);
05032             }
05033             if (dstvms) {
05034                init_mailstream(dstvms, 0);
05035                if (!dstvms->mailstream) {
05036                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
05037                } else {
05038                   STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05039                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
05040                }
05041             } else {
05042                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
05043             }
05044             myserveremail = serveremail;
05045             if (!ast_strlen_zero(vmtmp->serveremail))
05046                myserveremail = vmtmp->serveremail;
05047             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05048             /* NULL category for IMAP storage */
05049             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);
05050 #else
05051             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
05052 #endif
05053             saved_messages++;
05054             AST_LIST_REMOVE_CURRENT(&extensions, list);
05055             free_user(vmtmp);
05056             if (res)
05057                break;
05058          }
05059          AST_LIST_TRAVERSE_SAFE_END;
05060          if (saved_messages > 0) {
05061             /* give confirmation that the message was saved */
05062             /* commented out since we can't forward batches yet
05063             if (saved_messages == 1)
05064                res = ast_play_and_wait(chan, "vm-message");
05065             else
05066                res = ast_play_and_wait(chan, "vm-messages");
05067             if (!res)
05068                res = ast_play_and_wait(chan, "vm-saved"); */
05069             res = ast_play_and_wait(chan, "vm-msgsaved");
05070          }  
05071       }
05072 
05073       /* Remove surrogate file */
05074       vm_delete(msgfile);
05075       DISPOSE(dir, curmsg);
05076    }
05077 
05078    /* If anything failed above, we still have this list to free */
05079    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
05080       free_user(vmtmp);
05081    return res ? res : cmd;
05082 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 973 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

00974 {
00975    if (ast_test_flag(vmu, VM_ALLOCED))
00976       free(vmu);
00977 }

static void free_vm_users ( void   )  [static]

Definition at line 7809 of file app_voicemail.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), free_zone(), users, and VM_ALLOCED.

Referenced by load_config().

07810 {
07811    struct ast_vm_user *cur;
07812    struct vm_zone *zcur;
07813 
07814    AST_LIST_LOCK(&users);
07815    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
07816       ast_set_flag(cur, VM_ALLOCED);
07817       free_user(cur);
07818    }
07819    AST_LIST_UNLOCK(&users);
07820 
07821    AST_LIST_LOCK(&zones);
07822    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
07823       free_zone(zcur);
07824    }
07825    AST_LIST_UNLOCK(&zones);
07826 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3341 of file app_voicemail.c.

References free.

03342 {
03343    free(z);
03344 }

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

Definition at line 3274 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03275 {
03276    struct tm tm;
03277    time_t t;
03278 
03279    time(&t);
03280 
03281    ast_localtime(&t, &tm, NULL);
03282 
03283    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03284 }

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

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

04661 {
04662    int x;
04663    int d;
04664    char fn[PATH_MAX];
04665    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
04666    if (d)
04667       return d;
04668    for (x = start; x< 5; x++) {  /* For all folders */
04669       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
04670          return d;
04671       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
04672       if (d)
04673          return d;
04674       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
04675       d = vm_play_folder_name(chan, fn);
04676       if (d)
04677          return d;
04678       d = ast_waitfordigit(chan, 500);
04679       if (d)
04680          return d;
04681    }
04682    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
04683    if (d)
04684       return d;
04685    d = ast_waitfordigit(chan, 4000);
04686    return d;
04687 }

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

Definition at line 4689 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

04690 {
04691    int res = 0;
04692    res = ast_play_and_wait(chan, fn);  /* Folder name */
04693    while (((res < '0') || (res > '9')) &&
04694          (res != '#') && (res >= 0)) {
04695       res = get_folder(chan, 0);
04696    }
04697    return res;
04698 }

static int get_lastdigits ( int  num  )  [static]

Definition at line 6240 of file app_voicemail.c.

Referenced by vm_intro_ru(), and vm_intro_ua().

06241 {
06242    num %= 100;
06243    return (num < 20) ? num : num % 10;
06244 }

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

Definition at line 7695 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, users, and ast_vm_user::zonetag.

07696 {
07697    struct ast_vm_user *vmu;
07698    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
07699 
07700    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
07701    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
07702 
07703    AST_LIST_LOCK(&users);
07704    if (!AST_LIST_EMPTY(&users)) {
07705       if (argc == 3)
07706          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07707       else {
07708          int count = 0;
07709          AST_LIST_TRAVERSE(&users, vmu, list) {
07710             if (!strcmp(argv[4],vmu->context))
07711                count++;
07712          }
07713          if (count) {
07714             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07715          } else {
07716             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
07717             AST_LIST_UNLOCK(&users);
07718             return RESULT_FAILURE;
07719          }
07720       }
07721       AST_LIST_TRAVERSE(&users, vmu, list) {
07722          int newmsgs = 0, oldmsgs = 0;
07723          char count[12], tmp[256] = "";
07724 
07725          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
07726             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
07727             inboxcount(tmp, &newmsgs, &oldmsgs);
07728             snprintf(count,sizeof(count),"%d",newmsgs);
07729             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
07730          }
07731       }
07732    } else {
07733       ast_cli(fd, "There are no voicemail users currently defined\n");
07734       AST_LIST_UNLOCK(&users);
07735       return RESULT_FAILURE;
07736    }
07737    AST_LIST_UNLOCK(&users);
07738    return RESULT_SUCCESS;
07739 }

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

Definition at line 7741 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.

07742 {
07743    struct vm_zone *zone;
07744    char *output_format = "%-15s %-20s %-45s\n";
07745    int res = RESULT_SUCCESS;
07746 
07747    if (argc != 3)
07748       return RESULT_SHOWUSAGE;
07749 
07750    AST_LIST_LOCK(&zones);
07751    if (!AST_LIST_EMPTY(&zones)) {
07752       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
07753       AST_LIST_TRAVERSE(&zones, zone, list) {
07754          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
07755       }
07756    } else {
07757       ast_cli(fd, "There are no voicemail zones currently defined\n");
07758       res = RESULT_FAILURE;
07759    }
07760    AST_LIST_UNLOCK(&zones);
07761 
07762    return res;
07763 }

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

Definition at line 3585 of file app_voicemail.c.

References __has_voicemail(), and strsep().

03586 {
03587    char tmp[256], *tmp2 = tmp, *mbox, *context;
03588    ast_copy_string(tmp, mailbox, sizeof(tmp));
03589    while ((mbox = strsep(&tmp2, ","))) {
03590       if ((context = strchr(mbox, '@')))
03591          *context++ = '\0';
03592       else
03593          context = "default";
03594       if (__has_voicemail(context, mbox, folder, 1))
03595          return 1;
03596    }
03597    return 0;
03598 }

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

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

03602 {
03603    char tmp[256];
03604    char *context;
03605 
03606    if (newmsgs)
03607       *newmsgs = 0;
03608    if (oldmsgs)
03609       *oldmsgs = 0;
03610    /* If no mailbox, return immediately */
03611    if (ast_strlen_zero(mailbox))
03612       return 0;
03613    if (strchr(mailbox, ',')) {
03614       int tmpnew, tmpold;
03615       char *mb, *cur;
03616 
03617       ast_copy_string(tmp, mailbox, sizeof(tmp));
03618       mb = tmp;
03619       while ((cur = strsep(&mb, ", "))) {
03620          if (!ast_strlen_zero(cur)) {
03621             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
03622                return -1;
03623             else {
03624                if (newmsgs)
03625                   *newmsgs += tmpnew; 
03626                if (oldmsgs)
03627                   *oldmsgs += tmpold;
03628             }
03629          }
03630       }
03631       return 0;
03632    }
03633    ast_copy_string(tmp, mailbox, sizeof(tmp));
03634    context = strchr(tmp, '@');
03635    if (context) {
03636       *context = '\0';
03637       context++;
03638    } else
03639       context = "default";
03640    if (newmsgs)
03641       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
03642    if (oldmsgs)
03643       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
03644    return 0;
03645 }

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

Definition at line 2798 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

02799 {
02800    int l;
02801 
02802    if (bio->ateof)
02803       return 0;
02804 
02805    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
02806       if (ferror(fi))
02807          return -1;
02808 
02809       bio->ateof = 1;
02810       return 0;
02811    }
02812 
02813    bio->iolen= l;
02814    bio->iocp= 0;
02815 
02816    return 1;
02817 }

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

Definition at line 2819 of file app_voicemail.c.

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

Referenced by base_encode().

02820 {
02821    if (bio->iocp>=bio->iolen) {
02822       if (!inbuf(bio, fi))
02823          return EOF;
02824    }
02825 
02826    return bio->iobuf[bio->iocp++];
02827 }

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

Definition at line 3312 of file app_voicemail.c.

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

Referenced by leave_voicemail().

03313 {
03314    int res;
03315    char fn[PATH_MAX];
03316    char dest[PATH_MAX];
03317 
03318    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
03319 
03320    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
03321       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
03322       return -1;
03323    }
03324 
03325    res = play_greeting(chan, vmu, fn, ecodes);
03326    if (res == -2) {
03327       /* File did not exist */
03328       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
03329       if (res)
03330          return res;
03331       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
03332    }
03333 
03334    if (res)
03335       return res;
03336 
03337    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
03338    return res;
03339 }

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

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

02679 {
02680    int x;
02681    char fn[PATH_MAX];
02682 
02683    if (vm_lock_path(dir))
02684       return ERROR_LOCK_PATH;
02685 
02686    for (x = 0; x < vmu->maxmsg; x++) {
02687       make_file(fn, sizeof(fn), dir, x);
02688       if (ast_fileexists(fn, NULL, NULL) < 1)
02689          break;
02690    }
02691    ast_unlock_path(dir);
02692 
02693    return x - 1;
02694 }

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

Definition at line 3696 of file app_voicemail.c.

References ast_callerid_merge(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_goto_if_exists(), ast_log(), ast_opt_priority_jumping, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, EXISTS, ast_vm_user::exit, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), INTRO, invent_message(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, 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_greeting(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, S_OR, STORE, strsep(), transfer, 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().

03697 {
03698 #ifdef IMAP_STORAGE
03699    int newmsgs, oldmsgs;
03700 #endif
03701    struct vm_state *vms = NULL;
03702    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
03703    char callerid[256];
03704    FILE *txt;
03705    char date[256];
03706    int txtdes;
03707    int res = 0;
03708    int msgnum;
03709    int duration = 0;
03710    int ausemacro = 0;
03711    int ousemacro = 0;
03712    int ouseexten = 0;
03713    char dir[PATH_MAX], tmpdir[PATH_MAX];
03714    char dest[PATH_MAX];
03715    char fn[PATH_MAX];
03716    char prefile[PATH_MAX] = "";
03717    char tempfile[PATH_MAX] = "";
03718    char ext_context[256] = "";
03719    char fmt[80];
03720    char *context;
03721    char ecodes[16] = "#";
03722    char tmp[1024] = "", *tmpptr;
03723    struct ast_vm_user *vmu;
03724    struct ast_vm_user svm;
03725    const char *category = NULL;
03726 
03727    ast_copy_string(tmp, ext, sizeof(tmp));
03728    ext = tmp;
03729    context = strchr(tmp, '@');
03730    if (context) {
03731       *context++ = '\0';
03732       tmpptr = strchr(context, '&');
03733    } else {
03734       tmpptr = strchr(ext, '&');
03735    }
03736 
03737    if (tmpptr)
03738       *tmpptr++ = '\0';
03739 
03740    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
03741 
03742    if (option_debug > 2)
03743       ast_log(LOG_DEBUG, "Before find_user\n");
03744    if (!(vmu = find_user(&svm, context, ext))) {
03745       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
03746       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
03747          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
03748       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03749       return res;
03750    }
03751    /* Setup pre-file if appropriate */
03752    if (strcmp(vmu->context, "default"))
03753       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
03754    else
03755       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
03756    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
03757       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
03758       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
03759    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
03760       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
03761       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
03762    }
03763    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
03764    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
03765       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
03766       return -1;
03767    }
03768    RETRIEVE(tempfile, -1, vmu);
03769    if (ast_fileexists(tempfile, NULL, NULL) > 0)
03770       ast_copy_string(prefile, tempfile, sizeof(prefile));
03771    DISPOSE(tempfile, -1);
03772    /* It's easier just to try to make it than to check for its existence */
03773    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
03774    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
03775 
03776    /* Check current or macro-calling context for special extensions */
03777    if (ast_test_flag(vmu, VM_OPERATOR)) {
03778       if (!ast_strlen_zero(vmu->exit)) {
03779          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
03780             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
03781             ouseexten = 1;
03782          }
03783       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
03784          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
03785          ouseexten = 1;
03786       }
03787       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
03788       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
03789       ousemacro = 1;
03790       }
03791    }
03792 
03793    if (!ast_strlen_zero(vmu->exit)) {
03794       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
03795          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
03796    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
03797       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
03798    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
03799       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
03800       ausemacro = 1;
03801    }
03802 
03803    /* Play the beginning intro if desired */
03804    if (!ast_strlen_zero(prefile)) {
03805       res = play_greeting(chan, vmu, prefile, ecodes);
03806       if (res == -2) {
03807          /* The file did not exist */
03808          if (option_debug)
03809             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
03810          res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
03811       }
03812       if (res < 0) {
03813          if (option_debug)
03814             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
03815          free_user(vmu);
03816          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03817          return -1;
03818       }
03819    }
03820    if (res == '#') {
03821       /* On a '#' we skip the instructions */
03822       ast_set_flag(options, OPT_SILENT);
03823       res = 0;
03824    }
03825    if (!res && !ast_test_flag(options, OPT_SILENT)) {
03826       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
03827       if (res == '#') {
03828          ast_set_flag(options, OPT_SILENT);
03829          res = 0;
03830       }
03831    }
03832    if (res > 0)
03833       ast_stopstream(chan);
03834    /* Check for a '*' here in case the caller wants to escape from voicemail to something
03835     other than the operator -- an automated attendant or mailbox login for example */
03836    if (res == '*') {
03837       chan->exten[0] = 'a';
03838       chan->exten[1] = '\0';
03839       if (!ast_strlen_zero(vmu->exit)) {
03840          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
03841       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
03842          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
03843       }
03844       chan->priority = 0;
03845       free_user(vmu);
03846       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
03847       return 0;
03848    }
03849 
03850    /* Check for a '0' here */
03851    if (res == '0') {
03852    transfer:
03853       if (ouseexten || ousemacro) {
03854          chan->exten[0] = 'o';
03855          chan->exten[1] = '\0';
03856          if (!ast_strlen_zero(vmu->exit)) {
03857             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
03858          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
03859             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
03860          }
03861          ast_play_and_wait(chan, "transfer");
03862          chan->priority = 0;
03863          free_user(vmu);
03864          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
03865       }
03866       return 0;
03867    }
03868    if (res < 0) {
03869       free_user(vmu);
03870       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03871       return -1;
03872    }
03873    /* The meat of recording the message...  All the announcements and beeps have been played*/
03874    ast_copy_string(fmt, vmfmts, sizeof(fmt));
03875    if (!ast_strlen_zero(fmt)) {
03876       msgnum = 0;
03877 
03878 #ifdef IMAP_STORAGE
03879       /* Is ext a mailbox? */
03880       /* must open stream for this user to get info! */
03881       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
03882       if (res < 0) {
03883          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
03884          return -1;
03885       }
03886       if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) {
03887       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
03888        * rarely be used*/
03889          if (!(vms = create_vm_state_from_user(vmu))) {
03890             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
03891             return -1;
03892          }
03893       }
03894       vms->newmessages++;
03895       /* here is a big difference! We add one to it later */
03896       msgnum = newmsgs + oldmsgs;
03897       if (option_debug > 2)
03898          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
03899       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
03900       /* set variable for compatability */
03901       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
03902 
03903       /* Check if mailbox is full */
03904       check_quota(vms, imapfolder);
03905       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
03906          if (option_debug)
03907             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
03908          ast_play_and_wait(chan, "vm-mailboxfull");
03909          return -1;
03910       }
03911       if (option_debug > 2)
03912          ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
03913       if (msgnum >= vmu->maxmsg) {
03914          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03915          if (!res)
03916             res = ast_waitstream(chan, "");
03917          ast_log(LOG_WARNING, "No more messages possible\n");
03918          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03919          goto leave_vm_out;
03920       }
03921 
03922       /* Check if we have exceeded maxmsg */
03923       if (msgnum >= vmu->maxmsg) {
03924          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
03925          ast_play_and_wait(chan, "vm-mailboxfull");
03926          return -1;
03927       }
03928 #else
03929       if (count_messages(vmu, dir) >= vmu->maxmsg) {
03930          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03931          if (!res)
03932             res = ast_waitstream(chan, "");
03933          ast_log(LOG_WARNING, "No more messages possible\n");
03934          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03935          goto leave_vm_out;
03936       }
03937 
03938 #endif
03939       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
03940       txtdes = mkstemp(tmptxtfile);
03941       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
03942       if (txtdes < 0) {
03943          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03944          if (!res)
03945             res = ast_waitstream(chan, "");
03946          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
03947          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03948          goto leave_vm_out;
03949       }
03950 
03951       /* Now play the beep once we have the message number for our next message. */
03952       if (res >= 0) {
03953          /* Unless we're *really* silent, try to send the beep */
03954          res = ast_stream_and_wait(chan, "beep", chan->language, "");
03955       }
03956             
03957       /* Store information */
03958       txt = fdopen(txtdes, "w+");
03959       if (txt) {
03960          get_date(date, sizeof(date));
03961          fprintf(txt, 
03962             ";\n"
03963             "; Message Information file\n"
03964             ";\n"
03965             "[message]\n"
03966             "origmailbox=%s\n"
03967             "context=%s\n"
03968             "macrocontext=%s\n"
03969             "exten=%s\n"
03970             "priority=%d\n"
03971             "callerchan=%s\n"
03972             "callerid=%s\n"
03973             "origdate=%s\n"
03974             "origtime=%ld\n"
03975             "category=%s\n",
03976             ext,
03977             chan->context,
03978             chan->macrocontext, 
03979             chan->exten,
03980             chan->priority,
03981             chan->name,
03982             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
03983             date, (long)time(NULL),
03984             category ? category : ""); 
03985       } else
03986          ast_log(LOG_WARNING, "Error opening text file for output\n");
03987       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
03988 
03989       if (txt) {
03990          if (duration < vmminmessage) {
03991             fclose(txt);
03992             if (option_verbose > 2) 
03993                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
03994             ast_filedelete(tmptxtfile, NULL);
03995             unlink(tmptxtfile);
03996          } else {
03997             fprintf(txt, "duration=%d\n", duration);
03998             fclose(txt);
03999             if (vm_lock_path(dir)) {
04000                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
04001                /* Delete files */
04002                ast_filedelete(tmptxtfile, NULL);
04003                unlink(tmptxtfile);
04004             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
04005                if (option_debug) 
04006                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
04007                unlink(tmptxtfile);
04008                ast_unlock_path(dir);
04009             } else {
04010                for (;;) {
04011                   make_file(fn, sizeof(fn), dir, msgnum);
04012                   if (!EXISTS(dir, msgnum, fn, NULL))
04013                      break;
04014                   msgnum++;
04015                }
04016 
04017                /* assign a variable with the name of the voicemail file */ 
04018 #ifndef IMAP_STORAGE
04019                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
04020 #else
04021                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04022 #endif
04023 
04024                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
04025                ast_filerename(tmptxtfile, fn, NULL);
04026                rename(tmptxtfile, txtfile);
04027 
04028                ast_unlock_path(dir);
04029                /* We must store the file first, before copying the message, because
04030                 * ODBC storage does the entire copy with SQL.
04031                 */
04032                if (ast_fileexists(fn, NULL, NULL) > 0) {
04033                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
04034                }
04035 
04036                /* Are there to be more recipients of this message? */
04037                while (tmpptr) {
04038                   struct ast_vm_user recipu, *recip;
04039                   char *exten, *context;
04040                
04041                   exten = strsep(&tmpptr, "&");
04042                   context = strchr(exten, '@');
04043                   if (context) {
04044                      *context = '\0';
04045                      context++;
04046                   }
04047                   if ((recip = find_user(&recipu, context, exten))) {
04048                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
04049                      free_user(recip);
04050                   }
04051                }
04052                /* Notification and disposal needs to happen after the copy, though. */
04053                if (ast_fileexists(fn, NULL, NULL)) {
04054                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04055                   DISPOSE(dir, msgnum);
04056                }
04057             }
04058          }
04059       }
04060       if (res == '0') {
04061          goto transfer;
04062       } else if (res > 0)
04063          res = 0;
04064 
04065       if (duration < vmminmessage)
04066          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
04067          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04068       else
04069          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
04070    } else
04071       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
04072 leave_vm_out:
04073    free_user(vmu);
04074    
04075    return res;
04076 }

static int load_config ( void   )  [static]

Definition at line 7828 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_UNLOCK, ast_log(), ast_malloc, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, dialcontext, emailbody, emaildateformat, emailsubject, emailtitle, exitcontext, ext_pass_cmd, externnotify, find_or_create(), free, free_vm_users(), fromstring, globalflags, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, mailcmd, MAX_NUM_CID_CONTEXTS, maxgreet, maxlogins, MAXMSG, maxmsg, MAXMSGLIMIT, maxsilence, option_debug, pagerbody, pagerfromstring, pagersubject, populate_defaults(), s, saydurationminfo, SENDMAIL, serveremail, silencethreshold, skipms, smdi_iface, strsep(), users, userscontext, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxmessage, vmminmessage, VOICEMAIL_CONFIG, and volgain.

07829 {
07830    struct ast_vm_user *cur;
07831    struct ast_config *cfg, *ucfg;
07832    char *cat;
07833    struct ast_variable *var;
07834    const char *notifystr = NULL;
07835    const char *smdistr = NULL;
07836    const char *astattach;
07837    const char *astsearch;
07838    const char *astsaycid;
07839    const char *send_voicemail;
07840 #ifdef IMAP_STORAGE
07841    const char *imap_server;
07842    const char *imap_port;
07843    const char *imap_flags;
07844    const char *imap_folder;
07845    const char *auth_user;
07846    const char *auth_password;
07847    const char *expunge_on_hangup;
07848    const char *imap_timeout;
07849 #endif
07850    const char *astcallop;
07851    const char *astreview;
07852    const char *asttempgreetwarn;
07853    const char *astskipcmd;
07854    const char *asthearenv;
07855    const char *astsaydurationinfo;
07856    const char *astsaydurationminfo;
07857    const char *silencestr;
07858    const char *maxmsgstr;
07859    const char *astdirfwd;
07860    const char *thresholdstr;
07861    const char *fmt;
07862    const char *astemail;
07863    const char *ucontext;
07864    const char *astmailcmd = SENDMAIL;
07865    const char *astforcename;
07866    const char *astforcegreet;
07867    const char *s;
07868    char *q,*stringp;
07869    const char *dialoutcxt = NULL;
07870    const char *callbackcxt = NULL;  
07871    const char *exitcxt = NULL;   
07872    const char *extpc;
07873    const char *emaildateformatstr;
07874    const char *volgainstr;
07875    int x;
07876    int tmpadsi[4];
07877 
07878    cfg = ast_config_load(VOICEMAIL_CONFIG);
07879 
07880    free_vm_users();
07881 
07882    AST_LIST_LOCK(&users);
07883 
07884    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
07885 
07886    if (cfg) {
07887       /* General settings */
07888 
07889       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
07890          ucontext = "default";
07891       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
07892       /* Attach voice message to mail message ? */
07893       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
07894          astattach = "yes";
07895       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
07896 
07897       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
07898          astsearch = "no";
07899       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
07900 
07901       volgain = 0.0;
07902       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
07903          sscanf(volgainstr, "%lf", &volgain);
07904 
07905 #ifdef ODBC_STORAGE
07906       strcpy(odbc_database, "asterisk");
07907       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
07908          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
07909       }
07910       strcpy(odbc_table, "voicemessages");
07911       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
07912          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
07913       }
07914 #endif      
07915       /* Mail command */
07916       strcpy(mailcmd, SENDMAIL);
07917       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
07918          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
07919 
07920       maxsilence = 0;
07921       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
07922          maxsilence = atoi(silencestr);
07923          if (maxsilence > 0)
07924             maxsilence *= 1000;
07925       }
07926       
07927       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
07928          maxmsg = MAXMSG;
07929       } else {
07930          maxmsg = atoi(maxmsgstr);
07931          if (maxmsg <= 0) {
07932             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
07933             maxmsg = MAXMSG;
07934          } else if (maxmsg > MAXMSGLIMIT) {
07935             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
07936             maxmsg = MAXMSGLIMIT;
07937          }
07938       }
07939 
07940       /* Load date format config for voicemail mail */
07941       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
07942          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
07943       }
07944 
07945       /* External password changing command */
07946       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
07947          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
07948       }
07949 #ifdef IMAP_STORAGE
07950       /* IMAP server address */
07951       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
07952          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
07953       } else {
07954          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
07955       }
07956       /* IMAP server port */
07957       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
07958          ast_copy_string(imapport, imap_port, sizeof(imapport));
07959       } else {
07960          ast_copy_string(imapport,"143", sizeof(imapport));
07961       }
07962       /* IMAP server flags */
07963       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
07964          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
07965       }
07966       /* IMAP server master username */
07967       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
07968          ast_copy_string(authuser, auth_user, sizeof(authuser));
07969       }
07970       /* IMAP server master password */
07971       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
07972          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
07973       }
07974       /* Expunge on exit */
07975       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
07976          if (ast_false(expunge_on_hangup))
07977             expungeonhangup = 0;
07978          else
07979             expungeonhangup = 1;
07980       } else {
07981          expungeonhangup = 1;
07982       }
07983       /* IMAP voicemail folder */
07984       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
07985          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
07986       } else {
07987          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
07988       }
07989 
07990       /* There is some very unorthodox casting done here. This is due
07991        * to the way c-client handles the argument passed in. It expects a 
07992        * void pointer and casts the pointer directly to a long without
07993        * first dereferencing it. */
07994 
07995       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
07996          mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(imap_timeout)));
07997       } else {
07998          mail_parameters(NIL, SET_READTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
07999       }
08000 
08001       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
08002          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(imap_timeout)));
08003       } else {
08004          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08005       }
08006 
08007       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
08008          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(imap_timeout)));
08009       } else {
08010          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08011       }
08012 
08013       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
08014          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(imap_timeout)));
08015       } else {
08016          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08017       }
08018 
08019 #endif
08020       /* External voicemail notify application */
08021       
08022       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
08023          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
08024          if (option_debug > 2)
08025             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
08026          if (!strcasecmp(externnotify, "smdi")) {
08027             if (option_debug)
08028                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
08029             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
08030                smdi_iface = ast_smdi_interface_find(smdistr);
08031             } else {
08032                if (option_debug)
08033                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
08034                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
08035             }
08036 
08037             if (!smdi_iface) {
08038                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
08039                externnotify[0] = '\0';
08040             }
08041          }
08042       } else {
08043          externnotify[0] = '\0';
08044       }
08045 
08046       /* Silence treshold */
08047       silencethreshold = 256;
08048       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
08049          silencethreshold = atoi(thresholdstr);
08050       
08051       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
08052          astemail = ASTERISK_USERNAME;
08053       ast_copy_string(serveremail, astemail, sizeof(serveremail));
08054       
08055       vmmaxmessage = 0;
08056       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
08057          if (sscanf(s, "%d", &x) == 1) {
08058             vmmaxmessage = x;
08059          } else {
08060             ast_log(LOG_WARNING, "Invalid max message time length\n");
08061          }
08062       }
08063 
08064       vmminmessage = 0;
08065       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
08066          if (sscanf(s, "%d", &x) == 1) {
08067             vmminmessage = x;
08068             if (maxsilence <= vmminmessage)
08069                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
08070          } else {
08071             ast_log(LOG_WARNING, "Invalid min message time length\n");
08072          }
08073       }
08074       fmt = ast_variable_retrieve(cfg, "general", "format");
08075       if (!fmt)
08076          fmt = "wav";   
08077       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
08078 
08079       skipms = 3000;
08080       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
08081          if (sscanf(s, "%d", &x) == 1) {
08082             maxgreet = x;
08083          } else {
08084             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
08085          }
08086       }
08087 
08088       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
08089          if (sscanf(s, "%d", &x) == 1) {
08090             skipms = x;
08091          } else {
08092             ast_log(LOG_WARNING, "Invalid skipms value\n");
08093          }
08094       }
08095 
08096       maxlogins = 3;
08097       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
08098          if (sscanf(s, "%d", &x) == 1) {
08099             maxlogins = x;
08100          } else {
08101             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
08102          }
08103       }
08104 
08105       /* Force new user to record name ? */
08106       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
08107          astforcename = "no";
08108       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
08109 
08110       /* Force new user to record greetings ? */
08111       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
08112          astforcegreet = "no";
08113       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
08114 
08115       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
08116          if (option_debug > 2)
08117             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
08118          stringp = ast_strdupa(s);
08119          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
08120             if (!ast_strlen_zero(stringp)) {
08121                q = strsep(&stringp,",");
08122                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
08123                   q++;
08124                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
08125                if (option_debug > 2)
08126                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
08127             } else {
08128                cidinternalcontexts[x][0] = '\0';
08129             }
08130          }
08131       }
08132       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
08133          if (option_debug)
08134             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
08135          astreview = "no";
08136       }
08137       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
08138 
08139       /*Temperary greeting reminder */
08140       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
08141          if (option_debug)
08142             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
08143          asttempgreetwarn = "no";
08144       } else {
08145          if (option_debug)
08146             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
08147       }
08148       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
08149 
08150       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
08151          if (option_debug)
08152             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
08153          astcallop = "no";
08154       }
08155       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
08156 
08157       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
08158          if (option_debug)
08159             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
08160          astsaycid = "no";
08161       } 
08162       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
08163 
08164       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
08165          if (option_debug)
08166             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
08167          send_voicemail = "no";
08168       }
08169       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
08170    
08171       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
08172          if (option_debug)
08173             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
08174          asthearenv = "yes";
08175       }
08176       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
08177 
08178       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
08179          if (option_debug)
08180             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
08181          astsaydurationinfo = "yes";
08182       }
08183       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
08184 
08185       saydurationminfo = 2;
08186       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
08187          if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
08188             saydurationminfo = x;
08189          } else {
08190             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
08191          }
08192       }
08193 
08194       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
08195          if (option_debug)
08196             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
08197          astskipcmd = "no";
08198       }
08199       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
08200 
08201       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
08202          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
08203          if (option_debug)
08204             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
08205       } else {
08206          dialcontext[0] = '\0';  
08207       }
08208       
08209       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
08210          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
08211          if (option_debug)
08212             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
08213       } else {
08214          callcontext[0] = '\0';
08215       }
08216 
08217       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
08218          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
08219          if (option_debug)
08220             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
08221       } else {
08222          exitcontext[0] = '\0';
08223       }
08224 
08225       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
08226          astdirfwd = "no";
08227       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
08228       if ((ucfg = ast_config_load("users.conf"))) {   
08229          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
08230             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
08231                continue;
08232             if ((cur = find_or_create(userscontext, cat))) {
08233                populate_defaults(cur);
08234                apply_options_full(cur, ast_variable_browse(ucfg, cat));
08235                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
08236             }
08237          }
08238          ast_config_destroy(ucfg);
08239       }
08240       cat = ast_category_browse(cfg, NULL);
08241       while (cat) {
08242          if (strcasecmp(cat, "general")) {
08243             var = ast_variable_browse(cfg, cat);
08244             if (strcasecmp(cat, "zonemessages")) {
08245                /* Process mailboxes in this context */
08246                while (var) {
08247                   append_mailbox(cat, var->name, var->value);
08248                   var = var->next;
08249                }
08250             } else {
08251                /* Timezones in this context */
08252                while (var) {
08253                   struct vm_zone *z;
08254                   if ((z = ast_malloc(sizeof(*z)))) {
08255                      char *msg_format, *timezone;
08256                      msg_format = ast_strdupa(var->value);
08257                      timezone = strsep(&msg_format, "|");
08258                      if (msg_format) {
08259                         ast_copy_string(z->name, var->name, sizeof(z->name));
08260                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
08261                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
08262                         AST_LIST_LOCK(&zones);
08263                         AST_LIST_INSERT_HEAD(&zones, z, list);
08264                         AST_LIST_UNLOCK(&zones);
08265                      } else {
08266                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
08267                         free(z);
08268                      }
08269                   } else {
08270                      free(z);
08271                      AST_LIST_UNLOCK(&users);
08272                      ast_config_destroy(cfg);
08273                      return -1;
08274                   }
08275                   var = var->next;
08276                }
08277             }
08278          }
08279          cat = ast_category_browse(cfg, cat);
08280       }
08281       memset(fromstring,0,sizeof(fromstring));
08282       memset(pagerfromstring,0,sizeof(pagerfromstring));
08283       memset(emailtitle,0,sizeof(emailtitle));
08284       strcpy(charset, "ISO-8859-1");
08285       if (emailbody) {
08286          free(emailbody);
08287          emailbody = NULL;
08288       }
08289       if (emailsubject) {
08290          free(emailsubject);
08291          emailsubject = NULL;
08292       }
08293       if (pagerbody) {
08294          free(pagerbody);
08295          pagerbody = NULL;
08296       }
08297       if (pagersubject) {
08298          free(pagersubject);
08299          pagersubject = NULL;
08300       }
08301       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
08302          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
08303       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
08304          ast_copy_string(fromstring,s,sizeof(fromstring));
08305       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
08306          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
08307       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
08308          ast_copy_string(charset,s,sizeof(charset));
08309       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
08310          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08311          for (x = 0; x < 4; x++) {
08312             memcpy(&adsifdn[x], &tmpadsi[x], 1);
08313          }
08314       }
08315       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
08316          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08317          for (x = 0; x < 4; x++) {
08318             memcpy(&adsisec[x], &tmpadsi[x], 1);
08319          }
08320       }
08321       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
08322          if (atoi(s)) {
08323             adsiver = atoi(s);
08324          }
08325       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
08326          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
08327          ast_copy_string(emailtitle,s,sizeof(emailtitle));
08328       }
08329       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
08330          emailsubject = ast_strdup(s);
08331       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
08332          char *tmpread, *tmpwrite;
08333          emailbody = ast_strdup(s);
08334 
08335          /* substitute strings \t and \n into the appropriate characters */
08336          tmpread = tmpwrite = emailbody;
08337          while ((tmpwrite = strchr(tmpread,'\\'))) {
08338             switch (tmpwrite[1]) {
08339             case 'r':
08340                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08341                *tmpwrite = '\r';
08342                break;
08343             case 'n':
08344                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08345                *tmpwrite = '\n';
08346                break;
08347             case 't':
08348                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08349                *tmpwrite = '\t';
08350                break;
08351             default:
08352                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08353             }
08354             tmpread = tmpwrite + 1;
08355          }
08356       }
08357       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
08358          pagersubject = ast_strdup(s);
08359       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
08360          char *tmpread, *tmpwrite;
08361          pagerbody = ast_strdup(s);
08362 
08363          /* substitute strings \t and \n into the appropriate characters */
08364          tmpread = tmpwrite = pagerbody;
08365          while ((tmpwrite = strchr(tmpread, '\\'))) {
08366             switch (tmpwrite[1]) {
08367             case 'r':
08368                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08369                *tmpwrite = '\r';
08370                break;
08371             case 'n':
08372                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08373                *tmpwrite = '\n';
08374                break;
08375             case 't':
08376                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08377                *tmpwrite = '\t';
08378                break;
08379             default:
08380                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08381             }
08382             tmpread = tmpwrite + 1;
08383          }
08384       }
08385       AST_LIST_UNLOCK(&users);
08386       ast_config_destroy(cfg);
08387       return 0;
08388    } else {
08389       AST_LIST_UNLOCK(&users);
08390       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
08391       return 0;
08392    }
08393 }

static int load_module ( void   )  [static]

Definition at line 8416 of file app_voicemail.c.

References app, app2, app3, app4, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_free, ast_install_vm_functions(), ast_log(), ast_module_helper(), AST_MODULE_LOAD_DECLINE, ast_register_application(), cli_voicemail, descrip_vm, descrip_vm_box_exists, descrip_vmain, descrip_vmauthenticate, free, has_voicemail(), inboxcount(), load_config(), LOG_ERROR, 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().

08417 {
08418    int res;
08419    char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
08420    free(adsi_loaded);
08421    if (!adsi_loaded) {
08422       /* If embedded, res_adsi may be known as "res_adsi" not "res_adsi.so" */
08423       adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
08424       ast_free(adsi_loaded);
08425       if (!adsi_loaded) {
08426          ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
08427          return AST_MODULE_LOAD_DECLINE;
08428       }
08429    }
08430 
08431    my_umask = umask(0);
08432    umask(my_umask);
08433    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
08434    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
08435    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
08436    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
08437    if (res)
08438       return(res);
08439 
08440    if ((res=load_config())) {
08441       return(res);
08442    }
08443 
08444    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08445 
08446    /* compute the location of the voicemail spool directory */
08447    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
08448 
08449    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
08450 
08451    return res;
08452 }

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

Definition at line 894 of file app_voicemail.c.

References VM_SPOOL_DIR.

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

00895 {
00896    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00897 }

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 2974 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, ast_vm_user::mailbox, my_umask, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), strip_control(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

02975 {
02976    char date[256];
02977    char host[MAXHOSTNAMELEN] = "";
02978    char who[256];
02979    char bound[256];
02980    char fname[256];
02981    char dur[256];
02982    char tmpcmd[256];
02983    char enc_cidnum[256] = "", enc_cidname[256] = "";
02984    struct tm tm;
02985    char *passdata2;
02986    size_t len_passdata;
02987 #ifdef IMAP_STORAGE
02988 #define ENDL "\r\n"
02989 #else
02990 #define ENDL "\n"
02991 #endif
02992 
02993    if (cidnum) {
02994       strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum));
02995    }
02996    if (cidname) {
02997       strip_control(cidname, enc_cidname, sizeof(enc_cidname));
02998    }
02999    gethostname(host, sizeof(host) - 1);
03000    if (strchr(srcemail, '@'))
03001       ast_copy_string(who, srcemail, sizeof(who));
03002    else {
03003       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03004    }
03005    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03006    strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03007    fprintf(p, "Date: %s" ENDL, date);
03008 
03009    /* Set date format for voicemail mail */
03010    strftime(date, sizeof(date), emaildateformat, &tm);
03011 
03012    if (*fromstring) {
03013       struct ast_channel *ast;
03014       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
03015          char *passdata;
03016          int vmlen = strlen(fromstring)*3 + 200;
03017          if ((passdata = alloca(vmlen))) {
03018             memset(passdata, 0, vmlen);
03019             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, enc_cidnum, enc_cidname, dur, date, passdata, vmlen, category);
03020             pbx_substitute_variables_helper(ast, fromstring, passdata, vmlen);
03021             len_passdata = strlen(passdata) * 2 + 3;
03022             passdata2 = alloca(len_passdata);
03023             fprintf(p, "From: %s <%s>" ENDL, quote(passdata, passdata2, len_passdata), who);
03024          } else
03025             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03026          ast_channel_free(ast);
03027       } else
03028          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03029    } else
03030       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
03031    len_passdata = strlen(vmu->fullname) * 2 + 3;
03032    passdata2 = alloca(len_passdata);
03033    fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata), vmu->email);
03034    if (emailsubject) {
03035       struct ast_channel *ast;
03036       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
03037          char *passdata;
03038          int vmlen = strlen(emailsubject)*3 + 200;
03039          if ((passdata = alloca(vmlen))) {
03040             memset(passdata, 0, vmlen);
03041             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03042             pbx_substitute_variables_helper(ast, emailsubject, passdata, vmlen);
03043             fprintf(p, "Subject: %s" ENDL, passdata);
03044          } else {
03045             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03046          }
03047          ast_channel_free(ast);
03048       } else {
03049          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03050       }
03051    } else   if (*emailtitle) {
03052       fprintf(p, emailtitle, msgnum + 1, mailbox) ;
03053       fprintf(p, ENDL) ;
03054    } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
03055       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03056    } else {
03057       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03058    }
03059    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
03060    if (imap) {
03061       /* additional information needed for IMAP searching */
03062       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
03063       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
03064       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
03065       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
03066       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
03067       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
03068       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
03069       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
03070       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
03071       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
03072       if (!ast_strlen_zero(category)) {
03073          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
03074       }
03075       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
03076       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
03077    }
03078    if (!ast_strlen_zero(cidnum)) {
03079       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
03080    }
03081    if (!ast_strlen_zero(cidname)) {
03082       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
03083    }
03084    fprintf(p, "MIME-Version: 1.0" ENDL);
03085    if (attach_user_voicemail) {
03086       /* Something unique. */
03087       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
03088 
03089       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
03090       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
03091       fprintf(p, "--%s" ENDL, bound);
03092    }
03093    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
03094    if (emailbody) {
03095       struct ast_channel *ast;
03096       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
03097          char *passdata;
03098          int vmlen = strlen(emailbody)*3 + 200;
03099          if ((passdata = alloca(vmlen))) {
03100             memset(passdata, 0, vmlen);
03101             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03102             pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
03103             fprintf(p, "%s" ENDL, passdata);
03104          } else
03105             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03106          ast_channel_free(ast);
03107       } else
03108          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03109    } else {
03110       fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a %s long message (number %d)" ENDL
03111 
03112       "in mailbox %s from %s, on %s so you might" ENDL
03113       "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, 
03114       dur, msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
03115    }
03116    if (attach_user_voicemail) {
03117       /* Eww. We want formats to tell us their own MIME type */
03118       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
03119       char tmpdir[256], newtmp[256];
03120       int tmpfd = -1;
03121    
03122       if (vmu->volgain < -.001 || vmu->volgain > .001) {
03123          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
03124          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
03125          tmpfd = mkstemp(newtmp);
03126          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
03127          if (option_debug > 2)
03128             ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
03129          if (tmpfd > -1) {
03130             int soxstatus;
03131             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
03132             if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
03133                attach = newtmp;
03134                if (option_debug > 2) {
03135                   ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
03136                }
03137             } else {
03138                ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
03139                   soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
03140                ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
03141             }
03142          }
03143       }
03144       fprintf(p, "--%s" ENDL, bound);
03145       fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
03146       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
03147       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
03148       fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
03149       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
03150       base_encode(fname, p);
03151       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
03152       if (tmpfd > -1) {
03153          unlink(fname);
03154          close(tmpfd);
03155          unlink(newtmp);
03156       }
03157    }
03158 #undef ENDL
03159 }

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

Definition at line 899 of file app_voicemail.c.

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

00900 {
00901    return snprintf(dest, len, "%s/msg%04d", dir, num);
00902 }

static char* mbox ( int  id  )  [static]

Definition at line 956 of file app_voicemail.c.

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

00957 {
00958    static char *msgs[] = {
00959       "INBOX",
00960       "Old",
00961       "Work",
00962       "Family",
00963       "Friends",
00964       "Cust1",
00965       "Cust2",
00966       "Cust3",
00967       "Cust4",
00968       "Cust5",
00969    };
00970    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
00971 }

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

Definition at line 3548 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

03549 {
03550    return __has_voicemail(context, mailbox, folder, 0);
03551 }

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

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

Referenced by copy_message(), and leave_voicemail().

04803 {
04804    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
04805    int newmsgs = 0, oldmsgs = 0;
04806    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
04807 
04808    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
04809    make_file(fn, sizeof(fn), todir, msgnum);
04810    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
04811 
04812    if (!ast_strlen_zero(vmu->attachfmt)) {
04813       if (strstr(fmt, vmu->attachfmt)) {
04814          fmt = vmu->attachfmt;
04815       } else {
04816          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);
04817       }
04818    }
04819 
04820    /* Attach only the first format */
04821    fmt = ast_strdupa(fmt);
04822    stringp = fmt;
04823    strsep(&stringp, "|");
04824 
04825    if (!ast_strlen_zero(vmu->email)) {
04826       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
04827       char *myserveremail = serveremail;
04828       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
04829       if (!ast_strlen_zero(vmu->serveremail))
04830          myserveremail = vmu->serveremail;
04831       
04832       if (attach_user_voicemail)
04833          RETRIEVE(todir, msgnum, vmu);
04834 
04835       /*XXX possible imap issue, should category be NULL XXX*/
04836       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
04837 
04838       if (attach_user_voicemail)
04839          DISPOSE(todir, msgnum);
04840    }
04841 
04842    if (!ast_strlen_zero(vmu->pager)) {
04843       char *myserveremail = serveremail;
04844       if (!ast_strlen_zero(vmu->serveremail))
04845          myserveremail = vmu->serveremail;
04846       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
04847    }
04848 
04849    if (ast_test_flag(vmu, VM_DELETE)) {
04850       DELETE(todir, msgnum, fn, vmu);
04851    }
04852 
04853    /* Leave voicemail for someone */
04854    if (ast_app_has_voicemail(ext_context, NULL)) {
04855       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
04856    }
04857    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);
04858    run_externnotify(vmu->context, vmu->mailbox);
04859    return 0;
04860 }

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

Definition at line 2829 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

02830 {
02831    if (bio->linelength>=BASELINELEN) {
02832       if (fputs(eol,so)==EOF)
02833          return -1;
02834 
02835       bio->linelength= 0;
02836    }
02837 
02838    if (putc(((unsigned char)c),so)==EOF)
02839       return -1;
02840 
02841    bio->linelength++;
02842 
02843    return 1;
02844 }

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

Definition at line 5401 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, resequence_mailbox(), vm_state::username, and vm_state::vmbox.

Referenced by vm_execmain().

05402 {
05403    int res = 0;
05404    int count_msg, last_msg;
05405 
05406    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
05407    
05408    /* Rename the member vmbox HERE so that we don't try to return before
05409     * we know what's going on.
05410     */
05411    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
05412    
05413    /* Faster to make the directory than to check if it exists. */
05414    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
05415 
05416    count_msg = count_messages(vmu, vms->curdir);
05417    if (count_msg < 0)
05418       return count_msg;
05419    else
05420       vms->lastmsg = count_msg - 1;
05421 
05422    /*
05423    The following test is needed in case sequencing gets messed up.
05424    There appears to be more than one way to mess up sequence, so
05425    we will not try to find all of the root causes--just fix it when
05426    detected.
05427    */
05428 
05429    last_msg = last_message_index(vmu, vms->curdir);
05430    if (last_msg < 0)
05431       return last_msg;
05432    else if (vms->lastmsg != last_msg)
05433    {
05434       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
05435       res = resequence_mailbox(vmu, vms->curdir);
05436       if (res)
05437          return res;
05438    }
05439 
05440    return 0;
05441 }

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

Definition at line 3286 of file app_voicemail.c.

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

Referenced by invent_message(), and leave_voicemail().

03287 {
03288    int res = -2;
03289 
03290 #ifdef ODBC_STORAGE
03291    int success = 
03292 #endif
03293    RETRIEVE(filename, -1, vmu);
03294    if (ast_fileexists(filename, NULL, NULL) > 0) {
03295       res = ast_streamfile(chan, filename, chan->language);
03296       if (res > -1) 
03297          res = ast_waitstream(chan, ecodes);
03298 #ifdef ODBC_STORAGE
03299       if (success == -1) {
03300          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03301          if (option_debug)
03302             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03303          store_file(filename, vmu->mailbox, vmu->context, -1);
03304       }
03305 #endif
03306    }
03307    DISPOSE(filename, -1);
03308 
03309    return res;
03310 }

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

Definition at line 5300 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, 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_latin(), and vm_execmain().

05301 {
05302    int res = 0;
05303    char filename[256], *cid;
05304    const char *origtime, *context, *category, *duration;
05305    struct ast_config *msg_cfg;
05306 
05307    vms->starting = 0; 
05308    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05309    adsi_message(chan, vms);
05310    if (!vms->curmsg)
05311       res = wait_file2(chan, vms, "vm-first");  /* "First" */
05312    else if (vms->curmsg == vms->lastmsg)
05313       res = wait_file2(chan, vms, "vm-last");      /* "last" */
05314    if (!res) {
05315       /* POLISH syntax */
05316       if (!strncasecmp(chan->language, "pl",2)) { 
05317          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05318             int ten, one;
05319             char nextmsg[256];
05320             ten = (vms->curmsg + 1) / 10;
05321             one = (vms->curmsg + 1) % 10;
05322             
05323             if (vms->curmsg < 20) {
05324                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
05325                res = wait_file2(chan, vms, nextmsg);
05326             } else {
05327                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
05328                res = wait_file2(chan, vms, nextmsg);
05329                if (one > 0) {
05330                   if (!res) {
05331                      snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
05332                      res = wait_file2(chan, vms, nextmsg);
05333                   }
05334                }
05335             }
05336          }
05337          if (!res)
05338             res = wait_file2(chan, vms, "vm-message");
05339       } else {
05340          if (!strncasecmp(chan->language,"se",2)) /* SWEDISH syntax */
05341             res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
05342          else /* DEFAULT syntax */
05343             res = wait_file2(chan, vms, "vm-message");
05344          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05345             if (!res)
05346                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05347          }
05348       }
05349    }
05350 
05351    /* Retrieve info from VM attribute file */
05352    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
05353    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
05354    RETRIEVE(vms->curdir, vms->curmsg, vmu);
05355    msg_cfg = ast_config_load(filename);
05356    if (!msg_cfg) {
05357       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
05358       return 0;
05359    }
05360 
05361    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
05362       ast_log(LOG_WARNING, "No origtime?!\n");
05363       DISPOSE(vms->curdir, vms->curmsg);
05364       ast_config_destroy(msg_cfg);
05365       return 0;
05366    }
05367 
05368    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
05369    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
05370    category = ast_variable_retrieve(msg_cfg, "message", "category");
05371 
05372    context = ast_variable_retrieve(msg_cfg, "message", "context");
05373    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
05374       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
05375    if (!res)
05376       res = play_message_category(chan, category);
05377    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
05378       res = play_message_datetime(chan, vmu, origtime, filename);
05379    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
05380       res = play_message_callerid(chan, vms, cid, context, 0);
05381    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
05382       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
05383    /* Allow pressing '1' to skip envelope / callerid */
05384    if (res == '1')
05385       res = 0;
05386    ast_config_destroy(msg_cfg);
05387 
05388    if (!res) {
05389       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05390       vms->heard[vms->curmsg] = 1;
05391       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
05392          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
05393          res = 0;
05394       }
05395    }
05396    DISPOSE(vms->curdir, vms->curmsg);
05397    return res;
05398 }

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

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

05183 {
05184    int res = 0;
05185    int i;
05186    char *callerid, *name;
05187    char prefile[PATH_MAX] = "";
05188    
05189 
05190    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
05191    /* 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 */
05192    if ((cid == NULL)||(context == NULL))
05193       return res;
05194 
05195    /* Strip off caller ID number from name */
05196    if (option_debug > 2)
05197       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05198    ast_callerid_parse(cid, &name, &callerid);
05199    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05200       /* Check for internal contexts and only */
05201       /* say extension when the call didn't come from an internal context in the list */
05202       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
05203          if (option_debug > 2)
05204             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05205          if ((strcmp(cidinternalcontexts[i], context) == 0))
05206             break;
05207       }
05208       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
05209          if (!res) {
05210             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05211             if (!ast_strlen_zero(prefile)) {
05212             /* See if we can find a recorded name for this person instead of their extension number */
05213                if (ast_fileexists(prefile, NULL, NULL) > 0) {
05214                   if (option_verbose > 2)
05215                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05216                   if (!callback)
05217                      res = wait_file2(chan, vms, "vm-from");
05218                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
05219                } else {
05220                   if (option_verbose > 2)
05221                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
05222                   /* BB: Say "from extension" as one saying to sound smoother */
05223                   if (!callback)
05224                      res = wait_file2(chan, vms, "vm-from-extension");
05225                   res = ast_say_digit_str(chan, callerid, "", chan->language);
05226                }
05227             }
05228          }
05229       }
05230 
05231       else if (!res){
05232          if (option_debug > 2)
05233             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
05234          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
05235          if (!callback)
05236             res = wait_file2(chan, vms, "vm-from-phonenumber");
05237          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05238       }
05239    } else {
05240       /* Number unknown */
05241       if (option_debug)
05242          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
05243       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05244       res = wait_file2(chan, vms, "vm-unknown-caller");
05245    }
05246    return res;
05247 }

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

Definition at line 5097 of file app_voicemail.c.

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

Referenced by play_message().

05098 {
05099    int res = 0;
05100 
05101    if (!ast_strlen_zero(category))
05102       res = ast_play_and_wait(chan, category);
05103 
05104    if (res) {
05105       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05106       res = 0;
05107    }
05108 
05109    return res;
05110 }

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

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

Referenced by advanced_options(), and play_message().

05113 {
05114    int res = 0;
05115    struct vm_zone *the_zone = NULL;
05116    time_t t;
05117 
05118    if (ast_get_time_t(origtime, &t, 0, NULL)) {
05119       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05120       return 0;
05121    }
05122 
05123    /* Does this user have a timezone specified? */
05124    if (!ast_strlen_zero(vmu->zonetag)) {
05125       /* Find the zone in the list */
05126       struct vm_zone *z;
05127       AST_LIST_LOCK(&zones);
05128       AST_LIST_TRAVERSE(&zones, z, list) {
05129          if (!strcmp(z->name, vmu->zonetag)) {
05130             the_zone = z;
05131             break;
05132          }
05133       }
05134       AST_LIST_UNLOCK(&zones);
05135    }
05136 
05137 /* No internal variable parsing for now, so we'll comment it out for the time being */
05138 #if 0
05139    /* Set the DIFF_* variables */
05140    ast_localtime(&t, &time_now, NULL);
05141    tv_now = ast_tvnow();
05142    tnow = tv_now.tv_sec;
05143    ast_localtime(&tnow, &time_then, NULL);
05144 
05145    /* Day difference */
05146    if (time_now.tm_year == time_then.tm_year)
05147       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
05148    else
05149       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05150    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05151 
05152    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05153 #endif
05154    if (the_zone)
05155       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05156    else if (!strncasecmp(chan->language,"pl",2))       /* POLISH syntax */
05157       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05158    else if (!strncasecmp(chan->language,"se",2))       /* SWEDISH syntax */
05159       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05160    else if (!strncasecmp(chan->language,"no",2))       /* NORWEGIAN syntax */
05161       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05162    else if (!strncasecmp(chan->language,"de",2))       /* GERMAN syntax */
05163       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05164    else if (!strncasecmp(chan->language,"nl",2))      /* DUTCH syntax */
05165       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05166    else if (!strncasecmp(chan->language,"it",2))      /* ITALIAN syntax */
05167       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);
05168    else if (!strncasecmp(chan->language,"gr",2))
05169       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05170    else if (!strcasecmp(chan->language,"pt_BR"))
05171       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);      
05172    else
05173       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05174 #if 0
05175    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05176 #endif
05177    return res;
05178 }

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

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

05250 {
05251    int res = 0;
05252    int durationm;
05253    int durations;
05254    /* Verify that we have a duration for the message */
05255    if (duration == NULL)
05256       return res;
05257 
05258    /* Convert from seconds to minutes */
05259    durations=atoi(duration);
05260    durationm=(durations / 60);
05261 
05262    if (option_debug > 2)
05263       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05264 
05265    if ((!res) && (durationm >= minduration)) {
05266       res = wait_file2(chan, vms, "vm-duration");
05267 
05268       /* POLISH syntax */
05269       if (!strncasecmp(chan->language, "pl",2)) {
05270          div_t num = div(durationm, 10);
05271 
05272          if (durationm == 1) {
05273             res = ast_play_and_wait(chan, "digits/1z");
05274             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05275          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05276             if (num.rem == 2) {
05277                if (!num.quot) {
05278                   res = ast_play_and_wait(chan, "digits/2-ie");
05279                } else {
05280                   res = say_and_wait(chan, durationm - 2 , chan->language);
05281                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05282                }
05283             } else {
05284                res = say_and_wait(chan, durationm, chan->language);
05285             }
05286             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05287          } else {
05288             res = say_and_wait(chan, durationm, chan->language);
05289             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05290          }
05291       /* DEFAULT syntax */
05292       } else {
05293          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05294          res = wait_file2(chan, vms, "vm-minutes");
05295       }
05296    }
05297    return res;
05298 }

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

08709 {
08710    /* Record message & let caller review or re-record it, or set options if applicable */
08711    int res = 0;
08712    int cmd = 0;
08713    int max_attempts = 3;
08714    int attempts = 0;
08715    int recorded = 0;
08716    int message_exists = 0;
08717    signed char zero_gain = 0;
08718    char tempfile[PATH_MAX];
08719    char *acceptdtmf = "#";
08720    char *canceldtmf = "";
08721 
08722    /* Note that urgent and private are for flagging messages as such in the future */
08723 
08724    /* barf if no pointer passed to store duration in */
08725    if (duration == NULL) {
08726       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
08727       return -1;
08728    }
08729 
08730    if (!outsidecaller)
08731       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
08732    else
08733       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
08734 
08735    cmd = '3';  /* Want to start by recording */
08736 
08737    while ((cmd >= 0) && (cmd != 't')) {
08738       switch (cmd) {
08739       case '1':
08740          if (!message_exists) {
08741             /* In this case, 1 is to record a message */
08742             cmd = '3';
08743             break;
08744          } else {
08745             /* Otherwise 1 is to save the existing message */
08746             if (option_verbose > 2)
08747                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
08748             if (!outsidecaller)
08749                ast_filerename(tempfile, recordfile, NULL);
08750             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
08751             if (!outsidecaller) {
08752                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
08753                DISPOSE(recordfile, -1);
08754             }
08755             cmd = 't';
08756             return res;
08757          }
08758       case '2':
08759          /* Review */
08760          if (option_verbose > 2)
08761             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
08762          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
08763          break;
08764       case '3':
08765          message_exists = 0;
08766          /* Record */
08767          if (recorded == 1) {
08768             if (option_verbose > 2)
08769                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
08770          } else { 
08771             if (option_verbose > 2)
08772                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
08773          }
08774          if (recorded && outsidecaller) {
08775             cmd = ast_play_and_wait(chan, INTRO);
08776             cmd = ast_play_and_wait(chan, "beep");
08777          }
08778          recorded = 1;
08779          /* 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 */
08780          if (record_gain)
08781             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
08782          if (ast_test_flag(vmu, VM_OPERATOR))
08783             canceldtmf = "0";
08784          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
08785          if (record_gain)
08786             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
08787          if (cmd == -1) {
08788             /* User has hung up, no options to give */
08789             if (!outsidecaller) {
08790                /* user was recording a greeting and they hung up, so let's delete the recording. */
08791                ast_filedelete(tempfile, NULL);
08792             }
08793             return cmd;
08794          }
08795          if (cmd == '0') {
08796             break;
08797          } else if (cmd == '*') {
08798             break;
08799          } 
08800 #if 0       
08801          else if (vmu->review && (*duration < 5)) {
08802             /* Message is too short */
08803             if (option_verbose > 2)
08804                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
08805             cmd = ast_play_and_wait(chan, "vm-tooshort");
08806             cmd = ast_filedelete(tempfile, NULL);
08807             break;
08808          }
08809          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
08810             /* Message is all silence */
08811             if (option_verbose > 2)
08812                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
08813             cmd = ast_filedelete(tempfile, NULL);
08814             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
08815             if (!cmd)
08816                cmd = ast_play_and_wait(chan, "vm-speakup");
08817             break;
08818          }
08819 #endif
08820          else {
08821             /* If all is well, a message exists */
08822             message_exists = 1;
08823             cmd = 0;
08824          }
08825          break;
08826       case '4':
08827       case '5':
08828       case '6':
08829       case '7':
08830       case '8':
08831       case '9':
08832       case '*':
08833       case '#':
08834          cmd = ast_play_and_wait(chan, "vm-sorry");
08835          break;
08836 #if 0 
08837 /*  XXX Commented out for the moment because of the dangers of deleting
08838     a message while recording (can put the message numbers out of sync) */
08839       case '*':
08840          /* Cancel recording, delete message, offer to take another message*/
08841          cmd = ast_play_and_wait(chan, "vm-deleted");
08842          cmd = ast_filedelete(tempfile, NULL);
08843          if (outsidecaller) {
08844             res = vm_exec(chan, NULL);
08845             return res;
08846          }
08847          else
08848             return 1;
08849 #endif
08850       case '0':
08851          if (!ast_test_flag(vmu, VM_OPERATOR)) {
08852             cmd = ast_play_and_wait(chan, "vm-sorry");
08853             break;
08854          }
08855          if (message_exists || recorded) {
08856             cmd = ast_play_and_wait(chan, "vm-saveoper");
08857             if (!cmd)
08858                cmd = ast_waitfordigit(chan, 3000);
08859             if (cmd == '1') {
08860                ast_play_and_wait(chan, "vm-msgsaved");
08861                cmd = '0';
08862             } else {
08863                ast_play_and_wait(chan, "vm-deleted");
08864                DELETE(recordfile, -1, recordfile, vmu);
08865                cmd = '0';
08866             }
08867          }
08868          return cmd;
08869       default:
08870          /* If the caller is an ouside caller, and the review option is enabled,
08871             allow them to review the message, but let the owner of the box review
08872             their OGM's */
08873          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
08874             return cmd;
08875          if (message_exists) {
08876             cmd = ast_play_and_wait(chan, "vm-review");
08877          }
08878          else {
08879             cmd = ast_play_and_wait(chan, "vm-torerecord");
08880             if (!cmd)
08881                cmd = ast_waitfordigit(chan, 600);
08882          }
08883          
08884          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
08885             cmd = ast_play_and_wait(chan, "vm-reachoper");
08886             if (!cmd)
08887                cmd = ast_waitfordigit(chan, 600);
08888          }
08889 #if 0
08890          if (!cmd)
08891             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
08892 #endif
08893          if (!cmd)
08894             cmd = ast_waitfordigit(chan, 6000);
08895          if (!cmd) {
08896             attempts++;
08897          }
08898          if (attempts > max_attempts) {
08899             cmd = 't';
08900          }
08901       }
08902    }
08903    if (outsidecaller)
08904       ast_play_and_wait(chan, "vm-goodbye");
08905    if (cmd == 't')
08906       cmd = 0;
08907    return cmd;
08908 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

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

00591 {
00592    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00593    if (saydurationminfo)
00594       vmu->saydurationm = saydurationminfo;
00595    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00596    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00597    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00598    if (maxmsg)
00599       vmu->maxmsg = maxmsg;
00600    vmu->volgain = volgain;
00601 }

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 2918 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().

02919 {
02920    char callerid[256];
02921    /* Prepare variables for substition in email body and subject */
02922    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
02923    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
02924    snprintf(passdata, passdatasize, "%d", msgnum);
02925    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
02926    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
02927    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
02928    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
02929    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
02930    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
02931    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
02932    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
02933 }

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

Definition at line 2935 of file app_voicemail.c.

02936 {
02937    char *ptr = to;
02938    *ptr++ = '"';
02939    for (; ptr < to + len - 1; from++) {
02940       if (*from == '"')
02941          *ptr++ = '\\';
02942       else if (*from == '\0')
02943          break;
02944       *ptr++ = *from;
02945    }
02946    if (ptr < to + len - 1)
02947       *ptr++ = '"';
02948    *ptr = '\0';
02949    return to;
02950 }

static int reload ( void   )  [static]

Definition at line 8395 of file app_voicemail.c.

References load_config().

08396 {
08397    return(load_config());
08398 }

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

Definition at line 2663 of file app_voicemail.c.

References ast_filerename().

02664 {
02665    char stxt[PATH_MAX];
02666    char dtxt[PATH_MAX];
02667    ast_filerename(sfn,dfn,NULL);
02668    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02669    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02670    rename(stxt, dtxt);
02671 }

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

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

04080 {
04081    /* we know max messages, so stop process when number is hit */
04082 
04083    int x,dest;
04084    char sfn[PATH_MAX];
04085    char dfn[PATH_MAX];
04086 
04087    if (vm_lock_path(dir))
04088       return ERROR_LOCK_PATH;
04089 
04090    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
04091       make_file(sfn, sizeof(sfn), dir, x);
04092       if (EXISTS(dir, x, sfn, NULL)) {
04093          
04094          if (x != dest) {
04095             make_file(dfn, sizeof(dfn), dir, dest);
04096             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04097          }
04098          
04099          dest++;
04100       }
04101    }
04102    ast_unlock_path(dir);
04103 
04104    return 0;
04105 }

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

Definition at line 789 of file app_voicemail.c.

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

Referenced by vm_change_password(), and vm_change_password_shell().

00790 {
00791    /* This function could be made to generate one from a database, too */
00792    struct ast_vm_user *cur;
00793    int res = -1;
00794    AST_LIST_LOCK(&users);
00795    AST_LIST_TRAVERSE(&users, cur, list) {
00796       if ((!context || !strcasecmp(context, cur->context)) &&
00797          (!strcasecmp(mailbox, cur->mailbox)))
00798             break;
00799    }
00800    if (cur) {
00801       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00802       res = 0;
00803    }
00804    AST_LIST_UNLOCK(&users);
00805    return res;
00806 }

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

Definition at line 3649 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_station(), 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, option_debug, smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.

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

03650 {
03651    char arguments[255];
03652    char ext_context[256] = "";
03653    int newvoicemails = 0, oldvoicemails = 0;
03654    struct ast_smdi_mwi_message *mwi_msg;
03655 
03656    if (!ast_strlen_zero(context))
03657       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
03658    else
03659       ast_copy_string(ext_context, extension, sizeof(ext_context));
03660 
03661    if (!strcasecmp(externnotify, "smdi")) {
03662       if (ast_app_has_voicemail(ext_context, NULL)) 
03663          ast_smdi_mwi_set(smdi_iface, extension);
03664       else
03665          ast_smdi_mwi_unset(smdi_iface, extension);
03666 
03667       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
03668          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
03669          if (!strncmp(mwi_msg->cause, "INV", 3))
03670             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
03671          else if (!strncmp(mwi_msg->cause, "BLK", 3))
03672             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
03673          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
03674          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
03675       } else {
03676          if (option_debug)
03677             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
03678       }
03679    } else if (!ast_strlen_zero(externnotify)) {
03680       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
03681          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
03682       } else {
03683          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
03684          if (option_debug)
03685             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
03686          ast_safe_system(arguments);
03687       }
03688    }
03689 }

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

Definition at line 4115 of file app_voicemail.c.

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

Referenced by vm_execmain().

04116 {
04117 #ifdef IMAP_STORAGE
04118    /* we must use mbox(x) folder names, and copy the message there */
04119    /* simple. huh? */
04120    char sequence[10];
04121    /* get the real IMAP message number for this message */
04122    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04123    if (option_debug > 2)
04124       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
04125    if (box == 1) {
04126       mail_setflag(vms->mailstream, sequence, "\\Seen");
04127    } else if (box == 0) {
04128       mail_clearflag(vms->mailstream, sequence, "\\Seen");
04129    }
04130    if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1))
04131       return 0;
04132    else 
04133       return !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
04134 #else
04135    char *dir = vms->curdir;
04136    char *username = vms->username;
04137    char *context = vmu->context;
04138    char sfn[PATH_MAX];
04139    char dfn[PATH_MAX];
04140    char ddir[PATH_MAX];
04141    const char *dbox = mbox(box);
04142    int x;
04143    make_file(sfn, sizeof(sfn), dir, msg);
04144    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04145 
04146    if (vm_lock_path(ddir))
04147       return ERROR_LOCK_PATH;
04148 
04149    for (x = 0; x < vmu->maxmsg; x++) {
04150       make_file(dfn, sizeof(dfn), ddir, x);
04151       if (!EXISTS(ddir, x, dfn, NULL))
04152          break;
04153    }
04154    if (x >= vmu->maxmsg) {
04155       ast_unlock_path(ddir);
04156       return ERROR_MAILBOX_FULL;
04157    }
04158    if (strcmp(sfn, dfn)) {
04159       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04160    }
04161    ast_unlock_path(ddir);
04162 #endif
04163    return 0;
04164 }

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

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

04109 {
04110    int d;
04111    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04112    return d;
04113 }

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

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

Referenced by forward_message(), and notify_new_message().

03161 {
03162    FILE *p=NULL;
03163    char tmp[80] = "/tmp/astmail-XXXXXX";
03164    char tmp2[256];
03165 
03166    if (vmu && ast_strlen_zero(vmu->email)) {
03167       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03168       return(0);
03169    }
03170    if (!strcmp(format, "wav49"))
03171       format = "WAV";
03172    if (option_debug > 2)
03173       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));
03174    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03175       command hangs */
03176    if ((p = vm_mkftemp(tmp)) == NULL) {
03177       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03178       return -1;
03179    } else {
03180       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03181       fclose(p);
03182       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03183       ast_safe_system(tmp2);
03184       if (option_debug > 2)
03185          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03186    }
03187    return 0;
03188 }

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

References ast_channel_alloc(), ast_channel_free(), ast_log(), ast_safe_system(), AST_STATE_DOWN, fromstring, LOG_DEBUG, 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().

03191 {
03192    char date[256];
03193    char host[MAXHOSTNAMELEN] = "";
03194    char who[256];
03195    char dur[PATH_MAX];
03196    char tmp[80] = "/tmp/astmail-XXXXXX";
03197    char tmp2[PATH_MAX];
03198    struct tm tm;
03199    FILE *p;
03200 
03201    if ((p = vm_mkftemp(tmp)) == NULL) {
03202       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03203       return -1;
03204    } else {
03205       gethostname(host, sizeof(host)-1);
03206       if (strchr(srcemail, '@'))
03207          ast_copy_string(who, srcemail, sizeof(who));
03208       else {
03209          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03210       }
03211       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03212       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03213       fprintf(p, "Date: %s\n", date);
03214 
03215       if (*pagerfromstring) {
03216          struct ast_channel *ast;
03217          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
03218             char *passdata;
03219             int vmlen = strlen(fromstring)*3 + 200;
03220             if ((passdata = alloca(vmlen))) {
03221                memset(passdata, 0, vmlen);
03222                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03223                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
03224                fprintf(p, "From: %s <%s>\n", passdata, who);
03225             } else 
03226                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03227             ast_channel_free(ast);
03228          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03229       } else
03230          fprintf(p, "From: Asterisk PBX <%s>\n", who);
03231       fprintf(p, "To: %s\n", pager);
03232       if (pagersubject) {
03233          struct ast_channel *ast;
03234          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
03235             char *passdata;
03236             int vmlen = strlen(pagersubject) * 3 + 200;
03237             if ((passdata = alloca(vmlen))) {
03238                memset(passdata, 0, vmlen);
03239                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03240                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
03241                fprintf(p, "Subject: %s\n\n", passdata);
03242             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03243             ast_channel_free(ast);
03244          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03245       } else
03246          fprintf(p, "Subject: New VM\n\n");
03247       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
03248       if (pagerbody) {
03249          struct ast_channel *ast;
03250          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) {
03251             char *passdata;
03252             int vmlen = strlen(pagerbody)*3 + 200;
03253             if ((passdata = alloca(vmlen))) {
03254                memset(passdata, 0, vmlen);
03255                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, cidnum, cidname, dur, date, passdata, vmlen, category);
03256                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
03257                fprintf(p, "%s\n", passdata);
03258             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03259          ast_channel_free(ast);
03260          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03261       } else {
03262          fprintf(p, "New %s long msg in box %s\n"
03263                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
03264       }
03265       fclose(p);
03266       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03267       ast_safe_system(tmp2);
03268       if (option_debug > 2)
03269          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
03270    }
03271    return 0;
03272 }

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

Definition at line 574 of file app_voicemail.c.

Referenced by make_email_file().

00575 {
00576    char *bufptr = buf;
00577    for (; *input; input++) {
00578       if (*input < 32) {
00579          continue;
00580       }
00581       *bufptr++ = *input;
00582       if (bufptr == buf + buflen - 1) {
00583          break;
00584       }
00585    }
00586    *bufptr = '\0';
00587    return buf;
00588 }

static int unload_module ( void   )  [static]

Definition at line 8400 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.

08401 {
08402    int res;
08403    
08404    res = ast_unregister_application(app);
08405    res |= ast_unregister_application(app2);
08406    res |= ast_unregister_application(app3);
08407    res |= ast_unregister_application(app4);
08408    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08409    ast_uninstall_vm_functions();
08410    
08411    ast_module_user_hangup_all();
08412 
08413    return res;
08414 }

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 6791 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(), find_user(), LOG_DEBUG, option_debug, option_verbose, ast_vm_user::password, password, and VERBOSE_PREFIX_3.

Referenced by vm_execmain(), and vmauthenticate().

06794 {
06795    int useadsi=0, valid=0, logretries=0;
06796    char password[AST_MAX_EXTENSION]="", *passptr;
06797    struct ast_vm_user vmus, *vmu = NULL;
06798 
06799    /* If ADSI is supported, setup login screen */
06800    adsi_begin(chan, &useadsi);
06801    if (!skipuser && useadsi)
06802       adsi_login(chan);
06803    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
06804       ast_log(LOG_WARNING, "Couldn't stream login file\n");
06805       return -1;
06806    }
06807    
06808    /* Authenticate them and get their mailbox/password */
06809    
06810    while (!valid && (logretries < maxlogins)) {
06811       /* Prompt for, and read in the username */
06812       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
06813          ast_log(LOG_WARNING, "Couldn't read username\n");
06814          return -1;
06815       }
06816       if (ast_strlen_zero(mailbox)) {
06817          if (chan->cid.cid_num) {
06818             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
06819          } else {
06820             if (option_verbose > 2)
06821                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
06822             return -1;
06823          }
06824       }
06825       if (useadsi)
06826          adsi_password(chan);
06827 
06828       if (!ast_strlen_zero(prefix)) {
06829          char fullusername[80] = "";
06830          ast_copy_string(fullusername, prefix, sizeof(fullusername));
06831          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
06832          ast_copy_string(mailbox, fullusername, mailbox_size);
06833       }
06834 
06835       if (option_debug)
06836          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
06837       vmu = find_user(&vmus, context, mailbox);
06838       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
06839          /* saved password is blank, so don't bother asking */
06840          password[0] = '\0';
06841       } else {
06842          if (ast_streamfile(chan, "vm-password", chan->language)) {
06843             ast_log(LOG_WARNING, "Unable to stream password file\n");
06844             return -1;
06845          }
06846          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
06847             ast_log(LOG_WARNING, "Unable to read password\n");
06848             return -1;
06849          }
06850       }
06851 
06852       if (vmu) {
06853          passptr = vmu->password;
06854          if (passptr[0] == '-') passptr++;
06855       }
06856       if (vmu && !strcmp(passptr, password))
06857          valid++;
06858       else {
06859          if (option_verbose > 2)
06860             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
06861          if (!ast_strlen_zero(prefix))
06862             mailbox[0] = '\0';
06863       }
06864       logretries++;
06865       if (!valid) {
06866          if (skipuser || logretries >= maxlogins) {
06867             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
06868                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
06869                return -1;
06870             }
06871          } else {
06872             if (useadsi)
06873                adsi_login(chan);
06874             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
06875                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
06876                return -1;
06877             }
06878          }
06879          if (ast_waitstream(chan, "")) /* Channel is hung up */
06880             return -1;
06881       }
06882    }
06883    if (!valid && (logretries >= maxlogins)) {
06884       ast_stopstream(chan);
06885       ast_play_and_wait(chan, "vm-goodbye");
06886       return -1;
06887    }
06888    if (vmu && !skipuser) {
06889       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
06890    }
06891    return 0;
06892 }

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

Definition at line 7604 of file app_voicemail.c.

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

Referenced by load_module().

07605 {
07606    struct ast_module_user *u;
07607    struct ast_vm_user svm;
07608    char *context, *box;
07609    int priority_jump = 0;
07610    AST_DECLARE_APP_ARGS(args,
07611       AST_APP_ARG(mbox);
07612       AST_APP_ARG(options);
07613    );
07614 
07615    if (ast_strlen_zero(data)) {
07616       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
07617       return -1;
07618    }
07619 
07620    u = ast_module_user_add(chan);
07621 
07622    box = ast_strdupa(data);
07623 
07624    AST_STANDARD_APP_ARGS(args, box);
07625 
07626    if (args.options) {
07627       if (strchr(args.options, 'j'))
07628          priority_jump = 1;
07629    }
07630 
07631    if ((context = strchr(args.mbox, '@'))) {
07632       *context = '\0';
07633       context++;
07634    }
07635 
07636    if (find_user(&svm, context, args.mbox)) {
07637       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
07638       if (priority_jump || ast_opt_priority_jumping)
07639          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
07640             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);
07641    } else
07642       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
07643    ast_module_user_remove(u);
07644    return 0;
07645 }

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

Definition at line 6779 of file app_voicemail.c.

References vm_browse_messages_en(), and vm_browse_messages_latin().

Referenced by vm_execmain().

06780 {
06781    if (!strncasecmp(chan->language, "es", 2) ||
06782          !strncasecmp(chan->language, "it", 2) ||
06783          !strncasecmp(chan->language, "pt", 2) ||
06784          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
06785       return vm_browse_messages_latin(chan, vms, vmu);
06786    } else { /* Default to English syntax */
06787       return vm_browse_messages_en(chan, vms, vmu);
06788    }
06789 }

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

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

06732 {
06733    int cmd=0;
06734 
06735    if (vms->lastmsg > -1) {
06736       cmd = play_message(chan, vmu, vms);
06737    } else {
06738       cmd = ast_play_and_wait(chan, "vm-youhave");
06739       if (!cmd) 
06740          cmd = ast_play_and_wait(chan, "vm-no");
06741       if (!cmd) {
06742          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06743          cmd = ast_play_and_wait(chan, vms->fn);
06744       }
06745       if (!cmd)
06746          cmd = ast_play_and_wait(chan, "vm-messages");
06747    }
06748    return cmd;
06749 }

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

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

06753 {
06754    int cmd=0;
06755 
06756    if (vms->lastmsg > -1) {
06757       cmd = play_message(chan, vmu, vms);
06758    } else {
06759       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06760       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
06761          if (!cmd) {
06762             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
06763             cmd = ast_play_and_wait(chan, vms->fn);
06764          }
06765          if (!cmd)
06766             cmd = ast_play_and_wait(chan, "vm-messages");
06767       } else {
06768          if (!cmd)
06769             cmd = ast_play_and_wait(chan, "vm-messages");
06770          if (!cmd) {
06771             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06772             cmd = ast_play_and_wait(chan, vms->fn);
06773          }
06774       }
06775    }
06776    return cmd;
06777 }

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

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

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

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

Definition at line 883 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00884 {
00885    char buf[255];
00886    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00887    if (!ast_safe_system(buf)) {
00888       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00889       /* Reset the password in memory, too */
00890       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00891    }
00892 }

static int vm_delete ( char *  file  )  [static]

Definition at line 2783 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message(), and forward_message().

02784 {
02785    char *txt;
02786    int txtsize = 0;
02787 
02788    txtsize = (strlen(file) + 5)*sizeof(char);
02789    txt = alloca(txtsize);
02790    /* Sprintf here would safe because we alloca'd exactly the right length,
02791     * but trying to eliminate all sprintf's anyhow
02792     */
02793    snprintf(txt, txtsize, "%s.txt", file);
02794    unlink(txt);
02795    return ast_filedelete(file, NULL);
02796 }

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

Definition at line 7457 of file app_voicemail.c.

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

Referenced by load_module(), and play_record_review().

07458 {
07459    int res = 0;
07460    struct ast_module_user *u;
07461    char *tmp;
07462    struct leave_vm_options leave_options;
07463    struct ast_flags flags = { 0 };
07464    static int deprecate_warning = 0;
07465    char *opts[OPT_ARG_ARRAY_SIZE];
07466    AST_DECLARE_APP_ARGS(args,
07467       AST_APP_ARG(argv0);
07468       AST_APP_ARG(argv1);
07469    );
07470 
07471    u = ast_module_user_add(chan);
07472    
07473    memset(&leave_options, 0, sizeof(leave_options));
07474 
07475    if (chan->_state != AST_STATE_UP)
07476       ast_answer(chan);
07477 
07478    if (!ast_strlen_zero(data)) {
07479       tmp = ast_strdupa(data);
07480       AST_STANDARD_APP_ARGS(args, tmp);
07481       if (args.argc == 2) {
07482          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07483             ast_module_user_remove(u);
07484             return -1;
07485          }
07486          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07487          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07488             int gain;
07489 
07490             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
07491                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07492                ast_module_user_remove(u);
07493                return -1;
07494             } else {
07495                leave_options.record_gain = (signed char) gain;
07496             }
07497          }
07498       } else {
07499          /* old style options parsing */
07500          int old = 0;
07501          char *orig_argv0 = args.argv0;
07502          while (*(args.argv0)) {
07503             if (*(args.argv0) == 's') {
07504                old = 1;
07505                ast_set_flag(&leave_options, OPT_SILENT);
07506             } else if (*(args.argv0) == 'b') {
07507                old = 1;
07508                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07509             } else if (*(args.argv0) == 'u') {
07510                old = 1;
07511                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07512             } else if (*(args.argv0) == 'j') {
07513                old = 1;
07514                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07515             } else
07516                break;
07517             (args.argv0)++;
07518          }
07519          if (!deprecate_warning && old) {
07520             deprecate_warning = 1;
07521             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07522             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07523          }
07524       }
07525    } else {
07526       char tmp[256];
07527       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07528       if (res < 0) {
07529          ast_module_user_remove(u);
07530          return res;
07531       }
07532       if (ast_strlen_zero(tmp)) {
07533          ast_module_user_remove(u);
07534          return 0;
07535       }
07536       args.argv0 = ast_strdupa(tmp);
07537    }
07538 
07539    res = leave_voicemail(chan, args.argv0, &leave_options);
07540 
07541    if (res == ERROR_LOCK_PATH) {
07542       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07543       /*Send the call to n+101 priority, where n is the current priority*/
07544       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07545          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07546             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07547       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07548       res = 0;
07549    }
07550    
07551    ast_module_user_remove(u);
07552 
07553    return res;
07554 }

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

Definition at line 6894 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(), dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free, free_user(), get_folder2(), globalflags, has_voicemail(), language, ast_vm_user::language, LOG_DEBUG, ast_vm_user::mailbox, make_file(), manager_event(), maxlogins, ast_vm_user::maxmsg, open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, option_debug, option_verbose, parse(), ast_vm_user::password, play_message(), run_externnotify(), save_to_folder(), say_and_wait(), VERBOSE_PREFIX_3, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, and vmfmts.

Referenced by load_module().

06895 {
06896    /* XXX This is, admittedly, some pretty horrendus code.  For some
06897       reason it just seemed a lot easier to do with GOTO's.  I feel
06898       like I'm back in my GWBASIC days. XXX */
06899    int res=-1;
06900    int cmd=0;
06901    int valid = 0;
06902    struct ast_module_user *u;
06903    char prefixstr[80] ="";
06904    char ext_context[256]="";
06905    int box;
06906    int useadsi = 0;
06907    int skipuser = 0;
06908    struct vm_state vms;
06909    struct ast_vm_user *vmu = NULL, vmus;
06910    char *context=NULL;
06911    int silentexit = 0;
06912    struct ast_flags flags = { 0 };
06913    signed char record_gain = 0;
06914    int play_auto = 0;
06915    int play_folder = 0;
06916 #ifdef IMAP_STORAGE
06917    int deleted = 0;
06918 #endif
06919    u = ast_module_user_add(chan);
06920 
06921    /* Add the vm_state to the active list and keep it active */
06922    memset(&vms, 0, sizeof(vms));
06923    vms.lastmsg = -1;
06924 
06925    memset(&vmus, 0, sizeof(vmus));
06926 
06927    if (chan->_state != AST_STATE_UP) {
06928       if (option_debug)
06929          ast_log(LOG_DEBUG, "Before ast_answer\n");
06930       ast_answer(chan);
06931    }
06932 
06933    if (!ast_strlen_zero(data)) {
06934       char *opts[OPT_ARG_ARRAY_SIZE];
06935       char *parse;
06936       AST_DECLARE_APP_ARGS(args,
06937          AST_APP_ARG(argv0);
06938          AST_APP_ARG(argv1);
06939       );
06940 
06941       parse = ast_strdupa(data);
06942 
06943       AST_STANDARD_APP_ARGS(args, parse);
06944 
06945       if (args.argc == 2) {
06946          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
06947             ast_module_user_remove(u);
06948             return -1;
06949          }
06950          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
06951             int gain;
06952             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
06953                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
06954                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
06955                   ast_module_user_remove(u);
06956                   return -1;
06957                } else {
06958                   record_gain = (signed char) gain;
06959                }
06960             } else {
06961                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
06962             }
06963          }
06964          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
06965             play_auto = 1;
06966             if (opts[OPT_ARG_PLAYFOLDER]) {
06967                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
06968                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
06969                }
06970             } else {
06971                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
06972             }  
06973             if ( play_folder > 9 || play_folder < 0) {
06974                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
06975                play_folder = 0;
06976             }
06977          }
06978       } else {
06979          /* old style options parsing */
06980          while (*(args.argv0)) {
06981             if (*(args.argv0) == 's')
06982                ast_set_flag(&flags, OPT_SILENT);
06983             else if (*(args.argv0) == 'p')
06984                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
06985             else 
06986                break;
06987             (args.argv0)++;
06988          }
06989 
06990       }
06991 
06992       valid = ast_test_flag(&flags, OPT_SILENT);
06993 
06994       if ((context = strchr(args.argv0, '@')))
06995          *context++ = '\0';
06996 
06997       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
06998          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
06999       else
07000          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
07001 
07002       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
07003          skipuser++;
07004       else
07005          valid = 0;
07006    }
07007 
07008    if (!valid)
07009       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
07010 
07011    if (option_debug)
07012       ast_log(LOG_DEBUG, "After vm_authenticate\n");
07013    if (!res) {
07014       valid = 1;
07015       if (!skipuser)
07016          vmu = &vmus;
07017    } else {
07018       res = 0;
07019    }
07020 
07021    /* If ADSI is supported, setup login screen */
07022    adsi_begin(chan, &useadsi);
07023 
07024 #ifdef IMAP_STORAGE
07025    vms.interactive = 1;
07026    vms.updated = 1;
07027    ast_copy_string(vms.context, vmu->context, sizeof(vms.context));
07028    vmstate_insert(&vms);
07029    init_vm_state(&vms);
07030 #endif
07031    if (!valid)
07032       goto out;
07033 
07034    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07035       /* TODO: Handle memory allocation failure */
07036    }
07037    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07038       /* TODO: Handle memory allocation failure */
07039    }
07040    
07041    /* Set language from config to override channel language */
07042    if (!ast_strlen_zero(vmu->language))
07043       ast_string_field_set(chan, language, vmu->language);
07044    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
07045    /* Retrieve old and new message counts */
07046    if (option_debug)
07047       ast_log(LOG_DEBUG, "Before open_mailbox\n");
07048    res = open_mailbox(&vms, vmu, 1);
07049    if (res == ERROR_LOCK_PATH)
07050       goto out;
07051    vms.oldmessages = vms.lastmsg + 1;
07052    if (option_debug > 2)
07053       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
07054    /* Start in INBOX */
07055    res = open_mailbox(&vms, vmu, 0);
07056    if (res == ERROR_LOCK_PATH)
07057       goto out;
07058    vms.newmessages = vms.lastmsg + 1;
07059    if (option_debug > 2)
07060       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
07061       
07062    /* Select proper mailbox FIRST!! */
07063    if (play_auto) {
07064       res = open_mailbox(&vms, vmu, play_folder);
07065       if (res == ERROR_LOCK_PATH)
07066          goto out;
07067 
07068       /* If there are no new messages, inform the user and hangup */
07069       if (vms.lastmsg == -1) {
07070          cmd = vm_browse_messages(chan, &vms, vmu);
07071          res = 0;
07072          goto out;
07073       }
07074    } else {
07075       if (!vms.newmessages && vms.oldmessages) {
07076          /* If we only have old messages start here */
07077          res = open_mailbox(&vms, vmu, 1);
07078          play_folder = 1;
07079          if (res == ERROR_LOCK_PATH)
07080             goto out;
07081       }
07082    }
07083 
07084    if (useadsi)
07085       adsi_status(chan, &vms);
07086    res = 0;
07087 
07088    /* Check to see if this is a new user */
07089    if (!strcasecmp(vmu->mailbox, vmu->password) && 
07090       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
07091       if (ast_play_and_wait(chan, "vm-newuser") == -1)
07092          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
07093       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
07094       if ((cmd == 't') || (cmd == '#')) {
07095          /* Timeout */
07096          res = 0;
07097          goto out;
07098       } else if (cmd < 0) {
07099          /* Hangup */
07100          res = -1;
07101          goto out;
07102       }
07103    }
07104 #ifdef IMAP_STORAGE
07105       if (option_debug > 2)
07106          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
07107       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
07108          if (option_debug)
07109             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
07110          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07111       }
07112       if (option_debug > 2)
07113          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07114       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
07115          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07116          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07117       }
07118 #endif
07119    if (play_auto) {
07120       cmd = '1';
07121    } else {
07122       cmd = vm_intro(chan, vmu, &vms);
07123    }
07124 
07125    vms.repeats = 0;
07126    vms.starting = 1;
07127    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07128       /* Run main menu */
07129       switch (cmd) {
07130       case '1':
07131          vms.curmsg = 0;
07132          /* Fall through */
07133       case '5':
07134          cmd = vm_browse_messages(chan, &vms, vmu);
07135          break;
07136       case '2': /* Change folders */
07137          if (useadsi)
07138             adsi_folders(chan, 0, "Change to folder...");
07139          cmd = get_folder2(chan, "vm-changeto", 0);
07140          if (cmd == '#') {
07141             cmd = 0;
07142          } else if (cmd > 0) {
07143             cmd = cmd - '0';
07144             res = close_mailbox(&vms, vmu);
07145             if (res == ERROR_LOCK_PATH)
07146                goto out;
07147             res = open_mailbox(&vms, vmu, cmd);
07148             if (res == ERROR_LOCK_PATH)
07149                goto out;
07150             play_folder = cmd;
07151             cmd = 0;
07152          }
07153          if (useadsi)
07154             adsi_status2(chan, &vms);
07155             
07156          if (!cmd)
07157             cmd = vm_play_folder_name(chan, vms.vmbox);
07158 
07159          vms.starting = 1;
07160          break;
07161       case '3': /* Advanced options */
07162          cmd = 0;
07163          vms.repeats = 0;
07164          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07165             switch (cmd) {
07166             case '1': /* Reply */
07167                if (vms.lastmsg > -1 && !vms.starting) {
07168                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
07169                   if (cmd == ERROR_LOCK_PATH) {
07170                      res = cmd;
07171                      goto out;
07172                   }
07173                } else
07174                   cmd = ast_play_and_wait(chan, "vm-sorry");
07175                cmd = 't';
07176                break;
07177             case '2': /* Callback */
07178                if (option_verbose > 2 && !vms.starting)
07179                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
07180                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
07181                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
07182                   if (cmd == 9) {
07183                      silentexit = 1;
07184                      goto out;
07185                   } else if (cmd == ERROR_LOCK_PATH) {
07186                      res = cmd;
07187                      goto out;
07188                   }
07189                }
07190                else 
07191                   cmd = ast_play_and_wait(chan, "vm-sorry");
07192                cmd = 't';
07193                break;
07194             case '3': /* Envelope */
07195                if (vms.lastmsg > -1 && !vms.starting) {
07196                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
07197                   if (cmd == ERROR_LOCK_PATH) {
07198                      res = cmd;
07199                      goto out;
07200                   }
07201                } else
07202                   cmd = ast_play_and_wait(chan, "vm-sorry");
07203                cmd = 't';
07204                break;
07205             case '4': /* Dialout */
07206                if (!ast_strlen_zero(vmu->dialout)) {
07207                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
07208                   if (cmd == 9) {
07209                      silentexit = 1;
07210                      goto out;
07211                   }
07212                }
07213                else 
07214                   cmd = ast_play_and_wait(chan, "vm-sorry");
07215                cmd = 't';
07216                break;
07217 
07218             case '5': /* Leave VoiceMail */
07219                if (ast_test_flag(vmu, VM_SVMAIL)) {
07220                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
07221                   if (cmd == ERROR_LOCK_PATH) {
07222                      res = cmd;
07223                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
07224                      goto out;
07225                   }
07226                } else
07227                   cmd = ast_play_and_wait(chan,"vm-sorry");
07228                cmd='t';
07229                break;
07230                
07231             case '*': /* Return to main menu */
07232                cmd = 't';
07233                break;
07234 
07235             default:
07236                cmd = 0;
07237                if (!vms.starting) {
07238                   cmd = ast_play_and_wait(chan, "vm-toreply");
07239                }
07240                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
07241                   cmd = ast_play_and_wait(chan, "vm-tocallback");
07242                }
07243                if (!cmd && !vms.starting) {
07244                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
07245                }
07246                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
07247                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
07248                }
07249                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
07250                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
07251                if (!cmd)
07252                   cmd = ast_play_and_wait(chan, "vm-starmain");
07253                if (!cmd)
07254                   cmd = ast_waitfordigit(chan,6000);
07255                if (!cmd)
07256                   vms.repeats++;
07257                if (vms.repeats > 3)
07258                   cmd = 't';
07259             }
07260          }
07261          if (cmd == 't') {
07262             cmd = 0;
07263             vms.repeats = 0;
07264          }
07265          break;
07266       case '4':
07267          if (vms.curmsg > 0) {
07268             vms.curmsg--;
07269             cmd = play_message(chan, vmu, &vms);
07270          } else {
07271             cmd = ast_play_and_wait(chan, "vm-nomore");
07272          }
07273          break;
07274       case '6':
07275          if (vms.curmsg < vms.lastmsg) {
07276             vms.curmsg++;
07277             cmd = play_message(chan, vmu, &vms);
07278          } else {
07279             cmd = ast_play_and_wait(chan, "vm-nomore");
07280          }
07281          break;
07282       case '7':
07283          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
07284             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
07285             if (useadsi)
07286                adsi_delete(chan, &vms);
07287             if (vms.deleted[vms.curmsg]) {
07288                if (play_folder == 0)
07289                   vms.newmessages--;
07290                else if (play_folder == 1)
07291                   vms.oldmessages--;
07292                cmd = ast_play_and_wait(chan, "vm-deleted");
07293             }
07294             else {
07295                if (play_folder == 0)
07296                   vms.newmessages++;
07297                else if (play_folder == 1)
07298                   vms.oldmessages++;
07299                cmd = ast_play_and_wait(chan, "vm-undeleted");
07300             }
07301             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07302                if (vms.curmsg < vms.lastmsg) {
07303                   vms.curmsg++;
07304                   cmd = play_message(chan, vmu, &vms);
07305                } else {
07306                   cmd = ast_play_and_wait(chan, "vm-nomore");
07307                }
07308             }
07309          } else /* Delete not valid if we haven't selected a message */
07310             cmd = 0;
07311 #ifdef IMAP_STORAGE
07312          deleted = 1;
07313 #endif
07314          break;
07315    
07316       case '8':
07317          if (vms.lastmsg > -1) {
07318             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
07319             if (cmd == ERROR_LOCK_PATH) {
07320                res = cmd;
07321                goto out;
07322             }
07323          } else
07324             cmd = ast_play_and_wait(chan, "vm-nomore");
07325          break;
07326       case '9':
07327          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
07328             /* No message selected */
07329             cmd = 0;
07330             break;
07331          }
07332          if (useadsi)
07333             adsi_folders(chan, 1, "Save to folder...");
07334          cmd = get_folder2(chan, "vm-savefolder", 1);
07335          box = 0; /* Shut up compiler */
07336          if (cmd == '#') {
07337             cmd = 0;
07338             break;
07339          } else if (cmd > 0) {
07340             box = cmd = cmd - '0';
07341             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
07342             if (cmd == ERROR_LOCK_PATH) {
07343                res = cmd;
07344                goto out;
07345 #ifndef IMAP_STORAGE
07346             } else if (!cmd) {
07347                vms.deleted[vms.curmsg] = 1;
07348 #endif
07349             } else {
07350                vms.deleted[vms.curmsg] = 0;
07351                vms.heard[vms.curmsg] = 0;
07352             }
07353          }
07354          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
07355          if (useadsi)
07356             adsi_message(chan, &vms);
07357          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
07358          if (!cmd) {
07359             cmd = ast_play_and_wait(chan, "vm-message");
07360             if (!cmd)
07361                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
07362             if (!cmd)
07363                cmd = ast_play_and_wait(chan, "vm-savedto");
07364             if (!cmd)
07365                cmd = vm_play_folder_name(chan, vms.fn);
07366          } else {
07367             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07368          }
07369          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07370             if (vms.curmsg < vms.lastmsg) {
07371                vms.curmsg++;
07372                cmd = play_message(chan, vmu, &vms);
07373             } else {
07374                cmd = ast_play_and_wait(chan, "vm-nomore");
07375             }
07376          }
07377          break;
07378       case '*':
07379          if (!vms.starting) {
07380             cmd = ast_play_and_wait(chan, "vm-onefor");
07381             if (!cmd)
07382                cmd = vm_play_folder_name(chan, vms.vmbox);
07383             if (!cmd)
07384                cmd = ast_play_and_wait(chan, "vm-opts");
07385             if (!cmd)
07386                cmd = vm_instructions(chan, &vms, 1);
07387          } else
07388             cmd = 0;
07389          break;
07390       case '0':
07391          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
07392          if (useadsi)
07393             adsi_status(chan, &vms);
07394          break;
07395       default: /* Nothing */
07396          cmd = vm_instructions(chan, &vms, 0);
07397          break;
07398       }
07399    }
07400    if ((cmd == 't') || (cmd == '#')) {
07401       /* Timeout */
07402       res = 0;
07403    } else {
07404       /* Hangup */
07405       res = -1;
07406    }
07407 
07408 out:
07409    if (res > -1) {
07410       ast_stopstream(chan);
07411       adsi_goodbye(chan);
07412       if (valid) {
07413          if (silentexit)
07414             res = ast_play_and_wait(chan, "vm-dialout");
07415          else 
07416             res = ast_play_and_wait(chan, "vm-goodbye");
07417          if (res > 0)
07418             res = 0;
07419       }
07420       if (useadsi)
07421          ast_adsi_unload_session(chan);
07422    }
07423    if (vmu)
07424       close_mailbox(&vms, vmu);
07425    if (valid) {
07426       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
07427       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
07428       run_externnotify(vmu->context, vmu->mailbox);
07429    }
07430 #ifdef IMAP_STORAGE
07431    /* expunge message - use UID Expunge if supported on IMAP server*/
07432    if (option_debug > 2)
07433       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
07434    if (vmu && deleted == 1 && expungeonhangup == 1) {
07435 #ifdef HAVE_IMAP_TK2006
07436       if (LEVELUIDPLUS (vms.mailstream)) {
07437          mail_expunge_full(vms.mailstream,NIL,EX_UID);
07438       } else 
07439 #endif
07440          mail_expunge(vms.mailstream);
07441    }
07442    /*  before we delete the state, we should copy pertinent info
07443     *  back to the persistent model */
07444    vmstate_delete(&vms);
07445 #endif
07446    if (vmu)
07447       free_user(vmu);
07448    if (vms.deleted)
07449       free(vms.deleted);
07450    if (vms.heard)
07451       free(vms.heard);
07452    ast_module_user_remove(u);
07453 
07454    return res;
07455 }

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

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

Referenced by forward_message().

04702 {
04703    int cmd = 0;
04704    int retries = 0, prepend_duration = 0, already_recorded = 0;
04705    signed char zero_gain = 0;
04706    struct ast_config *msg_cfg;
04707    const char *duration_str;
04708    char msgfile[PATH_MAX], backup[PATH_MAX];
04709    char textfile[PATH_MAX];
04710 
04711    /* Must always populate duration correctly */
04712    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
04713    strcpy(textfile, msgfile);
04714    strcpy(backup, msgfile);
04715    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
04716    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
04717 
04718    if (!(msg_cfg = ast_config_load(textfile))) {
04719       return -1;
04720    }
04721 
04722    *duration = 0;
04723    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
04724       *duration = atoi(duration_str);
04725 
04726    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
04727       if (cmd)
04728          retries = 0;
04729       switch (cmd) {
04730       case '1': 
04731          /* prepend a message to the current message, update the metadata and return */
04732       {
04733          prepend_duration = 0;
04734 
04735          /* if we can't read the message metadata, stop now */
04736          if (!msg_cfg) {
04737             cmd = 0;
04738             break;
04739          }
04740 
04741          /* Back up the original file, so we can retry the prepend */
04742          if (already_recorded)
04743             ast_filecopy(backup, msgfile, NULL);
04744          else
04745             ast_filecopy(msgfile, backup, NULL);
04746          already_recorded = 1;
04747 
04748          if (record_gain)
04749             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
04750 
04751          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
04752          if (record_gain)
04753             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
04754 
04755          if (prepend_duration) {
04756             struct ast_category *msg_cat;
04757             /* need enough space for a maximum-length message duration */
04758             char duration_str[12];
04759 
04760             prepend_duration += *duration;
04761             msg_cat = ast_category_get(msg_cfg, "message");
04762             snprintf(duration_str, 11, "%d", prepend_duration);
04763             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
04764                config_text_file_save(textfile, msg_cfg, "app_voicemail");
04765             }
04766          }
04767 
04768          break;
04769       }
04770       case '2': 
04771          cmd = 't';
04772          break;
04773       case '*':
04774          cmd = '*';
04775          break;
04776       default: 
04777          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
04778             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
04779          if (!cmd)
04780             cmd = ast_play_and_wait(chan,"vm-starmain");
04781             /* "press star to return to the main menu" */
04782          if (!cmd)
04783             cmd = ast_waitfordigit(chan,6000);
04784          if (!cmd)
04785             retries++;
04786          if (retries > 3)
04787             cmd = 't';
04788       }
04789    }
04790 
04791    ast_config_destroy(msg_cfg);
04792    if (already_recorded)
04793       ast_filedelete(backup, NULL);
04794    if (prepend_duration)
04795       *duration = prepend_duration;
04796 
04797    if (cmd == 't' || cmd == 'S')
04798       cmd = 0;
04799    return cmd;
04800 }

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

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

06431 {
06432    int res = 0;
06433    /* Play instructions and wait for new command */
06434    while (!res) {
06435       if (vms->starting) {
06436          if (vms->lastmsg > -1) {
06437             res = ast_play_and_wait(chan, "vm-onefor");
06438             if (!res)
06439                res = vm_play_folder_name(chan, vms->vmbox);
06440          }
06441          if (!res)
06442             res = ast_play_and_wait(chan, "vm-opts");
06443       } else {
06444          if (vms->curmsg)
06445             res = ast_play_and_wait(chan, "vm-prev");
06446          if (!res && !skipadvanced)
06447             res = ast_play_and_wait(chan, "vm-advopts");
06448          if (!res)
06449             res = ast_play_and_wait(chan, "vm-repeat");
06450          if (!res && (vms->curmsg != vms->lastmsg))
06451             res = ast_play_and_wait(chan, "vm-next");
06452          if (!res) {
06453             if (!vms->deleted[vms->curmsg])
06454                res = ast_play_and_wait(chan, "vm-delete");
06455             else
06456                res = ast_play_and_wait(chan, "vm-undelete");
06457             if (!res)
06458                res = ast_play_and_wait(chan, "vm-toforward");
06459             if (!res)
06460                res = ast_play_and_wait(chan, "vm-savemessage");
06461          }
06462       }
06463       if (!res)
06464          res = ast_play_and_wait(chan, "vm-helpexit");
06465       if (!res)
06466          res = ast_waitfordigit(chan, 6000);
06467       if (!res) {
06468          vms->repeats++;
06469          if (vms->repeats > 2) {
06470             res = 't';
06471          }
06472       }
06473    }
06474    return res;
06475 }

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

Definition at line 6385 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_intro_ua(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.

Referenced by vm_execmain().

06386 {
06387    char prefile[256];
06388    
06389    /* Notify the user that the temp greeting is set and give them the option to remove it */
06390    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06391    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
06392       if (ast_fileexists(prefile, NULL, NULL) > 0)
06393          ast_play_and_wait(chan, "vm-tempgreetactive");
06394    }
06395 
06396    /* Play voicemail intro - syntax is different for different languages */
06397    if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
06398       return vm_intro_de(chan, vms);
06399    } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */
06400       return vm_intro_es(chan, vms);
06401    } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
06402       return vm_intro_it(chan, vms);
06403    } else if (!strncasecmp(chan->language, "fr", 2)) {   /* FRENCH syntax */
06404       return vm_intro_fr(chan, vms);
06405    } else if (!strncasecmp(chan->language, "nl", 2)) {   /* DUTCH syntax */
06406       return vm_intro_nl(chan, vms);
06407    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
06408       return vm_intro_pt_BR(chan, vms);      
06409    } else if (!strncasecmp(chan->language, "pt", 2)) {   /* PORTUGUESE syntax */
06410       return vm_intro_pt(chan, vms);
06411    } else if (!strncasecmp(chan->language, "cz", 2)) {   /* CZECH syntax */
06412       return vm_intro_cz(chan, vms);
06413    } else if (!strncasecmp(chan->language, "gr", 2)) {   /* GREEK syntax */
06414       return vm_intro_gr(chan, vms);
06415    } else if (!strncasecmp(chan->language, "pl", 2)) {   /* POLISH syntax */
06416       return vm_intro_pl(chan, vms);
06417    } else if (!strncasecmp(chan->language, "se", 2)) {   /* SWEDISH syntax */
06418       return vm_intro_se(chan, vms);
06419    } else if (!strncasecmp(chan->language, "no", 2)) {   /* NORWEGIAN syntax */
06420       return vm_intro_no(chan, vms);
06421    } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */
06422       return vm_intro_ru(chan, vms);
06423    } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */
06424       return vm_intro_ua(chan, vms);
06425    } else {             /* Default to ENGLISH */
06426       return vm_intro_en(chan, vms);
06427    }
06428 }

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

Definition at line 6180 of file app_voicemail.c.

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

Referenced by vm_intro().

06181 {
06182    int res;
06183    res = ast_play_and_wait(chan, "vm-youhave");
06184    if (!res) {
06185       if (vms->newmessages) {
06186          if (vms->newmessages == 1) {
06187             res = ast_play_and_wait(chan, "digits/jednu");
06188          } else {
06189             res = say_and_wait(chan, vms->newmessages, chan->language);
06190          }
06191          if (!res) {
06192             if ((vms->newmessages == 1))
06193                res = ast_play_and_wait(chan, "vm-novou");
06194             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06195                res = ast_play_and_wait(chan, "vm-nove");
06196             if (vms->newmessages > 4)
06197                res = ast_play_and_wait(chan, "vm-novych");
06198          }
06199          if (vms->oldmessages && !res)
06200             res = ast_play_and_wait(chan, "vm-and");
06201          else if (!res) {
06202             if ((vms->newmessages == 1))
06203                res = ast_play_and_wait(chan, "vm-zpravu");
06204             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06205                res = ast_play_and_wait(chan, "vm-zpravy");
06206             if (vms->newmessages > 4)
06207                res = ast_play_and_wait(chan, "vm-zprav");
06208          }
06209       }
06210       if (!res && vms->oldmessages) {
06211          res = say_and_wait(chan, vms->oldmessages, chan->language);
06212          if (!res) {
06213             if ((vms->oldmessages == 1))
06214                res = ast_play_and_wait(chan, "vm-starou");
06215             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06216                res = ast_play_and_wait(chan, "vm-stare");
06217             if (vms->oldmessages > 4)
06218                res = ast_play_and_wait(chan, "vm-starych");
06219          }
06220          if (!res) {
06221             if ((vms->oldmessages == 1))
06222                res = ast_play_and_wait(chan, "vm-zpravu");
06223             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06224                res = ast_play_and_wait(chan, "vm-zpravy");
06225             if (vms->oldmessages > 4)
06226                res = ast_play_and_wait(chan, "vm-zprav");
06227          }
06228       }
06229       if (!res) {
06230          if (!vms->oldmessages && !vms->newmessages) {
06231             res = ast_play_and_wait(chan, "vm-no");
06232             if (!res)
06233                res = ast_play_and_wait(chan, "vm-zpravy");
06234          }
06235       }
06236    }
06237    return res;
06238 }

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

Definition at line 5873 of file app_voicemail.c.

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

Referenced by vm_intro().

05874 {
05875    /* Introduce messages they have */
05876    int res;
05877    res = ast_play_and_wait(chan, "vm-youhave");
05878    if (!res) {
05879       if (vms->newmessages) {
05880          if ((vms->newmessages == 1))
05881             res = ast_play_and_wait(chan, "digits/1F");
05882          else
05883             res = say_and_wait(chan, vms->newmessages, chan->language);
05884          if (!res)
05885             res = ast_play_and_wait(chan, "vm-INBOX");
05886          if (vms->oldmessages && !res)
05887             res = ast_play_and_wait(chan, "vm-and");
05888          else if (!res) {
05889             if ((vms->newmessages == 1))
05890                res = ast_play_and_wait(chan, "vm-message");
05891             else
05892                res = ast_play_and_wait(chan, "vm-messages");
05893          }
05894             
05895       }
05896       if (!res && vms->oldmessages) {
05897          if (vms->oldmessages == 1)
05898             res = ast_play_and_wait(chan, "digits/1F");
05899          else
05900             res = say_and_wait(chan, vms->oldmessages, chan->language);
05901          if (!res)
05902             res = ast_play_and_wait(chan, "vm-Old");
05903          if (!res) {
05904             if (vms->oldmessages == 1)
05905                res = ast_play_and_wait(chan, "vm-message");
05906             else
05907                res = ast_play_and_wait(chan, "vm-messages");
05908          }
05909       }
05910       if (!res) {
05911          if (!vms->oldmessages && !vms->newmessages) {
05912             res = ast_play_and_wait(chan, "vm-no");
05913             if (!res)
05914                res = ast_play_and_wait(chan, "vm-messages");
05915          }
05916       }
05917    }
05918    return res;
05919 }

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

Definition at line 5635 of file app_voicemail.c.

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

Referenced by vm_intro().

05636 {
05637    int res;
05638 
05639    /* Introduce messages they have */
05640    res = ast_play_and_wait(chan, "vm-youhave");
05641    if (!res) {
05642       if (vms->newmessages) {
05643          res = say_and_wait(chan, vms->newmessages, chan->language);
05644          if (!res)
05645             res = ast_play_and_wait(chan, "vm-INBOX");
05646          if (vms->oldmessages && !res)
05647             res = ast_play_and_wait(chan, "vm-and");
05648          else if (!res) {
05649             if ((vms->newmessages == 1))
05650                res = ast_play_and_wait(chan, "vm-message");
05651             else
05652                res = ast_play_and_wait(chan, "vm-messages");
05653          }
05654             
05655       }
05656       if (!res && vms->oldmessages) {
05657          res = say_and_wait(chan, vms->oldmessages, chan->language);
05658          if (!res)
05659             res = ast_play_and_wait(chan, "vm-Old");
05660          if (!res) {
05661             if (vms->oldmessages == 1)
05662                res = ast_play_and_wait(chan, "vm-message");
05663             else
05664                res = ast_play_and_wait(chan, "vm-messages");
05665          }
05666       }
05667       if (!res) {
05668          if (!vms->oldmessages && !vms->newmessages) {
05669             res = ast_play_and_wait(chan, "vm-no");
05670             if (!res)
05671                res = ast_play_and_wait(chan, "vm-messages");
05672          }
05673       }
05674    }
05675    return res;
05676 }

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

Definition at line 5922 of file app_voicemail.c.

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

Referenced by vm_intro().

05923 {
05924    /* Introduce messages they have */
05925    int res;
05926    if (!vms->oldmessages && !vms->newmessages) {
05927       res = ast_play_and_wait(chan, "vm-youhaveno");
05928       if (!res)
05929          res = ast_play_and_wait(chan, "vm-messages");
05930    } else {
05931       res = ast_play_and_wait(chan, "vm-youhave");
05932    }
05933    if (!res) {
05934       if (vms->newmessages) {
05935          if (!res) {
05936             if ((vms->newmessages == 1)) {
05937                res = ast_play_and_wait(chan, "digits/1M");
05938                if (!res)
05939                   res = ast_play_and_wait(chan, "vm-message");
05940                if (!res)
05941                   res = ast_play_and_wait(chan, "vm-INBOXs");
05942             } else {
05943                res = say_and_wait(chan, vms->newmessages, chan->language);
05944                if (!res)
05945                   res = ast_play_and_wait(chan, "vm-messages");
05946                if (!res)
05947                   res = ast_play_and_wait(chan, "vm-INBOX");
05948             }
05949          }
05950          if (vms->oldmessages && !res)
05951             res = ast_play_and_wait(chan, "vm-and");
05952       }
05953       if (vms->oldmessages) {
05954          if (!res) {
05955             if (vms->oldmessages == 1) {
05956                res = ast_play_and_wait(chan, "digits/1M");
05957                if (!res)
05958                   res = ast_play_and_wait(chan, "vm-message");
05959                if (!res)
05960                   res = ast_play_and_wait(chan, "vm-Olds");
05961             } else {
05962                res = say_and_wait(chan, vms->oldmessages, chan->language);
05963                if (!res)
05964                   res = ast_play_and_wait(chan, "vm-messages");
05965                if (!res)
05966                   res = ast_play_and_wait(chan, "vm-Old");
05967             }
05968          }
05969       }
05970    }
05971 return res;
05972 }

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

Definition at line 6023 of file app_voicemail.c.

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

Referenced by vm_intro().

06024 {
06025    /* Introduce messages they have */
06026    int res;
06027    res = ast_play_and_wait(chan, "vm-youhave");
06028    if (!res) {
06029       if (vms->newmessages) {
06030          res = say_and_wait(chan, vms->newmessages, chan->language);
06031          if (!res)
06032             res = ast_play_and_wait(chan, "vm-INBOX");
06033          if (vms->oldmessages && !res)
06034             res = ast_play_and_wait(chan, "vm-and");
06035          else if (!res) {
06036             if ((vms->newmessages == 1))
06037                res = ast_play_and_wait(chan, "vm-message");
06038             else
06039                res = ast_play_and_wait(chan, "vm-messages");
06040          }
06041             
06042       }
06043       if (!res && vms->oldmessages) {
06044          res = say_and_wait(chan, vms->oldmessages, chan->language);
06045          if (!res)
06046             res = ast_play_and_wait(chan, "vm-Old");
06047          if (!res) {
06048             if (vms->oldmessages == 1)
06049                res = ast_play_and_wait(chan, "vm-message");
06050             else
06051                res = ast_play_and_wait(chan, "vm-messages");
06052          }
06053       }
06054       if (!res) {
06055          if (!vms->oldmessages && !vms->newmessages) {
06056             res = ast_play_and_wait(chan, "vm-no");
06057             if (!res)
06058                res = ast_play_and_wait(chan, "vm-messages");
06059          }
06060       }
06061    }
06062    return res;
06063 }

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

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

05598 {
05599    int res = 0;
05600 
05601    if (vms->newmessages) {
05602       res = ast_play_and_wait(chan, "vm-youhave");
05603       if (!res) 
05604          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05605       if (!res) {
05606          if ((vms->newmessages == 1)) {
05607             res = ast_play_and_wait(chan, "vm-INBOX");
05608             if (!res)
05609                res = ast_play_and_wait(chan, "vm-message");
05610          } else {
05611             res = ast_play_and_wait(chan, "vm-INBOXs");
05612             if (!res)
05613                res = ast_play_and_wait(chan, "vm-messages");
05614          }
05615       }
05616    } else if (vms->oldmessages){
05617       res = ast_play_and_wait(chan, "vm-youhave");
05618       if (!res)
05619          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05620       if ((vms->oldmessages == 1)){
05621          res = ast_play_and_wait(chan, "vm-Old");
05622          if (!res)
05623             res = ast_play_and_wait(chan, "vm-message");
05624       } else {
05625          res = ast_play_and_wait(chan, "vm-Olds");
05626          if (!res)
05627             res = ast_play_and_wait(chan, "vm-messages");
05628       }
05629    } else if (!vms->oldmessages && !vms->newmessages) 
05630       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05631    return res;
05632 }

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

Definition at line 5679 of file app_voicemail.c.

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

Referenced by vm_intro().

05680 {
05681    /* Introduce messages they have */
05682    int res;
05683    if (!vms->oldmessages && !vms->newmessages)
05684       res = ast_play_and_wait(chan, "vm-no") ||
05685          ast_play_and_wait(chan, "vm-message");
05686    else
05687       res = ast_play_and_wait(chan, "vm-youhave");
05688    if (!res && vms->newmessages) {
05689       res = (vms->newmessages == 1) ?
05690          ast_play_and_wait(chan, "digits/un") ||
05691          ast_play_and_wait(chan, "vm-nuovo") ||
05692          ast_play_and_wait(chan, "vm-message") :
05693          /* 2 or more new messages */
05694          say_and_wait(chan, vms->newmessages, chan->language) ||
05695          ast_play_and_wait(chan, "vm-nuovi") ||
05696          ast_play_and_wait(chan, "vm-messages");
05697       if (!res && vms->oldmessages)
05698          res = ast_play_and_wait(chan, "vm-and");
05699    }
05700    if (!res && vms->oldmessages) {
05701       res = (vms->oldmessages == 1) ?
05702          ast_play_and_wait(chan, "digits/un") ||
05703          ast_play_and_wait(chan, "vm-vecchio") ||
05704          ast_play_and_wait(chan, "vm-message") :
05705          /* 2 or more old messages */
05706          say_and_wait(chan, vms->oldmessages, chan->language) ||
05707          ast_play_and_wait(chan, "vm-vecchi") ||
05708          ast_play_and_wait(chan, "vm-messages");
05709    }
05710    return res ? -1 : 0;
05711 }

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

Definition at line 6066 of file app_voicemail.c.

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

Referenced by vm_intro().

06067 {
06068    /* Introduce messages they have */
06069    int res;
06070    res = ast_play_and_wait(chan, "vm-youhave");
06071    if (!res) {
06072       if (vms->newmessages) {
06073          res = say_and_wait(chan, vms->newmessages, chan->language);
06074          if (!res) {
06075             if (vms->newmessages == 1)
06076                res = ast_play_and_wait(chan, "vm-INBOXs");
06077             else
06078                res = ast_play_and_wait(chan, "vm-INBOX");
06079          }
06080          if (vms->oldmessages && !res)
06081             res = ast_play_and_wait(chan, "vm-and");
06082          else if (!res) {
06083             if ((vms->newmessages == 1))
06084                res = ast_play_and_wait(chan, "vm-message");
06085             else
06086                res = ast_play_and_wait(chan, "vm-messages");
06087          }
06088             
06089       }
06090       if (!res && vms->oldmessages) {
06091          res = say_and_wait(chan, vms->oldmessages, chan->language);
06092          if (!res) {
06093             if (vms->oldmessages == 1)
06094                res = ast_play_and_wait(chan, "vm-Olds");
06095             else
06096                res = ast_play_and_wait(chan, "vm-Old");
06097          }
06098          if (!res) {
06099             if (vms->oldmessages == 1)
06100                res = ast_play_and_wait(chan, "vm-message");
06101             else
06102                res = ast_play_and_wait(chan, "vm-messages");
06103          }
06104       }
06105       if (!res) {
06106          if (!vms->oldmessages && !vms->newmessages) {
06107             res = ast_play_and_wait(chan, "vm-no");
06108             if (!res)
06109                res = ast_play_and_wait(chan, "vm-messages");
06110          }
06111       }
06112    }
06113    return res;
06114 }

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

Definition at line 5829 of file app_voicemail.c.

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

Referenced by vm_intro().

05830 {
05831    /* Introduce messages they have */
05832    int res;
05833 
05834    res = ast_play_and_wait(chan, "vm-youhave");
05835    if (res)
05836       return res;
05837 
05838    if (!vms->oldmessages && !vms->newmessages) {
05839       res = ast_play_and_wait(chan, "vm-no");
05840       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05841       return res;
05842    }
05843 
05844    if (vms->newmessages) {
05845       if ((vms->newmessages == 1)) {
05846          res = ast_play_and_wait(chan, "digits/1");
05847          res = res ? res : ast_play_and_wait(chan, "vm-ny");
05848          res = res ? res : ast_play_and_wait(chan, "vm-message");
05849       } else {
05850          res = say_and_wait(chan, vms->newmessages, chan->language);
05851          res = res ? res : ast_play_and_wait(chan, "vm-nye");
05852          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05853       }
05854       if (!res && vms->oldmessages)
05855          res = ast_play_and_wait(chan, "vm-and");
05856    }
05857    if (!res && vms->oldmessages) {
05858       if (vms->oldmessages == 1) {
05859          res = ast_play_and_wait(chan, "digits/1");
05860          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
05861          res = res ? res : ast_play_and_wait(chan, "vm-message");
05862       } else {
05863          res = say_and_wait(chan, vms->oldmessages, chan->language);
05864          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
05865          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05866       }
05867    }
05868 
05869    return res;
05870 }

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

Definition at line 5714 of file app_voicemail.c.

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

Referenced by vm_intro().

05715 {
05716    /* Introduce messages they have */
05717    int res;
05718    div_t num;
05719 
05720    if (!vms->oldmessages && !vms->newmessages) {
05721       res = ast_play_and_wait(chan, "vm-no");
05722       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05723       return res;
05724    } else {
05725       res = ast_play_and_wait(chan, "vm-youhave");
05726    }
05727 
05728    if (vms->newmessages) {
05729       num = div(vms->newmessages, 10);
05730       if (vms->newmessages == 1) {
05731          res = ast_play_and_wait(chan, "digits/1-a");
05732          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
05733          res = res ? res : ast_play_and_wait(chan, "vm-message");
05734       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05735          if (num.rem == 2) {
05736             if (!num.quot) {
05737                res = ast_play_and_wait(chan, "digits/2-ie");
05738             } else {
05739                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
05740                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05741             }
05742          } else {
05743             res = say_and_wait(chan, vms->newmessages, chan->language);
05744          }
05745          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
05746          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05747       } else {
05748          res = say_and_wait(chan, vms->newmessages, chan->language);
05749          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
05750          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05751       }
05752       if (!res && vms->oldmessages)
05753          res = ast_play_and_wait(chan, "vm-and");
05754    }
05755    if (!res && vms->oldmessages) {
05756       num = div(vms->oldmessages, 10);
05757       if (vms->oldmessages == 1) {
05758          res = ast_play_and_wait(chan, "digits/1-a");
05759          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
05760          res = res ? res : ast_play_and_wait(chan, "vm-message");
05761       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05762          if (num.rem == 2) {
05763             if (!num.quot) {
05764                res = ast_play_and_wait(chan, "digits/2-ie");
05765             } else {
05766                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
05767                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05768             }
05769          } else {
05770             res = say_and_wait(chan, vms->oldmessages, chan->language);
05771          }
05772          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
05773          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05774       } else {
05775          res = say_and_wait(chan, vms->oldmessages, chan->language);
05776          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
05777          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05778       }
05779    }
05780 
05781    return res;
05782 }

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

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

06118 {
06119    /* Introduce messages they have */
06120    int res;
06121    res = ast_play_and_wait(chan, "vm-youhave");
06122    if (!res) {
06123       if (vms->newmessages) {
06124          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06125          if (!res) {
06126             if ((vms->newmessages == 1)) {
06127                res = ast_play_and_wait(chan, "vm-message");
06128                if (!res)
06129                   res = ast_play_and_wait(chan, "vm-INBOXs");
06130             } else {
06131                res = ast_play_and_wait(chan, "vm-messages");
06132                if (!res)
06133                   res = ast_play_and_wait(chan, "vm-INBOX");
06134             }
06135          }
06136          if (vms->oldmessages && !res)
06137             res = ast_play_and_wait(chan, "vm-and");
06138       }
06139       if (!res && vms->oldmessages) {
06140          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06141          if (!res) {
06142             if (vms->oldmessages == 1) {
06143                res = ast_play_and_wait(chan, "vm-message");
06144                if (!res)
06145                   res = ast_play_and_wait(chan, "vm-Olds");
06146             } else {
06147                res = ast_play_and_wait(chan, "vm-messages");
06148                if (!res)
06149                   res = ast_play_and_wait(chan, "vm-Old");
06150             }
06151          }
06152       }
06153       if (!res) {
06154          if (!vms->oldmessages && !vms->newmessages) {
06155             res = ast_play_and_wait(chan, "vm-no");
06156             if (!res)
06157                res = ast_play_and_wait(chan, "vm-messages");
06158          }
06159       }
06160    }
06161    return res;
06162 }

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

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

05975                                                                          {
05976    /* Introduce messages they have */
05977    int res;
05978    if (!vms->oldmessages && !vms->newmessages) {
05979       res = ast_play_and_wait(chan, "vm-nomessages");
05980       return res;
05981    }
05982    else {
05983       res = ast_play_and_wait(chan, "vm-youhave");
05984    }
05985    if (vms->newmessages) {
05986       if (!res)
05987          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05988       if ((vms->newmessages == 1)) {
05989          if (!res)
05990             res = ast_play_and_wait(chan, "vm-message");
05991          if (!res)
05992             res = ast_play_and_wait(chan, "vm-INBOXs");
05993       }
05994       else {
05995          if (!res)
05996             res = ast_play_and_wait(chan, "vm-messages");
05997          if (!res)
05998             res = ast_play_and_wait(chan, "vm-INBOX");
05999       }
06000       if (vms->oldmessages && !res)
06001          res = ast_play_and_wait(chan, "vm-and");
06002    }
06003    if (vms->oldmessages) {
06004       if (!res)
06005          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06006       if (vms->oldmessages == 1) {
06007          if (!res)
06008             res = ast_play_and_wait(chan, "vm-message");
06009          if (!res)
06010             res = ast_play_and_wait(chan, "vm-Olds");
06011       }
06012       else {
06013          if (!res)
06014       res = ast_play_and_wait(chan, "vm-messages");
06015          if (!res)
06016             res = ast_play_and_wait(chan, "vm-Old");
06017       }
06018    }
06019    return res;
06020 }

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

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

06247 {
06248    int res;
06249    int lastnum = 0;
06250    int dcnum;
06251 
06252    res = ast_play_and_wait(chan, "vm-youhave");
06253    if (!res && vms->newmessages) {
06254       lastnum = get_lastdigits(vms->newmessages);
06255       dcnum = vms->newmessages - lastnum;
06256       if (dcnum)
06257          res = say_and_wait(chan, dcnum, chan->language);
06258       if (!res && lastnum) {
06259          if (lastnum == 1) 
06260             res = ast_play_and_wait(chan, "digits/odno");
06261          else
06262             res = say_and_wait(chan, lastnum, chan->language);
06263       }
06264 
06265       if (!res)
06266          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-novoe" : "vm-novyh");
06267 
06268       if (!res && vms->oldmessages)
06269          res = ast_play_and_wait(chan, "vm-and");
06270    }
06271 
06272    if (!res && vms->oldmessages) {
06273       lastnum = get_lastdigits(vms->oldmessages);
06274       dcnum = vms->oldmessages - lastnum;
06275       if (dcnum)
06276          res = say_and_wait(chan, dcnum, chan->language);
06277       if (!res && lastnum) {
06278          if (lastnum == 1) 
06279             res = ast_play_and_wait(chan, "digits/odno");
06280          else
06281             res = say_and_wait(chan, lastnum, chan->language);
06282       }
06283 
06284       if (!res)
06285          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-staroe" : "vm-staryh");
06286    }
06287 
06288    if (!res && !vms->newmessages && !vms->oldmessages) {
06289       lastnum = 0;
06290       res = ast_play_and_wait(chan, "vm-no");
06291    }
06292 
06293    if (!res) {
06294       switch (lastnum) {
06295       case 1:
06296          res = ast_play_and_wait(chan, "vm-soobshenie");
06297          break;
06298       case 2:
06299       case 3:
06300       case 4:
06301          res = ast_play_and_wait(chan, "vm-soobsheniya");
06302          break;
06303       default:
06304          res = ast_play_and_wait(chan, "vm-soobsheniy");
06305          break;
06306       }
06307    }
06308 
06309    return res;
06310 }

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

Definition at line 5785 of file app_voicemail.c.

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

Referenced by vm_intro().

05786 {
05787    /* Introduce messages they have */
05788    int res;
05789 
05790    res = ast_play_and_wait(chan, "vm-youhave");
05791    if (res)
05792       return res;
05793 
05794    if (!vms->oldmessages && !vms->newmessages) {
05795       res = ast_play_and_wait(chan, "vm-no");
05796       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05797       return res;
05798    }
05799 
05800    if (vms->newmessages) {
05801       if ((vms->newmessages == 1)) {
05802          res = ast_play_and_wait(chan, "digits/ett");
05803          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
05804          res = res ? res : ast_play_and_wait(chan, "vm-message");
05805       } else {
05806          res = say_and_wait(chan, vms->newmessages, chan->language);
05807          res = res ? res : ast_play_and_wait(chan, "vm-nya");
05808          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05809       }
05810       if (!res && vms->oldmessages)
05811          res = ast_play_and_wait(chan, "vm-and");
05812    }
05813    if (!res && vms->oldmessages) {
05814       if (vms->oldmessages == 1) {
05815          res = ast_play_and_wait(chan, "digits/ett");
05816          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
05817          res = res ? res : ast_play_and_wait(chan, "vm-message");
05818       } else {
05819          res = say_and_wait(chan, vms->oldmessages, chan->language);
05820          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
05821          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05822       }
05823    }
05824 
05825    return res;
05826 }

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

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

06321 {
06322    int res;
06323    int lastnum = 0;
06324    int dcnum;
06325 
06326    res = ast_play_and_wait(chan, "vm-youhave");
06327    if (!res && vms->newmessages) {
06328       lastnum = get_lastdigits(vms->newmessages);
06329       dcnum = vms->newmessages - lastnum;
06330       if (dcnum)
06331          res = say_and_wait(chan, dcnum, chan->language);
06332       if (!res && lastnum) {
06333          if (lastnum == 1) 
06334             res = ast_play_and_wait(chan, "digits/ua/1e");
06335          else
06336             res = say_and_wait(chan, lastnum, chan->language);
06337       }
06338 
06339       if (!res)
06340          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-nove" : "vm-INBOX");
06341 
06342       if (!res && vms->oldmessages)
06343          res = ast_play_and_wait(chan, "vm-and");
06344    }
06345 
06346    if (!res && vms->oldmessages) {
06347       lastnum = get_lastdigits(vms->oldmessages);
06348       dcnum = vms->oldmessages - lastnum;
06349       if (dcnum)
06350          res = say_and_wait(chan, dcnum, chan->language);
06351       if (!res && lastnum) {
06352          if (lastnum == 1) 
06353             res = ast_play_and_wait(chan, "digits/ua/1e");
06354          else
06355             res = say_and_wait(chan, lastnum, chan->language);
06356       }
06357 
06358       if (!res)
06359          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-stare" : "vm-Old");
06360    }
06361 
06362    if (!res && !vms->newmessages && !vms->oldmessages) {
06363       lastnum = 0;
06364       res = ast_play_and_wait(chan, "vm-no");
06365    }
06366 
06367    if (!res) {
06368       switch (lastnum) {
06369       case 1:
06370       case 2:
06371       case 3:
06372       case 4:
06373          res = ast_play_and_wait(chan, "vm-message");
06374          break;
06375       default:
06376          res = ast_play_and_wait(chan, "vm-messages");
06377          break;
06378       }
06379    }
06380 
06381    return res;
06382 }

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

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

02117 {
02118    switch (ast_lock_path(path)) {
02119    case AST_LOCK_TIMEOUT:
02120       return -1;
02121    default:
02122       return 0;
02123    }
02124 }

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

Definition at line 905 of file app_voicemail.c.

References my_umask, and VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

00906 {
00907    FILE *p = NULL;
00908    int pfd = mkstemp(template);
00909    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
00910    if (pfd > -1) {
00911       p = fdopen(pfd, "w+");
00912       if (!p) {
00913          close(pfd);
00914          pfd = -1;
00915       }
00916    }
00917    return p;
00918 }

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

06478 {
06479    int cmd = 0;
06480    int duration = 0;
06481    int tries = 0;
06482    char newpassword[80] = "";
06483    char newpassword2[80] = "";
06484    char prefile[PATH_MAX] = "";
06485    unsigned char buf[256];
06486    int bytes=0;
06487 
06488    if (ast_adsi_available(chan)) {
06489       bytes += adsi_logo(buf + bytes);
06490       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
06491       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06492       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06493       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06494       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06495    }
06496 
06497    /* First, have the user change their password 
06498       so they won't get here again */
06499    for (;;) {
06500       newpassword[1] = '\0';
06501       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06502       if (cmd == '#')
06503          newpassword[0] = '\0';
06504       if (cmd < 0 || cmd == 't' || cmd == '#')
06505          return cmd;
06506       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
06507       if (cmd < 0 || cmd == 't' || cmd == '#')
06508          return cmd;
06509       newpassword2[1] = '\0';
06510       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06511       if (cmd == '#')
06512          newpassword2[0] = '\0';
06513       if (cmd < 0 || cmd == 't' || cmd == '#')
06514          return cmd;
06515       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
06516       if (cmd < 0 || cmd == 't' || cmd == '#')
06517          return cmd;
06518       if (!strcmp(newpassword, newpassword2))
06519          break;
06520       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06521       cmd = ast_play_and_wait(chan, "vm-mismatch");
06522       if (++tries == 3)
06523          return -1;
06524    }
06525    if (ast_strlen_zero(ext_pass_cmd)) 
06526       vm_change_password(vmu,newpassword);
06527    else 
06528       vm_change_password_shell(vmu,newpassword);
06529    if (option_debug > 2)
06530       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06531    cmd = ast_play_and_wait(chan,"vm-passchanged");
06532 
06533    /* If forcename is set, have the user record their name */  
06534    if (ast_test_flag(vmu, VM_FORCENAME)) {
06535       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06536       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06537          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06538          if (cmd < 0 || cmd == 't' || cmd == '#')
06539             return cmd;
06540       }
06541    }
06542 
06543    /* If forcegreetings is set, have the user record their greetings */
06544    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06545       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06546       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06547          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06548          if (cmd < 0 || cmd == 't' || cmd == '#')
06549             return cmd;
06550       }
06551 
06552       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06553       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06554          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06555          if (cmd < 0 || cmd == 't' || cmd == '#')
06556             return cmd;
06557       }
06558    }
06559 
06560    return cmd;
06561 }

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

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_waitfordigit(), ast_vm_user::context, 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().

06564 {
06565    int cmd = 0;
06566    int retries = 0;
06567    int duration = 0;
06568    char newpassword[80] = "";
06569    char newpassword2[80] = "";
06570    char prefile[PATH_MAX] = "";
06571    unsigned char buf[256];
06572    int bytes=0;
06573 
06574    if (ast_adsi_available(chan))
06575    {
06576       bytes += adsi_logo(buf + bytes);
06577       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06578       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06579       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06580       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06581       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06582    }
06583    while ((cmd >= 0) && (cmd != 't')) {
06584       if (cmd)
06585          retries = 0;
06586       switch (cmd) {
06587       case '1':
06588          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06589          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06590          break;
06591       case '2': 
06592          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06593          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06594          break;
06595       case '3': 
06596          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06597          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06598          break;
06599       case '4': 
06600          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06601          break;
06602       case '5':
06603          if (vmu->password[0] == '-') {
06604             cmd = ast_play_and_wait(chan, "vm-no");
06605             break;
06606          }
06607          newpassword[1] = '\0';
06608          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06609          if (cmd == '#')
06610             newpassword[0] = '\0';
06611          else {
06612             if (cmd < 0)
06613                break;
06614             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06615                break;
06616             }
06617          }
06618          newpassword2[1] = '\0';
06619          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06620          if (cmd == '#')
06621             newpassword2[0] = '\0';
06622          else {
06623             if (cmd < 0)
06624                break;
06625 
06626             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
06627                break;
06628             }
06629          }
06630          if (strcmp(newpassword, newpassword2)) {
06631             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06632             cmd = ast_play_and_wait(chan, "vm-mismatch");
06633             break;
06634          }
06635          if (ast_strlen_zero(ext_pass_cmd)) 
06636             vm_change_password(vmu,newpassword);
06637          else 
06638             vm_change_password_shell(vmu,newpassword);
06639          if (option_debug > 2)
06640             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06641          cmd = ast_play_and_wait(chan,"vm-passchanged");
06642          break;
06643       case '*': 
06644          cmd = 't';
06645          break;
06646       default: 
06647          cmd = 0;
06648          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06649          if (ast_fileexists(prefile, NULL, NULL))
06650             cmd = ast_play_and_wait(chan, "vm-tmpexists");
06651          if (!cmd)
06652             cmd = ast_play_and_wait(chan, "vm-options");
06653          if (!cmd)
06654             cmd = ast_waitfordigit(chan,6000);
06655          if (!cmd)
06656             retries++;
06657          if (retries > 3)
06658             cmd = 't';
06659       }
06660    }
06661    if (cmd == 't')
06662       cmd = 0;
06663    return cmd;
06664 }

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

Definition at line 5566 of file app_voicemail.c.

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

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

05567 {
05568    int cmd;
05569 
05570    if (!strncasecmp(chan->language, "it", 2) || !strncasecmp(chan->language, "es", 2) || !strncasecmp(chan->language, "fr", 2) || !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, French or Portuguese syntax */
05571       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05572       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05573    } else if (!strncasecmp(chan->language, "gr", 2)){
05574       return vm_play_folder_name_gr(chan, mbox);
05575    } else if (!strncasecmp(chan->language, "pl", 2)){
05576       return vm_play_folder_name_pl(chan, mbox);
05577    } else if (!strncasecmp(chan->language, "ua", 2)){  /* Ukrainian syntax */
05578       return vm_play_folder_name_ua(chan, mbox);
05579    } else {  /* Default English */
05580       cmd = ast_play_and_wait(chan, mbox);
05581       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05582    }
05583 }

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

Definition at line 5519 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05520 {
05521    int cmd;
05522    char *buf;
05523 
05524    buf = alloca(strlen(mbox)+2); 
05525    strcpy(buf, mbox);
05526    strcat(buf,"s");
05527 
05528    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
05529       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
05530       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05531    } else {
05532       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05533       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
05534    }
05535 }

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

Definition at line 5537 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05538 {
05539    int cmd;
05540 
05541    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05542       if (!strcasecmp(mbox, "vm-INBOX"))
05543          cmd = ast_play_and_wait(chan, "vm-new-e");
05544       else
05545          cmd = ast_play_and_wait(chan, "vm-old-e");
05546       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05547    } else {
05548       cmd = ast_play_and_wait(chan, "vm-messages");
05549       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05550    }
05551 }

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

Definition at line 5553 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05554 {
05555    int cmd;
05556 
05557    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05558       cmd = ast_play_and_wait(chan, "vm-messages");
05559       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05560    } else {
05561       cmd = ast_play_and_wait(chan, mbox);
05562       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05563    }
05564 }

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

Referenced by vm_options().

06667 {
06668    int res;
06669    int cmd = 0;
06670    int retries = 0;
06671    int duration = 0;
06672    char prefile[PATH_MAX] = "";
06673    unsigned char buf[256];
06674    char dest[PATH_MAX];
06675    int bytes = 0;
06676 
06677    if (ast_adsi_available(chan)) {
06678       bytes += adsi_logo(buf + bytes);
06679       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
06680       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06681       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06682       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06683       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06684    }
06685 
06686    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06687    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
06688       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
06689       return -1;
06690    }
06691    while ((cmd >= 0) && (cmd != 't')) {
06692       if (cmd)
06693          retries = 0;
06694       RETRIEVE(prefile, -1, vmu);
06695       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
06696          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06697          cmd = 't';  
06698       } else {
06699          switch (cmd) {
06700          case '1':
06701             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06702             break;
06703          case '2':
06704             DELETE(prefile, -1, prefile, vmu);
06705             ast_play_and_wait(chan, "vm-tempremoved");
06706             cmd = 't';  
06707             break;
06708          case '*': 
06709             cmd = 't';
06710             break;
06711          default:
06712             cmd = ast_play_and_wait(chan,
06713                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
06714                   "vm-tempgreeting2" : "vm-tempgreeting");
06715             if (!cmd)
06716                cmd = ast_waitfordigit(chan,6000);
06717             if (!cmd)
06718                retries++;
06719             if (retries > 3)
06720                cmd = 't';
06721          }
06722       }
06723       DISPOSE(prefile, -1);
06724    }
06725    if (cmd == 't')
06726       cmd = 0;
06727    return cmd;
06728 }

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

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

07648 {
07649    struct ast_module_user *u;
07650    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
07651    struct ast_vm_user vmus;
07652    char *options = NULL;
07653    int silent = 0, skipuser = 0;
07654    int res = -1;
07655 
07656    u = ast_module_user_add(chan);
07657    
07658    if (s) {
07659       s = ast_strdupa(s);
07660       user = strsep(&s, "|");
07661       options = strsep(&s, "|");
07662       if (user) {
07663          s = user;
07664          user = strsep(&s, "@");
07665          context = strsep(&s, "");
07666          if (!ast_strlen_zero(user))
07667             skipuser++;
07668          ast_copy_string(mailbox, user, sizeof(mailbox));
07669       }
07670    }
07671 
07672    if (options) {
07673       silent = (strchr(options, 's')) != NULL;
07674    }
07675 
07676    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
07677       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
07678       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
07679       ast_play_and_wait(chan, "auth-thankyou");
07680       res = 0;
07681    }
07682 
07683    ast_module_user_remove(u);
07684    return res;
07685 }

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

Definition at line 2955 of file app_voicemail.c.

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

Referenced by make_email_file(), and sendpage().

02956 {
02957    const struct vm_zone *z = NULL;
02958    time_t t = time(NULL);
02959 
02960    /* Does this user have a timezone specified? */
02961    if (!ast_strlen_zero(vmu->zonetag)) {
02962       /* Find the zone in the list */
02963       AST_LIST_LOCK(&zones);
02964       AST_LIST_TRAVERSE(&zones, z, list) {
02965          if (!strcmp(z->name, vmu->zonetag))
02966             break;
02967       }
02968       AST_LIST_UNLOCK(&zones);
02969    }
02970    ast_localtime(&t, tm, z ? z->timezone : NULL);
02971    return tm;
02972 }

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

Definition at line 5092 of file app_voicemail.c.

References ast_control_streamfile(), and skipms.

05093 {
05094    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05095 }

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

Definition at line 5084 of file app_voicemail.c.

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

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

05085 {
05086    int res;
05087    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05088       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05089    return res;
05090 }


Variable Documentation

char* addesc = "Comedian Mail" [static]

Definition at line 447 of file app_voicemail.c.

Referenced by adsi_load_vmail().

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

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

Referenced by adsi_load_vmail(), and load_config().

int adsiver = 1 [static]

Definition at line 570 of file app_voicemail.c.

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

char* app = "VoiceMail" [static]

Definition at line 523 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 526 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 528 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 529 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 553 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

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

Definition at line 566 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 556 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 7789 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 7794 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 7799 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 452 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vm_box_exists [static]

Definition at line 498 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vmain [static]

Definition at line 480 of file app_voicemail.c.

Referenced by load_module().

char* descrip_vmauthenticate [static]

Definition at line 512 of file app_voicemail.c.

Referenced by load_module().

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 552 of file app_voicemail.c.

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

char* emailbody = NULL [static]

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

Referenced by load_config(), and make_email_file().

char* emailsubject = NULL [static]

Definition at line 560 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char emailtitle[100] [static]

Definition at line 565 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 554 of file app_voicemail.c.

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

char ext_pass_cmd[128] [static]

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

Referenced by load_config(), and run_externnotify().

char fromstring[100] [static]

Definition at line 563 of file app_voicemail.c.

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

struct ast_flags globalflags = {0} [static]

Definition at line 548 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 537 of file app_voicemail.c.

Referenced by load_config().

int maxgreet [static]

Definition at line 544 of file app_voicemail.c.

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

int maxlogins [static]

Definition at line 546 of file app_voicemail.c.

Referenced by load_config(), and vm_execmain().

int maxmsg [static]

Definition at line 534 of file app_voicemail.c.

Referenced by load_config().

int maxsilence [static]

Definition at line 533 of file app_voicemail.c.

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

int my_umask

Definition at line 435 of file app_voicemail.c.

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

char* pagerbody = NULL [static]

Definition at line 561 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char pagerfromstring[100] [static]

Definition at line 564 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char* pagersubject = NULL [static]

Definition at line 562 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

int saydurationminfo [static]

Definition at line 550 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

char serveremail[80] [static]

Definition at line 536 of file app_voicemail.c.

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

int silencethreshold = 128 [static]

Definition at line 535 of file app_voicemail.c.

int skipms [static]

Definition at line 545 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 539 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 449 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 495 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 477 of file app_voicemail.c.

Referenced by load_module().

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 509 of file app_voicemail.c.

Referenced by load_module().

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

Definition at line 445 of file app_voicemail.c.

Referenced by load_config(), and pbx_load_users().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 431 of file app_voicemail.c.

Referenced by __has_voicemail(), 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 540 of file app_voicemail.c.

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

int vmmaxmessage [static]

Definition at line 543 of file app_voicemail.c.

Referenced by leave_voicemail(), and load_config().

int vmminmessage [static]

Definition at line 542 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 7687 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 7691 of file app_voicemail.c.

double volgain [static]

Definition at line 541 of file app_voicemail.c.

Referenced by load_config().


Generated on Mon Nov 24 15:34:25 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7