Mon Mar 31 07:38:52 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"

Include dependency graph for app_voicemail.c:

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
struct  vm_state
struct  vm_zone

Defines

#define ASTERISK_USERNAME   "asterisk"
#define BASELINELEN   72
#define BASEMAXINLINE   256
#define BASEMAXINLINE   256
#define CHUNKSIZE   65536
#define COMMAND_TIMEOUT   5000
#define COPY(a, b, c, d, e, f, g, h)   (copy_plain_file(g,h));
#define DELETE(a, b, c)   (vm_delete(c))
#define DISPOSE(a, b)
#define ENDL   "\n"
#define eol   "\r\n"
#define ERROR_LOCK_PATH   -100
#define 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)
#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_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, int len, char *dir, int num)
static const char * mbox (int id)
static int messagecount (const char *context, const char *mailbox, const char *folder)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static int ochar (struct baseio *bio, int c, FILE *so)
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
static int play_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 int unload_module (void)
static int vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
static int vm_box_exists (struct ast_channel *chan, void *data)
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static void vm_change_password (struct ast_vm_user *vmu, const char *newpassword)
static void vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword)
static int vm_delete (char *file)
static int vm_exec (struct ast_channel *chan, void *data)
static int vm_execmain (struct ast_channel *chan, void *data)
static int vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vmfmts, char *context, signed char record_gain, long *duration, struct vm_state *vms)
static int vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static int vm_intro_cz (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_it (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_nl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_no (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_ru (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_se (struct ast_channel *chan, struct vm_state *vms)
static int vm_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 165 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 181 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 182 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 182 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 162 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 158 of file app_voicemail.c.

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

Definition at line 427 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 428 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 423 of file app_voicemail.c.

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

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

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

Referenced by save_to_folder().

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

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

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 185 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 186 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 173 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

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

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( 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(), and vm_tempgreeting().

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

Definition at line 169 of file app_voicemail.c.

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 156 of file app_voicemail.c.

Referenced by run_externnotify().

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

Definition at line 424 of file app_voicemail.c.

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

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 443 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

Definition at line 201 of file app_voicemail.c.

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

#define VM_ATTACH   (1 << 11)

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

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 198 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

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

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

#define VM_OPERATOR   (1 << 1)

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

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 188 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 190 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 193 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

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

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

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

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 164 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 160 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

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

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

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 218 of file app_voicemail.c.

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


Function Documentation

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

Definition at line 2670 of file app_voicemail.c.

References ast_strlen_zero(), and VM_SPOOL_DIR.

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

02671 {
02672    DIR *dir;
02673    struct dirent *de;
02674    char fn[256];
02675    int ret = 0;
02676    if (!folder)
02677       folder = "INBOX";
02678    /* If no mailbox, return immediately */
02679    if (ast_strlen_zero(mailbox))
02680       return 0;
02681    if (!context)
02682       context = "default";
02683    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
02684    dir = opendir(fn);
02685    if (!dir)
02686       return 0;
02687    while ((de = readdir(dir))) {
02688       if (!strncasecmp(de->d_name, "msg", 3)) {
02689          if (shortcircuit) {
02690             ret = 1;
02691             break;
02692          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
02693             ret++;
02694       }
02695    }
02696    closedir(dir);
02697    return ret;
02698 }

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

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

03437 {
03438    int x;
03439    if (!ast_adsi_available(chan))
03440       return;
03441    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
03442    if (x < 0)
03443       return;
03444    if (!x) {
03445       if (adsi_load_vmail(chan, useadsi)) {
03446          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
03447          return;
03448       }
03449    } else
03450       *useadsi = 1;
03451 }

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

Definition at line 3623 of file app_voicemail.c.

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

Referenced by vm_execmain().

03624 {
03625    int bytes=0;
03626    unsigned char buf[256];
03627    unsigned char keys[8];
03628 
03629    int x;
03630 
03631    if (!ast_adsi_available(chan))
03632       return;
03633 
03634    /* New meaning for keys */
03635    for (x=0;x<5;x++)
03636       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03637 
03638    keys[6] = 0x0;
03639    keys[7] = 0x0;
03640 
03641    if (!vms->curmsg) {
03642       /* No prev key, provide "Folder" instead */
03643       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03644    }
03645    if (vms->curmsg >= vms->lastmsg) {
03646       /* If last message ... */
03647       if (vms->curmsg) {
03648          /* but not only message, provide "Folder" instead */
03649          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03650       } else {
03651          /* Otherwise if only message, leave blank */
03652          keys[3] = 1;
03653       }
03654    }
03655 
03656    /* If deleted, show "undeleted" */
03657    if (vms->deleted[vms->curmsg]) 
03658       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03659 
03660    /* Except "Exit" */
03661    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03662    bytes += ast_adsi_set_keys(buf + bytes, keys);
03663    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03664 
03665    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03666 }

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

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

03502 {
03503    unsigned char buf[256];
03504    int bytes=0;
03505    unsigned char keys[8];
03506    int x,y;
03507 
03508    if (!ast_adsi_available(chan))
03509       return;
03510 
03511    for (x=0;x<5;x++) {
03512       y = ADSI_KEY_APPS + 12 + start + x;
03513       if (y > ADSI_KEY_APPS + 12 + 4)
03514          y = 0;
03515       keys[x] = ADSI_KEY_SKT | y;
03516    }
03517    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
03518    keys[6] = 0;
03519    keys[7] = 0;
03520 
03521    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
03522    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
03523    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03524    bytes += ast_adsi_set_keys(buf + bytes, keys);
03525    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03526 
03527    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03528 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

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

03772 {
03773    unsigned char buf[256];
03774    int bytes=0;
03775 
03776    if (!ast_adsi_available(chan))
03777       return;
03778    bytes += adsi_logo(buf + bytes);
03779    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
03780    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
03781    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03782    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03783 
03784    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03785 }

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

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

03306 {
03307    unsigned char buf[256];
03308    int bytes=0;
03309    int x;
03310    char num[5];
03311 
03312    *useadsi = 0;
03313    bytes += ast_adsi_data_mode(buf + bytes);
03314    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03315 
03316    bytes = 0;
03317    bytes += adsi_logo(buf);
03318    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
03319 #ifdef DISPLAY
03320    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
03321 #endif
03322    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03323    bytes += ast_adsi_data_mode(buf + bytes);
03324    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03325 
03326    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
03327       bytes = 0;
03328       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
03329       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
03330       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03331       bytes += ast_adsi_voice_mode(buf + bytes, 0);
03332       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03333       return 0;
03334    }
03335 
03336 #ifdef DISPLAY
03337    /* Add a dot */
03338    bytes = 0;
03339    bytes += ast_adsi_logo(buf);
03340    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
03341    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
03342    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03343    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03344 #endif
03345    bytes = 0;
03346    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
03347    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
03348    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
03349    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
03350    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
03351    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
03352    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03353 
03354 #ifdef DISPLAY
03355    /* Add another dot */
03356    bytes = 0;
03357    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
03358    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03359 
03360    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03361    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03362 #endif
03363 
03364    bytes = 0;
03365    /* These buttons we load but don't use yet */
03366    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
03367    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
03368    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
03369    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
03370    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
03371    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
03372    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03373 
03374 #ifdef DISPLAY
03375    /* Add another dot */
03376    bytes = 0;
03377    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
03378    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03379    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03380 #endif
03381 
03382    bytes = 0;
03383    for (x=0;x<5;x++) {
03384       snprintf(num, sizeof(num), "%d", x);
03385       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
03386    }
03387    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
03388    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03389 
03390 #ifdef DISPLAY
03391    /* Add another dot */
03392    bytes = 0;
03393    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
03394    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03395    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03396 #endif
03397 
03398    if (ast_adsi_end_download(chan)) {
03399       bytes = 0;
03400       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
03401       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
03402       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03403       bytes += ast_adsi_voice_mode(buf + bytes, 0);
03404       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03405       return 0;
03406    }
03407    bytes = 0;
03408    bytes += ast_adsi_download_disconnect(buf + bytes);
03409    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03410    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
03411 
03412    if (option_debug)
03413       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
03414 
03415 #ifdef DISPLAY
03416    /* Add last dot */
03417    bytes = 0;
03418    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
03419    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03420 #endif
03421    if (option_debug)
03422       ast_log(LOG_DEBUG, "Restarting session...\n");
03423 
03424    bytes = 0;
03425    /* Load the session now */
03426    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
03427       *useadsi = 1;
03428       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
03429    } else
03430       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
03431 
03432    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03433    return 0;
03434 }

static void adsi_login ( struct ast_channel chan  )  [static]

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

03454 {
03455    unsigned char buf[256];
03456    int bytes=0;
03457    unsigned char keys[8];
03458    int x;
03459    if (!ast_adsi_available(chan))
03460       return;
03461 
03462    for (x=0;x<8;x++)
03463       keys[x] = 0;
03464    /* Set one key for next */
03465    keys[3] = ADSI_KEY_APPS + 3;
03466 
03467    bytes += adsi_logo(buf + bytes);
03468    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
03469    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
03470    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03471    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
03472    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
03473    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
03474    bytes += ast_adsi_set_keys(buf + bytes, keys);
03475    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03476    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03477 }

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

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

03298 {
03299    int bytes = 0;
03300    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
03301    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
03302    return bytes;
03303 }

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

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

03531 {
03532    int bytes=0;
03533    unsigned char buf[256]; 
03534    char buf1[256], buf2[256];
03535    char fn2[PATH_MAX];
03536 
03537    char cid[256]="";
03538    char *val;
03539    char *name, *num;
03540    char datetime[21]="";
03541    FILE *f;
03542 
03543    unsigned char keys[8];
03544 
03545    int x;
03546 
03547    if (!ast_adsi_available(chan))
03548       return;
03549 
03550    /* Retrieve important info */
03551    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
03552    f = fopen(fn2, "r");
03553    if (f) {
03554       while (!feof(f)) {   
03555          fgets((char *)buf, sizeof(buf), f);
03556          if (!feof(f)) {
03557             char *stringp=NULL;
03558             stringp = (char *)buf;
03559             strsep(&stringp, "=");
03560             val = strsep(&stringp, "=");
03561             if (!ast_strlen_zero(val)) {
03562                if (!strcmp((char *)buf, "callerid"))
03563                   ast_copy_string(cid, val, sizeof(cid));
03564                if (!strcmp((char *)buf, "origdate"))
03565                   ast_copy_string(datetime, val, sizeof(datetime));
03566             }
03567          }
03568       }
03569       fclose(f);
03570    }
03571    /* New meaning for keys */
03572    for (x=0;x<5;x++)
03573       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
03574    keys[6] = 0x0;
03575    keys[7] = 0x0;
03576 
03577    if (!vms->curmsg) {
03578       /* No prev key, provide "Folder" instead */
03579       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03580    }
03581    if (vms->curmsg >= vms->lastmsg) {
03582       /* If last message ... */
03583       if (vms->curmsg) {
03584          /* but not only message, provide "Folder" instead */
03585          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
03586          bytes += ast_adsi_voice_mode(buf + bytes, 0);
03587 
03588       } else {
03589          /* Otherwise if only message, leave blank */
03590          keys[3] = 1;
03591       }
03592    }
03593 
03594    if (!ast_strlen_zero(cid)) {
03595       ast_callerid_parse(cid, &name, &num);
03596       if (!name)
03597          name = num;
03598    } else
03599       name = "Unknown Caller";
03600 
03601    /* If deleted, show "undeleted" */
03602 
03603    if (vms->deleted[vms->curmsg])
03604       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
03605 
03606    /* Except "Exit" */
03607    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
03608    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
03609       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
03610    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
03611 
03612    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03613    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03614    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
03615    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
03616    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03617    bytes += ast_adsi_set_keys(buf + bytes, keys);
03618    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03619 
03620    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03621 }

static void adsi_password ( struct ast_channel chan  )  [static]

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

03480 {
03481    unsigned char buf[256];
03482    int bytes=0;
03483    unsigned char keys[8];
03484    int x;
03485    if (!ast_adsi_available(chan))
03486       return;
03487 
03488    for (x=0;x<8;x++)
03489       keys[x] = 0;
03490    /* Set one key for next */
03491    keys[3] = ADSI_KEY_APPS + 3;
03492 
03493    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03494    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
03495    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
03496    bytes += ast_adsi_set_keys(buf + bytes, keys);
03497    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03498    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03499 }

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

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

03669 {
03670    unsigned char buf[256] = "";
03671    char buf1[256] = "", buf2[256] = "";
03672    int bytes=0;
03673    unsigned char keys[8];
03674    int x;
03675 
03676    char *newm = (vms->newmessages == 1) ? "message" : "messages";
03677    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
03678    if (!ast_adsi_available(chan))
03679       return;
03680    if (vms->newmessages) {
03681       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
03682       if (vms->oldmessages) {
03683          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
03684          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
03685       } else {
03686          snprintf(buf2, sizeof(buf2), "%s.", newm);
03687       }
03688    } else if (vms->oldmessages) {
03689       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
03690       snprintf(buf2, sizeof(buf2), "%s.", oldm);
03691    } else {
03692       strcpy(buf1, "You have no messages.");
03693       buf2[0] = ' ';
03694       buf2[1] = '\0';
03695    }
03696    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03697    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03698    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03699 
03700    for (x=0;x<6;x++)
03701       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03702    keys[6] = 0;
03703    keys[7] = 0;
03704 
03705    /* Don't let them listen if there are none */
03706    if (vms->lastmsg < 0)
03707       keys[0] = 1;
03708    bytes += ast_adsi_set_keys(buf + bytes, keys);
03709 
03710    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03711 
03712    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03713 }

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

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

03716 {
03717    unsigned char buf[256] = "";
03718    char buf1[256] = "", buf2[256] = "";
03719    int bytes=0;
03720    unsigned char keys[8];
03721    int x;
03722 
03723    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
03724 
03725    if (!ast_adsi_available(chan))
03726       return;
03727 
03728    /* Original command keys */
03729    for (x=0;x<6;x++)
03730       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
03731 
03732    keys[6] = 0;
03733    keys[7] = 0;
03734 
03735    if ((vms->lastmsg + 1) < 1)
03736       keys[0] = 0;
03737 
03738    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
03739       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
03740 
03741    if (vms->lastmsg + 1)
03742       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
03743    else
03744       strcpy(buf2, "no messages.");
03745    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
03746    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
03747    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
03748    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
03749    bytes += ast_adsi_set_keys(buf + bytes, keys);
03750 
03751    bytes += ast_adsi_voice_mode(buf + bytes, 0);
03752 
03753    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
03754    
03755 }

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 8023 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(), LOG_DEBUG, LOG_ERROR, make_file(), name, option_debug, option_verbose, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, VERBOSE_PREFIX_3, and wait_file().

Referenced by vm_execmain().

08024 {
08025    int res = 0;
08026 #ifdef IMAP_STORAGE
08027    char origtimeS[256],cidS[256],contextS[256];
08028    char *header_content,*temp;
08029 #endif
08030    char filename[PATH_MAX];
08031    struct ast_config *msg_cfg = NULL;
08032    const char *origtime, *context;
08033    char *cid, *name, *num;
08034    int retries = 0;
08035 
08036    vms->starting = 0; 
08037 #ifdef IMAP_STORAGE
08038    /* START HERE */
08039    /* get the message info!! */
08040    if (option_debug > 2)
08041       ast_log (LOG_DEBUG,"Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n",vms->curmsg, vms->msgArray[vms->curmsg]);
08042    if (vms->msgArray[vms->curmsg] == 0) {
08043       ast_log (LOG_WARNING,"Trying to access unknown message\n");
08044       return -1;
08045    }
08046 
08047    /* This will only work for new messages... */
08048    header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
08049    /* empty string means no valid header */
08050    if (ast_strlen_zero(header_content)) {
08051       ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
08052       return -1;
08053    }
08054 
08055    /* Get info from headers!! */
08056    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Caller-ID-Num:");
08057    
08058    if (temp)
08059       ast_copy_string(cidS,temp, sizeof(cidS));
08060    else
08061       cidS[0] = '\0';
08062    
08063    cid = &cidS[0];
08064    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Context:");
08065    
08066    if (temp)
08067       ast_copy_string(contextS,temp, sizeof(contextS));
08068    else
08069       contextS[0] = '\0';
08070    
08071    context = &contextS[0];
08072    temp = get_header_by_tag(header_content, "X-Asterisk-VM-Orig-time:");
08073    
08074    if (temp)
08075       ast_copy_string(origtimeS,temp, sizeof(origtimeS));
08076    else
08077       origtimeS[0] = '\0';
08078    
08079    origtime = &origtimeS[0];
08080    
08081    ast_copy_string(filename, "IMAP_STORAGE", sizeof(filename));
08082 #else
08083    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08084 
08085    /* Retrieve info from VM attribute file */
08086 
08087    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08088    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08089    RETRIEVE(vms->curdir, vms->curmsg);
08090    msg_cfg = ast_config_load(filename);
08091    DISPOSE(vms->curdir, vms->curmsg);
08092    if (!msg_cfg) {
08093       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08094       return 0;
08095    }
08096 
08097    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08098       ast_config_destroy(msg_cfg);
08099       return 0;
08100    }
08101 
08102    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08103 
08104    context = ast_variable_retrieve(msg_cfg, "message", "context");
08105    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08106       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08107 #endif
08108    switch (option) {
08109    case 3:
08110       if (!res)
08111          res = play_message_datetime(chan, vmu, origtime, filename);
08112       if (!res)
08113          res = play_message_callerid(chan, vms, cid, context, 0);
08114 
08115       res = 't';
08116       break;
08117 
08118    case 2:  /* Call back */
08119 
08120       if (ast_strlen_zero(cid))
08121          break;
08122 
08123       ast_callerid_parse(cid, &name, &num);
08124       while ((res > -1) && (res != 't')) {
08125          switch (res) {
08126          case '1':
08127             if (num) {
08128                /* Dial the CID number */
08129                res = dialout(chan, vmu, num, vmu->callback);
08130                if (res) {
08131                   ast_config_destroy(msg_cfg);
08132                   return 9;
08133                }
08134             } else {
08135                res = '2';
08136             }
08137             break;
08138 
08139          case '2':
08140             /* Want to enter a different number, can only do this if there's a dialout context for this user */
08141             if (!ast_strlen_zero(vmu->dialout)) {
08142                res = dialout(chan, vmu, NULL, vmu->dialout);
08143                if (res) {
08144                   ast_config_destroy(msg_cfg);
08145                   return 9;
08146                }
08147             } else {
08148                if (option_verbose > 2)
08149                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
08150                res = ast_play_and_wait(chan, "vm-sorry");
08151             }
08152             ast_config_destroy(msg_cfg);
08153             return res;
08154          case '*':
08155             res = 't';
08156             break;
08157          case '3':
08158          case '4':
08159          case '5':
08160          case '6':
08161          case '7':
08162          case '8':
08163          case '9':
08164          case '0':
08165 
08166             res = ast_play_and_wait(chan, "vm-sorry");
08167             retries++;
08168             break;
08169          default:
08170             if (num) {
08171                if (option_verbose > 2)
08172                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
08173                res = ast_play_and_wait(chan, "vm-num-i-have");
08174                if (!res)
08175                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
08176                if (!res)
08177                   res = ast_play_and_wait(chan, "vm-tocallnum");
08178                /* Only prompt for a caller-specified number if there is a dialout context specified */
08179                if (!ast_strlen_zero(vmu->dialout)) {
08180                   if (!res)
08181                      res = ast_play_and_wait(chan, "vm-calldiffnum");
08182                }
08183             } else {
08184                res = ast_play_and_wait(chan, "vm-nonumber");
08185                if (!ast_strlen_zero(vmu->dialout)) {
08186                   if (!res)
08187                      res = ast_play_and_wait(chan, "vm-toenternumber");
08188                }
08189             }
08190             if (!res)
08191                res = ast_play_and_wait(chan, "vm-star-cancel");
08192             if (!res)
08193                res = ast_waitfordigit(chan, 6000);
08194             if (!res) {
08195                retries++;
08196                if (retries > 3)
08197                   res = 't';
08198             }
08199             break; 
08200             
08201          }
08202          if (res == 't')
08203             res = 0;
08204          else if (res == '*')
08205             res = -1;
08206       }
08207       break;
08208       
08209    case 1:  /* Reply */
08210       /* Send reply directly to sender */
08211       if (ast_strlen_zero(cid))
08212          break;
08213 
08214       ast_callerid_parse(cid, &name, &num);
08215       if (!num) {
08216          if (option_verbose > 2)
08217             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
08218          if (!res)
08219             res = ast_play_and_wait(chan, "vm-nonumber");
08220          ast_config_destroy(msg_cfg);
08221          return res;
08222       } else {
08223          struct ast_vm_user vmu2;
08224          if (find_user(&vmu2, vmu->context, num)) {
08225             struct leave_vm_options leave_options;
08226             char mailbox[AST_MAX_EXTENSION * 2 + 2];
08227             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
08228 
08229             if (option_verbose > 2)
08230                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
08231             
08232             memset(&leave_options, 0, sizeof(leave_options));
08233             leave_options.record_gain = record_gain;
08234             res = leave_voicemail(chan, mailbox, &leave_options);
08235             if (!res)
08236                res = 't';
08237             ast_config_destroy(msg_cfg);
08238             return res;
08239          } else {
08240             /* Sender has no mailbox, can't reply */
08241             if (option_verbose > 2)
08242                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
08243             ast_play_and_wait(chan, "vm-nobox");
08244             res = 't';
08245             ast_config_destroy(msg_cfg);
08246             return res;
08247          }
08248       } 
08249       res = 0;
08250 
08251       break;
08252    }
08253 
08254 #ifndef IMAP_STORAGE
08255    ast_config_destroy(msg_cfg);
08256 
08257    if (!res) {
08258       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08259       vms->heard[msg] = 1;
08260       res = wait_file(chan, vms, vms->fn);
08261    }
08262 #endif
08263    return res;
08264 }

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

Definition at line 7131 of file app_voicemail.c.

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

Referenced by load_config().

07132 {
07133    /* Assumes lock is already held */
07134    char *tmp;
07135    char *stringp;
07136    char *s;
07137    struct ast_vm_user *vmu;
07138 
07139    tmp = ast_strdupa(data);
07140 
07141    if ((vmu = find_or_create(context, mbox))) {
07142       populate_defaults(vmu);
07143 
07144       stringp = tmp;
07145       if ((s = strsep(&stringp, ","))) 
07146          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07147       if (stringp && (s = strsep(&stringp, ","))) 
07148          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
07149       if (stringp && (s = strsep(&stringp, ","))) 
07150          ast_copy_string(vmu->email, s, sizeof(vmu->email));
07151       if (stringp && (s = strsep(&stringp, ","))) 
07152          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
07153       if (stringp && (s = strsep(&stringp, ","))) 
07154          apply_options(vmu, s);
07155    }
07156    return 0;
07157 }

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

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

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

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

Definition at line 670 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00671 {  /* Destructively Parse options and apply */
00672    char *stringp;
00673    char *s;
00674    char *var, *value;
00675    stringp = ast_strdupa(options);
00676    while ((s = strsep(&stringp, "|"))) {
00677       value = s;
00678       if ((var = strsep(&value, "=")) && value) {
00679          apply_option(vmu, var, value);
00680       }
00681    }  
00682 }

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

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

00685 {
00686    struct ast_variable *tmp;
00687    tmp = var;
00688    while (tmp) {
00689       if (!strcasecmp(tmp->name, "vmsecret")) {
00690          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00691       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00692          if (ast_strlen_zero(retval->password))
00693             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00694       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00695          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00696       } else if (!strcasecmp(tmp->name, "pager")) {
00697          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00698       } else if (!strcasecmp(tmp->name, "email")) {
00699          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00700       } else if (!strcasecmp(tmp->name, "fullname")) {
00701          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00702       } else if (!strcasecmp(tmp->name, "context")) {
00703          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00704 #ifdef IMAP_STORAGE
00705       } else if (!strcasecmp(tmp->name, "imapuser")) {
00706          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00707       } else if (!strcasecmp(tmp->name, "imappassword")) {
00708          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00709 #endif
00710       } else
00711          apply_option(retval, tmp->name, tmp->value);
00712       tmp = tmp->next;
00713    } 
00714 }

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

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

Referenced by make_email_file().

01641 {
01642    unsigned char dtable[BASEMAXINLINE];
01643    int i,hiteof= 0;
01644    FILE *fi;
01645    struct baseio bio;
01646 
01647    memset(&bio, 0, sizeof(bio));
01648    bio.iocp = BASEMAXINLINE;
01649 
01650    if (!(fi = fopen(filename, "rb"))) {
01651       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
01652       return -1;
01653    }
01654 
01655    for (i= 0;i<9;i++) {
01656       dtable[i]= 'A'+i;
01657       dtable[i+9]= 'J'+i;
01658       dtable[26+i]= 'a'+i;
01659       dtable[26+i+9]= 'j'+i;
01660    }
01661    for (i= 0;i<8;i++) {
01662       dtable[i+18]= 'S'+i;
01663       dtable[26+i+18]= 's'+i;
01664    }
01665    for (i= 0;i<10;i++) {
01666       dtable[52+i]= '0'+i;
01667    }
01668    dtable[62]= '+';
01669    dtable[63]= '/';
01670 
01671    while (!hiteof){
01672       unsigned char igroup[3],ogroup[4];
01673       int c,n;
01674 
01675       igroup[0]= igroup[1]= igroup[2]= 0;
01676 
01677       for (n= 0;n<3;n++) {
01678          if ((c = inchar(&bio, fi)) == EOF) {
01679             hiteof= 1;
01680             break;
01681          }
01682 
01683          igroup[n]= (unsigned char)c;
01684       }
01685 
01686       if (n> 0) {
01687          ogroup[0]= dtable[igroup[0]>>2];
01688          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
01689          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
01690          ogroup[3]= dtable[igroup[2]&0x3F];
01691 
01692          if (n<3) {
01693             ogroup[3]= '=';
01694 
01695             if (n<2)
01696                ogroup[2]= '=';
01697          }
01698 
01699          for (i= 0;i<4;i++)
01700             ochar(&bio, ogroup[i], so);
01701       }
01702    }
01703 
01704    fclose(fi);
01705    
01706    if (fputs(eol,so)==EOF)
01707       return 0;
01708 
01709    return 1;
01710 }

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

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

00655 {
00656    int res;
00657    if (!ast_strlen_zero(vmu->uniqueid)) {
00658       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00659       if (res > 0) {
00660          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00661          res = 0;
00662       } else if (!res) {
00663          res = -1;
00664       }
00665       return res;
00666    }
00667    return -1;
00668 }

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

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

04907 {
04908    int x = 0;
04909 #ifndef IMAP_STORAGE
04910    int res = 0, nummsg;
04911 #endif
04912 
04913    if (vms->lastmsg <= -1)
04914       goto done;
04915 
04916    vms->curmsg = -1; 
04917 #ifndef IMAP_STORAGE
04918    /* Get the deleted messages fixed */ 
04919    if (vm_lock_path(vms->curdir))
04920       return ERROR_LOCK_PATH;
04921     
04922    for (x = 0; x < vmu->maxmsg; x++) { 
04923       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
04924          /* Save this message.  It's not in INBOX or hasn't been heard */ 
04925          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
04926          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
04927             break;
04928          vms->curmsg++; 
04929          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
04930          if (strcmp(vms->fn, vms->fn2)) { 
04931             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
04932          } 
04933       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
04934          /* Move to old folder before deleting */ 
04935          res = save_to_folder(vmu, vms, x, 1);
04936          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
04937             /* If save failed do not delete the message */
04938             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
04939             vms->deleted[x] = 0;
04940             vms->heard[x] = 0;
04941             --x;
04942          } 
04943       } 
04944    } 
04945 
04946    /* Delete ALL remaining messages */
04947    nummsg = x - 1;
04948    for (x = vms->curmsg + 1; x <= nummsg; x++) {
04949       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
04950       if (EXISTS(vms->curdir, x, vms->fn, NULL))
04951          DELETE(vms->curdir, x, vms->fn);
04952    }
04953    ast_unlock_path(vms->curdir);
04954 #else
04955    if (vms->deleted) {
04956       for (x=0;x < vmu->maxmsg;x++) { 
04957          if (vms->deleted[x]) { 
04958             if (option_debug > 2)
04959                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
04960             IMAP_DELETE(vms->curdir, x, vms->fn, vms);
04961          }
04962       }
04963    }
04964 #endif
04965 
04966 done:
04967    if (vms->deleted)
04968       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
04969    if (vms->heard)
04970       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
04971 
04972    return 0;
04973 }

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

Definition at line 7320 of file app_voicemail.c.

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

07321 {
07322    int which = 0;
07323    int wordlen;
07324    struct ast_vm_user *vmu;
07325    const char *context = "";
07326 
07327    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
07328    if (pos > 4)
07329       return NULL;
07330    if (pos == 3)
07331       return (state == 0) ? ast_strdup("for") : NULL;
07332    wordlen = strlen(word);
07333    AST_LIST_TRAVERSE(&users, vmu, list) {
07334       if (!strncasecmp(word, vmu->context, wordlen)) {
07335          if (context && strcmp(context, vmu->context) && ++which > state)
07336             return ast_strdup(vmu->context);
07337          /* ignore repeated contexts ? */
07338          context = vmu->context;
07339       }
07340    }
07341    return NULL;
07342 }

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

Definition at line 1518 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

01519 {
01520    int ifd;
01521    int ofd;
01522    int res;
01523    int len;
01524    char buf[4096];
01525 
01526 #ifdef HARDLINK_WHEN_POSSIBLE
01527    /* Hard link if possible; saves disk space & is faster */
01528    if (link(infile, outfile)) {
01529 #endif
01530       if ((ifd = open(infile, O_RDONLY)) < 0) {
01531          ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
01532          return -1;
01533       }
01534       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
01535          ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
01536          close(ifd);
01537          return -1;
01538       }
01539       do {
01540          len = read(ifd, buf, sizeof(buf));
01541          if (len < 0) {
01542             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
01543             close(ifd);
01544             close(ofd);
01545             unlink(outfile);
01546          }
01547          if (len) {
01548             res = write(ofd, buf, len);
01549             if (errno == ENOMEM || errno == ENOSPC || res != len) {
01550                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
01551                close(ifd);
01552                close(ofd);
01553                unlink(outfile);
01554             }
01555          }
01556       } while (len);
01557       close(ifd);
01558       close(ofd);
01559       return 0;
01560 #ifdef HARDLINK_WHEN_POSSIBLE
01561    } else {
01562       /* Hard link succeeded */
01563       return 0;
01564    }
01565 #endif
01566 }

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

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

Referenced by forward_message(), and leave_voicemail().

02626 {
02627    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
02628    const char *frombox = mbox(imbox);
02629    int recipmsgnum;
02630 
02631    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
02632 
02633    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
02634    
02635    if (!dir)
02636       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
02637    else
02638       ast_copy_string(fromdir, dir, sizeof(fromdir));
02639 
02640    make_file(frompath, sizeof(frompath), fromdir, msgnum);
02641 
02642    if (vm_lock_path(todir))
02643       return ERROR_LOCK_PATH;
02644 
02645    recipmsgnum = 0;
02646    do {
02647       make_file(topath, sizeof(topath), todir, recipmsgnum);
02648       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
02649          break;
02650       recipmsgnum++;
02651    } while (recipmsgnum < recip->maxmsg);
02652    if (recipmsgnum < recip->maxmsg) {
02653       COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
02654    } else {
02655       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
02656    }
02657    ast_unlock_path(todir);
02658    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
02659    
02660    return 0;
02661 }

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

Definition at line 1568 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by forward_message().

01569 {
01570    char frompath2[PATH_MAX], topath2[PATH_MAX];
01571    ast_filecopy(frompath, topath, NULL);
01572    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
01573    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
01574    copy(frompath2, topath2);
01575 }

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

Definition at line 1460 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

01461 {
01462    /* Find all .txt files - even if they are not in sequence from 0000 */
01463 
01464    int vmcount = 0;
01465    DIR *vmdir = NULL;
01466    struct dirent *vment = NULL;
01467 
01468    if (vm_lock_path(dir))
01469       return ERROR_LOCK_PATH;
01470 
01471    if ((vmdir = opendir(dir))) {
01472       while ((vment = readdir(vmdir))) {
01473          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
01474             vmcount++;
01475       }
01476       closedir(vmdir);
01477    }
01478    ast_unlock_path(dir);
01479    
01480    return vmcount;
01481 }

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

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

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

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

07963 {
07964    int cmd = 0;
07965    char destination[80] = "";
07966    int retries = 0;
07967 
07968    if (!num) {
07969       if (option_verbose > 2)
07970          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
07971       while (retries < 3 && cmd != 't') {
07972          destination[1] = '\0';
07973          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
07974          if (!cmd)
07975             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
07976          if (!cmd)
07977             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
07978          if (!cmd) {
07979             cmd = ast_waitfordigit(chan, 6000);
07980             if (cmd)
07981                destination[0] = cmd;
07982          }
07983          if (!cmd) {
07984             retries++;
07985          } else {
07986 
07987             if (cmd < 0)
07988                return 0;
07989             if (cmd == '*') {
07990                if (option_verbose > 2)
07991                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
07992                return 0;
07993             }
07994             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
07995                retries++;
07996             else
07997                cmd = 't';
07998          }
07999       }
08000       if (retries >= 3) {
08001          return 0;
08002       }
08003       
08004    } else {
08005       if (option_verbose > 2)
08006          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08007       ast_copy_string(destination, num, sizeof(destination));
08008    }
08009 
08010    if (!ast_strlen_zero(destination)) {
08011       if (destination[strlen(destination) -1 ] == '*')
08012          return 0; 
08013       if (option_verbose > 2)
08014          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08015       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08016       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08017       chan->priority = 0;
08018       return 9;
08019    }
08020    return 0;
08021 }

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

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

07112 {
07113    struct ast_vm_user *vmu;
07114    AST_LIST_TRAVERSE(&users, vmu, list) {
07115       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox))
07116          break;
07117       if (context && (!strcasecmp(context, vmu->context)) && (!strcasecmp(mbox, vmu->mailbox)))
07118          break;
07119    }
07120    
07121    if (!vmu) {
07122       if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07123          ast_copy_string(vmu->context, context, sizeof(vmu->context));
07124          ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07125          AST_LIST_INSERT_TAIL(&users, vmu, list);
07126       }
07127    }
07128    return vmu;
07129 }

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

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

00746 {
00747    /* This function could be made to generate one from a database, too */
00748    struct ast_vm_user *vmu=NULL, *cur;
00749    AST_LIST_LOCK(&users);
00750 
00751    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00752       context = "default";
00753 
00754    AST_LIST_TRAVERSE(&users, cur, list) {
00755       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00756          break;
00757       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00758          break;
00759    }
00760    if (cur) {
00761       /* Make a copy, so that on a reload, we have no race */
00762       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00763          memcpy(vmu, cur, sizeof(*vmu));
00764          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00765          AST_LIST_NEXT(vmu, list) = NULL;
00766       }
00767    } else
00768       vmu = find_user_realtime(ivm, context, mailbox);
00769    AST_LIST_UNLOCK(&users);
00770    return vmu;
00771 }

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

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

00717 {
00718    struct ast_variable *var;
00719    struct ast_vm_user *retval;
00720 
00721    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00722       if (!ivm)
00723          ast_set_flag(retval, VM_ALLOCED);   
00724       else
00725          memset(retval, 0, sizeof(*retval));
00726       if (mailbox) 
00727          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00728       populate_defaults(retval);
00729       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00730          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00731       else
00732          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00733       if (var) {
00734          apply_options_full(retval, var);
00735          ast_variables_destroy(var);
00736       } else { 
00737          if (!ivm) 
00738             free(retval);
00739          retval = NULL;
00740       }  
00741    } 
00742    return retval;
00743 }

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

References app, ast_clear_flag, AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), copy_plain_file(), create_dirpath(), vm_state::curdir, vm_state::curmsg, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, leave_voicemail(), LOG_DEBUG, LOG_ERROR, ast_vm_user::mailbox, make_file(), option_debug, 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(), VM_SPOOL_DIR, and vmfmts.

Referenced by vm_execmain().

03998 {
03999 #ifdef IMAP_STORAGE
04000    BODY *body;
04001    char *header_content;
04002    char *temp;
04003    char todir[256];
04004    int todircount=0;
04005    struct vm_state *dstvms;
04006 #endif
04007    char username[70]="";
04008    int res = 0, cmd = 0;
04009    struct ast_vm_user *receiver = NULL, *vmtmp;
04010    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
04011    char *stringp;
04012    const char *s;
04013    int saved_messages = 0, found = 0;
04014    int valid_extensions = 0;
04015    char *dir;
04016    int curmsg;
04017 
04018    if (vms == NULL) return -1;
04019    dir = vms->curdir;
04020    curmsg = vms->curmsg;
04021    
04022    while (!res && !valid_extensions) {
04023       int use_directory = 0;
04024       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
04025          int done = 0;
04026          int retries = 0;
04027          cmd=0;
04028          while ((cmd >= 0) && !done ){
04029             if (cmd)
04030                retries = 0;
04031             switch (cmd) {
04032             case '1': 
04033                use_directory = 0;
04034                done = 1;
04035                break;
04036             case '2': 
04037                use_directory = 1;
04038                done=1;
04039                break;
04040             case '*': 
04041                cmd = 't';
04042                done = 1;
04043                break;
04044             default: 
04045                /* Press 1 to enter an extension press 2 to use the directory */
04046                cmd = ast_play_and_wait(chan,"vm-forward");
04047                if (!cmd)
04048                   cmd = ast_waitfordigit(chan,3000);
04049                if (!cmd)
04050                   retries++;
04051                if (retries > 3)
04052                {
04053                   cmd = 't';
04054                   done = 1;
04055                }
04056                
04057             }
04058          }
04059          if (cmd < 0 || cmd == 't')
04060             break;
04061       }
04062       
04063       if (use_directory) {
04064          /* use app_directory */
04065          
04066          char old_context[sizeof(chan->context)];
04067          char old_exten[sizeof(chan->exten)];
04068          int old_priority;
04069          struct ast_app* app;
04070 
04071          
04072          app = pbx_findapp("Directory");
04073          if (app) {
04074             char vmcontext[256];
04075             /* make backup copies */
04076             memcpy(old_context, chan->context, sizeof(chan->context));
04077             memcpy(old_exten, chan->exten, sizeof(chan->exten));
04078             old_priority = chan->priority;
04079             
04080             /* call the the Directory, changes the channel */
04081             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
04082             res = pbx_exec(chan, app, vmcontext);
04083             
04084             ast_copy_string(username, chan->exten, sizeof(username));
04085             
04086             /* restore the old context, exten, and priority */
04087             memcpy(chan->context, old_context, sizeof(chan->context));
04088             memcpy(chan->exten, old_exten, sizeof(chan->exten));
04089             chan->priority = old_priority;
04090             
04091          } else {
04092             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
04093             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
04094          }
04095       } else {
04096          /* Ask for an extension */
04097          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
04098          if (res)
04099             break;
04100          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
04101             break;
04102       }
04103       
04104       /* start all over if no username */
04105       if (ast_strlen_zero(username))
04106          continue;
04107       stringp = username;
04108       s = strsep(&stringp, "*");
04109       /* start optimistic */
04110       valid_extensions = 1;
04111       while (s) {
04112          /* 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 */
04113          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
04114             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
04115             found++;
04116          } else {
04117             valid_extensions = 0;
04118             break;
04119          }
04120          s = strsep(&stringp, "*");
04121       }
04122       /* break from the loop of reading the extensions */
04123       if (valid_extensions)
04124          break;
04125       /* "I am sorry, that's not a valid extension.  Please try again." */
04126       res = ast_play_and_wait(chan, "pbx-invalid");
04127    }
04128    /* check if we're clear to proceed */
04129    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
04130       return res;
04131    if (flag==1) {
04132       struct leave_vm_options leave_options;
04133       char mailbox[AST_MAX_EXTENSION * 2 + 2];
04134       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
04135       if (context)
04136          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
04137       else
04138          ast_copy_string(mailbox, username, sizeof(mailbox));
04139 
04140       /* Send VoiceMail */
04141       memset(&leave_options, 0, sizeof(leave_options));
04142       leave_options.record_gain = record_gain;
04143       cmd = leave_voicemail(chan, mailbox, &leave_options);
04144    } else {
04145       /* Forward VoiceMail */
04146       long duration = 0;
04147       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
04148       struct vm_state vmstmp;
04149 
04150       memcpy(&vmstmp, vms, sizeof(vmstmp));
04151 
04152       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
04153       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
04154       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
04155 
04156       RETRIEVE(dir, curmsg);
04157 
04158       /* Alter a surrogate file, only */
04159       copy_plain_file(origmsgfile, msgfile);
04160 
04161       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
04162       if (!cmd) {
04163          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
04164 #ifdef IMAP_STORAGE
04165             char *myserveremail;
04166             int attach_user_voicemail;
04167             /* Need to get message content */
04168             if (option_debug > 2)
04169                ast_log (LOG_DEBUG, "Before mail_fetchheaders, curmsg is: %d, imap messages is %lu\n", vms->curmsg, vms->msgArray[vms->curmsg]);
04170             if (vms->msgArray[vms->curmsg] == 0) {
04171                ast_log (LOG_WARNING,"Trying to access unknown message\n");
04172                return -1;
04173             }
04174 
04175             /* This will only work for new messages... */
04176             header_content = mail_fetchheader (vms->mailstream, vms->msgArray[vms->curmsg]);
04177             /* empty string means no valid header */
04178             if (ast_strlen_zero(header_content)) {
04179                ast_log (LOG_ERROR,"Could not fetch header for message number %ld\n",vms->msgArray[vms->curmsg]);
04180                return -1;
04181             }
04182             /* Get header info needed by sendmail */
04183             temp = get_header_by_tag(header_content, "X-Asterisk-VM-Duration:");
04184             if (temp)
04185                duration = atoi(temp);
04186             else
04187                duration = 0;
04188 
04189             /* Attach only the first format */
04190             fmt = ast_strdupa(fmt);
04191             if (fmt) {
04192                stringp = fmt;
04193                strsep(&stringp, "|");
04194             } else {
04195                ast_log (LOG_ERROR,"audio format not set. Default to WAV\n");
04196                fmt = "WAV";
04197             }
04198             if (!strcasecmp(fmt, "wav49"))
04199                fmt = "WAV";
04200             if (option_debug > 2)
04201                ast_log (LOG_DEBUG,"**** format set to %s, vmfmts set to %s\n",fmt,vmfmts);
04202             /* ast_copy_string(fmt, vmfmts, sizeof(fmt));*/
04203             /* if (!ast_strlen_zero(fmt)) { */
04204             snprintf(todir, sizeof(todir), "%s%s/%s/tmp", VM_SPOOL_DIR, vmtmp->context, vmtmp->mailbox);
04205             make_gsm_file(vms->fn, sizeof(vms->fn), vms->imapuser, todir, vms->curmsg);
04206             if (option_debug > 2)
04207                ast_log (LOG_DEBUG,"Before mail_fetchstructure, message number is %ld, filename is:%s\n",vms->msgArray[vms->curmsg], vms->fn);
04208             /*mail_fetchstructure (mailstream, vmArray[0], &body); */
04209             mail_fetchstructure (vms->mailstream, vms->msgArray[vms->curmsg], &body);
04210             save_body(body,vms,"3","gsm");
04211             /* should not assume "fmt" here! */
04212             save_body(body,vms,"2",fmt);
04213 
04214             /* get destination mailbox */
04215             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox,0);
04216             if (dstvms) {
04217                init_mailstream(dstvms, 0);
04218                if (!dstvms->mailstream) {
04219                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
04220                } else {
04221                   STORE(todir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
04222                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
04223                }
04224             } else {
04225                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
04226             }
04227 
04228             myserveremail = serveremail;
04229             if (!ast_strlen_zero(vmtmp->serveremail))
04230                myserveremail = vmtmp->serveremail;
04231             attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
04232             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
04233             /* NULL category for IMAP storage */
04234             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);
04235 #else
04236             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
04237 #endif
04238             saved_messages++;
04239             AST_LIST_REMOVE_CURRENT(&extensions, list);
04240             free_user(vmtmp);
04241             if (res)
04242                break;
04243          }
04244          AST_LIST_TRAVERSE_SAFE_END;
04245          if (saved_messages > 0) {
04246             /* give confirmation that the message was saved */
04247             /* commented out since we can't forward batches yet
04248             if (saved_messages == 1)
04249                res = ast_play_and_wait(chan, "vm-message");
04250             else
04251                res = ast_play_and_wait(chan, "vm-messages");
04252             if (!res)
04253                res = ast_play_and_wait(chan, "vm-saved"); */
04254             res = ast_play_and_wait(chan, "vm-msgsaved");
04255          }  
04256       }
04257 
04258       /* Remove surrogate file */
04259       vm_delete(msgfile);
04260    }
04261 
04262    /* If anything failed above, we still have this list to free */
04263    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
04264       free_user(vmtmp);
04265    return res ? res : cmd;
04266 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 2131 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

02132 {
02133    if (ast_test_flag(vmu, VM_ALLOCED))
02134       free(vmu);
02135 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 2137 of file app_voicemail.c.

References free.

02138 {
02139    free(z);
02140 }

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

Definition at line 2064 of file app_voicemail.c.

References ast_localtime(), and t.

Referenced by leave_voicemail(), and tds_log().

02065 {
02066    struct tm tm;
02067    time_t t;
02068 
02069    time(&t);
02070 
02071    ast_localtime(&t, &tm, NULL);
02072 
02073    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
02074 }

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

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

03792 {
03793    int x;
03794    int d;
03795    char fn[PATH_MAX];
03796    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
03797    if (d)
03798       return d;
03799    for (x = start; x< 5; x++) {  /* For all folders */
03800       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
03801          return d;
03802       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
03803       if (d)
03804          return d;
03805       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
03806       d = vm_play_folder_name(chan, fn);
03807       if (d)
03808          return d;
03809       d = ast_waitfordigit(chan, 500);
03810       if (d)
03811          return d;
03812    }
03813    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
03814    if (d)
03815       return d;
03816    d = ast_waitfordigit(chan, 4000);
03817    return d;
03818 }

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

Definition at line 3820 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

03821 {
03822    int res = 0;
03823    res = ast_play_and_wait(chan, fn);  /* Folder name */
03824    while (((res < '0') || (res > '9')) &&
03825          (res != '#') && (res >= 0)) {
03826       res = get_folder(chan, 0);
03827    }
03828    return res;
03829 }

static int get_lastdigits ( int  num  )  [static]

Definition at line 5702 of file app_voicemail.c.

Referenced by vm_intro_ru(), and vm_intro_ua().

05703 {
05704    num %= 100;
05705    return (num < 20) ? num : num % 10;
05706 }

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

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

07251 {
07252    struct ast_vm_user *vmu;
07253    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
07254 
07255    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
07256    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
07257 
07258    AST_LIST_LOCK(&users);
07259    if (!AST_LIST_EMPTY(&users)) {
07260       if (argc == 3)
07261          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07262       else {
07263          int count = 0;
07264          AST_LIST_TRAVERSE(&users, vmu, list) {
07265             if (!strcmp(argv[4],vmu->context))
07266                count++;
07267          }
07268          if (count) {
07269             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
07270          } else {
07271             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
07272             AST_LIST_UNLOCK(&users);
07273             return RESULT_FAILURE;
07274          }
07275       }
07276       AST_LIST_TRAVERSE(&users, vmu, list) {
07277          int newmsgs = 0, oldmsgs = 0;
07278          char count[12], tmp[256] = "";
07279 
07280          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
07281             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
07282             inboxcount(tmp, &newmsgs, &oldmsgs);
07283             snprintf(count,sizeof(count),"%d",newmsgs);
07284             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
07285          }
07286       }
07287    } else {
07288       ast_cli(fd, "There are no voicemail users currently defined\n");
07289       AST_LIST_UNLOCK(&users);
07290       return RESULT_FAILURE;
07291    }
07292    AST_LIST_UNLOCK(&users);
07293    return RESULT_SUCCESS;
07294 }

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

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

07297 {
07298    struct vm_zone *zone;
07299    char *output_format = "%-15s %-20s %-45s\n";
07300    int res = RESULT_SUCCESS;
07301 
07302    if (argc != 3)
07303       return RESULT_SHOWUSAGE;
07304 
07305    AST_LIST_LOCK(&zones);
07306    if (!AST_LIST_EMPTY(&zones)) {
07307       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
07308       AST_LIST_TRAVERSE(&zones, zone, list) {
07309          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
07310       }
07311    } else {
07312       ast_cli(fd, "There are no voicemail zones currently defined\n");
07313       res = RESULT_FAILURE;
07314    }
07315    AST_LIST_UNLOCK(&zones);
07316 
07317    return res;
07318 }

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

Definition at line 2701 of file app_voicemail.c.

References __has_voicemail(), and strsep().

02702 {
02703    char tmp[256], *tmp2 = tmp, *mbox, *context;
02704    ast_copy_string(tmp, mailbox, sizeof(tmp));
02705    while ((mbox = strsep(&tmp2, ","))) {
02706       if ((context = strchr(mbox, '@')))
02707          *context++ = '\0';
02708       else
02709          context = "default";
02710       if (__has_voicemail(context, mbox, folder, 1))
02711          return 1;
02712    }
02713    return 0;
02714 }

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

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

02718 {
02719    char tmp[256];
02720    char *context;
02721 
02722    if (newmsgs)
02723       *newmsgs = 0;
02724    if (oldmsgs)
02725       *oldmsgs = 0;
02726    /* If no mailbox, return immediately */
02727    if (ast_strlen_zero(mailbox))
02728       return 0;
02729    if (strchr(mailbox, ',')) {
02730       int tmpnew, tmpold;
02731       char *mb, *cur;
02732 
02733       ast_copy_string(tmp, mailbox, sizeof(tmp));
02734       mb = tmp;
02735       while ((cur = strsep(&mb, ", "))) {
02736          if (!ast_strlen_zero(cur)) {
02737             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
02738                return -1;
02739             else {
02740                if (newmsgs)
02741                   *newmsgs += tmpnew; 
02742                if (oldmsgs)
02743                   *oldmsgs += tmpold;
02744             }
02745          }
02746       }
02747       return 0;
02748    }
02749    ast_copy_string(tmp, mailbox, sizeof(tmp));
02750    context = strchr(tmp, '@');
02751    if (context) {
02752       *context = '\0';
02753       context++;
02754    } else
02755       context = "default";
02756    if (newmsgs)
02757       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
02758    if (oldmsgs)
02759       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
02760    return 0;
02761 }

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

Definition at line 1592 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

01593 {
01594    int l;
01595 
01596    if (bio->ateof)
01597       return 0;
01598 
01599    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
01600       if (ferror(fi))
01601          return -1;
01602 
01603       bio->ateof = 1;
01604       return 0;
01605    }
01606 
01607    bio->iolen= l;
01608    bio->iocp= 0;
01609 
01610    return 1;
01611 }

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

Definition at line 1613 of file app_voicemail.c.

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

Referenced by base_encode().

01614 {
01615    if (bio->iocp>=bio->iolen) {
01616       if (!inbuf(bio, fi))
01617          return EOF;
01618    }
01619 
01620    return bio->iobuf[bio->iocp++];
01621 }

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

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

02103 {
02104    int res;
02105    char fn[PATH_MAX];
02106    char dest[PATH_MAX];
02107 
02108    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
02109 
02110    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
02111       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
02112       return -1;
02113    }
02114 
02115    res = play_greeting(chan, vmu, fn, ecodes);
02116    if (res == -2) {
02117       /* File did not exist */
02118       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
02119       if (res)
02120          return res;
02121       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
02122    }
02123 
02124    if (res)
02125       return res;
02126 
02127    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
02128    return res;
02129 }

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

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

01499 {
01500    int x;
01501    char fn[PATH_MAX];
01502 
01503    if (vm_lock_path(dir))
01504       return ERROR_LOCK_PATH;
01505 
01506    for (x = 0; x < vmu->maxmsg; x++) {
01507       make_file(fn, sizeof(fn), dir, x);
01508       if (ast_fileexists(fn, NULL, NULL) < 1)
01509          break;
01510    }
01511    ast_unlock_path(dir);
01512 
01513    return x - 1;
01514 }

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

Definition at line 2812 of file app_voicemail.c.

References ast_callerid_merge(), ast_calloc, ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_goto_if_exists(), ast_log(), ast_opt_priority_jumping, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), count_messages(), create_dirpath(), 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().

02813 {
02814 #ifdef IMAP_STORAGE
02815    int newmsgs, oldmsgs;
02816    struct vm_state *vms = NULL;
02817 #endif
02818    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
02819    char callerid[256];
02820    FILE *txt;
02821    char date[256];
02822    int txtdes;
02823    int res = 0;
02824    int msgnum;
02825    int duration = 0;
02826    int ausemacro = 0;
02827    int ousemacro = 0;
02828    int ouseexten = 0;
02829    char dir[PATH_MAX], tmpdir[PATH_MAX];
02830    char dest[PATH_MAX];
02831    char fn[PATH_MAX];
02832    char prefile[PATH_MAX] = "";
02833    char tempfile[PATH_MAX] = "";
02834    char ext_context[256] = "";
02835    char fmt[80];
02836    char *context;
02837    char ecodes[16] = "#";
02838    char tmp[1024] = "", *tmpptr;
02839    struct ast_vm_user *vmu;
02840    struct ast_vm_user svm;
02841    const char *category = NULL;
02842 
02843    ast_copy_string(tmp, ext, sizeof(tmp));
02844    ext = tmp;
02845    context = strchr(tmp, '@');
02846    if (context) {
02847       *context++ = '\0';
02848       tmpptr = strchr(context, '&');
02849    } else {
02850       tmpptr = strchr(ext, '&');
02851    }
02852 
02853    if (tmpptr)
02854       *tmpptr++ = '\0';
02855 
02856    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
02857 
02858    if (option_debug > 2)
02859       ast_log(LOG_DEBUG, "Before find_user\n");
02860    if (!(vmu = find_user(&svm, context, ext))) {
02861       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
02862       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
02863          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
02864       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02865       return res;
02866    }
02867    /* Setup pre-file if appropriate */
02868    if (strcmp(vmu->context, "default"))
02869       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
02870    else
02871       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
02872    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
02873       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
02874       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
02875    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
02876       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
02877       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
02878    }
02879    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
02880    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
02881       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
02882       return -1;
02883    }
02884    RETRIEVE(tempfile, -1);
02885    if (ast_fileexists(tempfile, NULL, NULL) > 0)
02886       ast_copy_string(prefile, tempfile, sizeof(prefile));
02887    DISPOSE(tempfile, -1);
02888    /* It's easier just to try to make it than to check for its existence */
02889    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
02890    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
02891 
02892    /* Check current or macro-calling context for special extensions */
02893    if (ast_test_flag(vmu, VM_OPERATOR)) {
02894       if (!ast_strlen_zero(vmu->exit)) {
02895          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
02896             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02897             ouseexten = 1;
02898          }
02899       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
02900          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02901          ouseexten = 1;
02902       }
02903       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
02904       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
02905       ousemacro = 1;
02906       }
02907    }
02908 
02909    if (!ast_strlen_zero(vmu->exit)) {
02910       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
02911          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02912    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
02913       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02914    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
02915       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
02916       ausemacro = 1;
02917    }
02918 
02919    /* Play the beginning intro if desired */
02920    if (!ast_strlen_zero(prefile)) {
02921       res = play_greeting(chan, vmu, prefile, ecodes);
02922       if (res == -2) {
02923          /* The file did not exist */
02924          if (option_debug)
02925             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
02926          res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
02927       }
02928       if (res < 0) {
02929          if (option_debug)
02930             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
02931          free_user(vmu);
02932          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02933          return -1;
02934       }
02935    }
02936    if (res == '#') {
02937       /* On a '#' we skip the instructions */
02938       ast_set_flag(options, OPT_SILENT);
02939       res = 0;
02940    }
02941    if (!res && !ast_test_flag(options, OPT_SILENT)) {
02942       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
02943       if (res == '#') {
02944          ast_set_flag(options, OPT_SILENT);
02945          res = 0;
02946       }
02947    }
02948    if (res > 0)
02949       ast_stopstream(chan);
02950    /* Check for a '*' here in case the caller wants to escape from voicemail to something
02951     other than the operator -- an automated attendant or mailbox login for example */
02952    if (res == '*') {
02953       chan->exten[0] = 'a';
02954       chan->exten[1] = '\0';
02955       if (!ast_strlen_zero(vmu->exit)) {
02956          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02957       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
02958          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02959       }
02960       chan->priority = 0;
02961       free_user(vmu);
02962       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02963       return 0;
02964    }
02965 
02966    /* Check for a '0' here */
02967    if (res == '0') {
02968    transfer:
02969       if (ouseexten || ousemacro) {
02970          chan->exten[0] = 'o';
02971          chan->exten[1] = '\0';
02972          if (!ast_strlen_zero(vmu->exit)) {
02973             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
02974          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
02975             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
02976          }
02977          ast_play_and_wait(chan, "transfer");
02978          chan->priority = 0;
02979          free_user(vmu);
02980          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
02981       }
02982       return 0;
02983    }
02984    if (res < 0) {
02985       free_user(vmu);
02986       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
02987       return -1;
02988    }
02989    /* The meat of recording the message...  All the announcements and beeps have been played*/
02990    ast_copy_string(fmt, vmfmts, sizeof(fmt));
02991    if (!ast_strlen_zero(fmt)) {
02992       msgnum = 0;
02993 
02994 #ifdef IMAP_STORAGE
02995       /* Is ext a mailbox? */
02996       /* must open stream for this user to get info! */
02997       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
02998       if (res < 0) {
02999          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
03000          return -1;
03001       }
03002       if (!(vms = get_vm_state_by_mailbox(ext,0))) {
03003       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
03004        * rarely be used*/
03005          if (!(vms = ast_calloc(1, sizeof(*vms)))) {
03006             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
03007             return -1;
03008          }
03009          ast_copy_string(vms->imapuser, vmu->imapuser, sizeof(vms->imapuser));
03010          ast_copy_string(vms->username, ext, sizeof(vms->username));
03011          vms->mailstream = NIL;
03012          if (option_debug > 2)
03013             ast_log(LOG_DEBUG, "Copied %s to %s\n", vmu->imapuser, vms->imapuser);
03014          vms->updated=1;
03015          ast_copy_string(vms->curbox, mbox(0), sizeof(vms->curbox));
03016          init_vm_state(vms);
03017          vmstate_insert(vms);
03018          vms = get_vm_state_by_mailbox(ext,0);
03019       }
03020       vms->newmessages++;
03021       /* here is a big difference! We add one to it later */
03022       msgnum = newmsgs + oldmsgs;
03023       if (option_debug > 2)
03024          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
03025       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
03026       /* set variable for compatibility */
03027       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
03028 
03029       /* Check if mailbox is full */
03030       check_quota(vms, imapfolder);
03031       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
03032          if (option_debug)
03033             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
03034          ast_play_and_wait(chan, "vm-mailboxfull");
03035          return -1;
03036       }
03037       if (option_debug > 2)
03038          ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
03039       if (msgnum >= vmu->maxmsg) {
03040          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03041          if (!res)
03042             res = ast_waitstream(chan, "");
03043          ast_log(LOG_WARNING, "No more messages possible\n");
03044          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03045          goto leave_vm_out;
03046       }
03047 
03048       /* Check if we have exceeded maxmsg */
03049       if (msgnum >= vmu->maxmsg) {
03050          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
03051          ast_play_and_wait(chan, "vm-mailboxfull");
03052          return -1;
03053       }
03054       /* here is a big difference! We add one to it later */
03055       if (option_debug > 2)
03056          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
03057 #else
03058       if (count_messages(vmu, dir) >= vmu->maxmsg) {
03059          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03060          if (!res)
03061             res = ast_waitstream(chan, "");
03062          ast_log(LOG_WARNING, "No more messages possible\n");
03063          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03064          goto leave_vm_out;
03065       }
03066 
03067 #endif
03068       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
03069       txtdes = mkstemp(tmptxtfile);
03070       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
03071       if (txtdes < 0) {
03072          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
03073          if (!res)
03074             res = ast_waitstream(chan, "");
03075          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
03076          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03077          goto leave_vm_out;
03078       }
03079 
03080       /* Now play the beep once we have the message number for our next message. */
03081       if (res >= 0) {
03082          /* Unless we're *really* silent, try to send the beep */
03083          res = ast_stream_and_wait(chan, "beep", chan->language, "");
03084       }
03085             
03086       /* Store information */
03087       txt = fdopen(txtdes, "w+");
03088       if (txt) {
03089          get_date(date, sizeof(date));
03090          fprintf(txt, 
03091             ";\n"
03092             "; Message Information file\n"
03093             ";\n"
03094             "[message]\n"
03095             "origmailbox=%s\n"
03096             "context=%s\n"
03097             "macrocontext=%s\n"
03098             "exten=%s\n"
03099             "priority=%d\n"
03100             "callerchan=%s\n"
03101             "callerid=%s\n"
03102             "origdate=%s\n"
03103             "origtime=%ld\n"
03104             "category=%s\n",
03105             ext,
03106             chan->context,
03107             chan->macrocontext, 
03108             chan->exten,
03109             chan->priority,
03110             chan->name,
03111             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
03112             date, (long)time(NULL),
03113             category ? category : ""); 
03114       } else
03115          ast_log(LOG_WARNING, "Error opening text file for output\n");
03116 #ifdef IMAP_STORAGE
03117       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
03118 #else
03119       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, NULL);
03120 #endif
03121 
03122       if (txt) {
03123          if (duration < vmminmessage) {
03124             fclose(txt);
03125             if (option_verbose > 2) 
03126                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
03127             ast_filedelete(tmptxtfile, NULL);
03128             unlink(tmptxtfile);
03129          } else {
03130             fprintf(txt, "duration=%d\n", duration);
03131             fclose(txt);
03132             if (vm_lock_path(dir)) {
03133                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
03134                /* Delete files */
03135                ast_filedelete(tmptxtfile, NULL);
03136                unlink(tmptxtfile);
03137             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
03138                if (option_debug) 
03139                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
03140                unlink(tmptxtfile);
03141                ast_unlock_path(dir);
03142             } else {
03143                for (;;) {
03144                   make_file(fn, sizeof(fn), dir, msgnum);
03145                   if (!EXISTS(dir, msgnum, fn, NULL))
03146                      break;
03147                   msgnum++;
03148                }
03149 
03150                /* assign a variable with the name of the voicemail file */ 
03151 #ifndef IMAP_STORAGE
03152                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
03153 #else
03154                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
03155 #endif
03156 
03157                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
03158                ast_filerename(tmptxtfile, fn, NULL);
03159                rename(tmptxtfile, txtfile);
03160 
03161                ast_unlock_path(dir);
03162                /* We must store the file first, before copying the message, because
03163                 * ODBC storage does the entire copy with SQL.
03164                 */
03165                if (ast_fileexists(fn, NULL, NULL) > 0) {
03166                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
03167                }
03168 
03169                /* Are there to be more recipients of this message? */
03170                while (tmpptr) {
03171                   struct ast_vm_user recipu, *recip;
03172                   char *exten, *context;
03173                
03174                   exten = strsep(&tmpptr, "&");
03175                   context = strchr(exten, '@');
03176                   if (context) {
03177                      *context = '\0';
03178                      context++;
03179                   }
03180                   if ((recip = find_user(&recipu, context, exten))) {
03181                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
03182                      free_user(recip);
03183                   }
03184                }
03185                /* Notification and disposal needs to happen after the copy, though. */
03186                if (ast_fileexists(fn, NULL, NULL)) {
03187                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03188                   DISPOSE(dir, msgnum);
03189                }
03190             }
03191          }
03192       }
03193       if (res == '0') {
03194          goto transfer;
03195       } else if (res > 0)
03196          res = 0;
03197 
03198       if (duration < vmminmessage)
03199          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
03200          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
03201       else
03202          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
03203    } else
03204       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
03205 leave_vm_out:
03206    free_user(vmu);
03207    
03208    return res;
03209 }

static int load_config ( void   )  [static]

Definition at line 7364 of file app_voicemail.c.

References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_config_option(), ast_false(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_malloc, ast_set2_flag, ast_set_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, dialcontext, emailbody, emaildateformat, emailsubject, emailtitle, exitcontext, ext_pass_cmd, externnotify, find_or_create(), free, free_user(), free_zone(), 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_ALLOCED, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxmessage, vmminmessage, VOICEMAIL_CONFIG, and volgain.

07365 {
07366    struct ast_vm_user *cur;
07367    struct vm_zone *zcur;
07368    struct ast_config *cfg, *ucfg;
07369    char *cat;
07370    struct ast_variable *var;
07371    const char *notifystr = NULL;
07372    const char *smdistr = NULL;
07373    const char *astattach;
07374    const char *astsearch;
07375    const char *astsaycid;
07376    const char *send_voicemail;
07377 #ifdef IMAP_STORAGE
07378    const char *imap_server;
07379    const char *imap_port;
07380    const char *imap_flags;
07381    const char *imap_folder;
07382    const char *auth_user;
07383    const char *auth_password;
07384    const char *expunge_on_hangup;
07385 #endif
07386    const char *astcallop;
07387    const char *astreview;
07388    const char *asttempgreetwarn;
07389    const char *astskipcmd;
07390    const char *asthearenv;
07391    const char *astsaydurationinfo;
07392    const char *astsaydurationminfo;
07393    const char *silencestr;
07394    const char *maxmsgstr;
07395    const char *astdirfwd;
07396    const char *thresholdstr;
07397    const char *fmt;
07398    const char *astemail;
07399    const char *ucontext;
07400    const char *astmailcmd = SENDMAIL;
07401    const char *astforcename;
07402    const char *astforcegreet;
07403    const char *s;
07404    char *q,*stringp;
07405    const char *dialoutcxt = NULL;
07406    const char *callbackcxt = NULL;  
07407    const char *exitcxt = NULL;   
07408    const char *extpc;
07409    const char *emaildateformatstr;
07410    const char *volgainstr;
07411    int x;
07412    int tmpadsi[4];
07413 
07414    cfg = ast_config_load(VOICEMAIL_CONFIG);
07415 
07416    AST_LIST_LOCK(&users);
07417    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
07418       ast_set_flag(cur, VM_ALLOCED);
07419       free_user(cur);
07420    }
07421 
07422    AST_LIST_LOCK(&zones);
07423    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 
07424       free_zone(zcur);
07425    AST_LIST_UNLOCK(&zones);
07426 
07427    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
07428 
07429    if (cfg) {
07430       /* General settings */
07431 
07432       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
07433          ucontext = "default";
07434       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
07435       /* Attach voice message to mail message ? */
07436       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
07437          astattach = "yes";
07438       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
07439 
07440       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
07441          astsearch = "no";
07442       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
07443 
07444       volgain = 0.0;
07445       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
07446          sscanf(volgainstr, "%lf", &volgain);
07447 
07448 #ifdef ODBC_STORAGE
07449       strcpy(odbc_database, "asterisk");
07450       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
07451          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
07452       }
07453       strcpy(odbc_table, "voicemessages");
07454       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
07455          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
07456       }
07457 #endif      
07458       /* Mail command */
07459       strcpy(mailcmd, SENDMAIL);
07460       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
07461          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
07462 
07463       maxsilence = 0;
07464       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
07465          maxsilence = atoi(silencestr);
07466          if (maxsilence > 0)
07467             maxsilence *= 1000;
07468       }
07469       
07470       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
07471          maxmsg = MAXMSG;
07472       } else {
07473          maxmsg = atoi(maxmsgstr);
07474          if (maxmsg <= 0) {
07475             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
07476             maxmsg = MAXMSG;
07477          } else if (maxmsg > MAXMSGLIMIT) {
07478             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
07479             maxmsg = MAXMSGLIMIT;
07480          }
07481       }
07482 
07483       /* Load date format config for voicemail mail */
07484       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
07485          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
07486       }
07487 
07488       /* External password changing command */
07489       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
07490          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
07491       }
07492 #ifdef IMAP_STORAGE
07493       /* IMAP server address */
07494       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
07495          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
07496       } else {
07497          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
07498       }
07499       /* IMAP server port */
07500       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
07501          ast_copy_string(imapport, imap_port, sizeof(imapport));
07502       } else {
07503          ast_copy_string(imapport,"143", sizeof(imapport));
07504       }
07505       /* IMAP server flags */
07506       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
07507          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
07508       }
07509       /* IMAP server master username */
07510       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
07511          ast_copy_string(authuser, auth_user, sizeof(authuser));
07512       }
07513       /* IMAP server master password */
07514       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
07515          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
07516       }
07517       /* Expunge on exit */
07518       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
07519          if (ast_false(expunge_on_hangup))
07520             expungeonhangup = 0;
07521          else
07522             expungeonhangup = 1;
07523       } else {
07524          expungeonhangup = 1;
07525       }
07526       /* IMAP voicemail folder */
07527       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
07528          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
07529       } else {
07530          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
07531       }
07532 #endif
07533       /* External voicemail notify application */
07534       
07535       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
07536          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
07537          if (option_debug > 2)
07538             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
07539          if (!strcasecmp(externnotify, "smdi")) {
07540             if (option_debug)
07541                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
07542             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
07543                smdi_iface = ast_smdi_interface_find(smdistr);
07544             } else {
07545                if (option_debug)
07546                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
07547                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
07548             }
07549 
07550             if (!smdi_iface) {
07551                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
07552                externnotify[0] = '\0';
07553             }
07554          }
07555       } else {
07556          externnotify[0] = '\0';
07557       }
07558 
07559       /* Silence treshold */
07560       silencethreshold = 256;
07561       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
07562          silencethreshold = atoi(thresholdstr);
07563       
07564       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
07565          astemail = ASTERISK_USERNAME;
07566       ast_copy_string(serveremail, astemail, sizeof(serveremail));
07567       
07568       vmmaxmessage = 0;
07569       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
07570          if (sscanf(s, "%d", &x) == 1) {
07571             vmmaxmessage = x;
07572          } else {
07573             ast_log(LOG_WARNING, "Invalid max message time length\n");
07574          }
07575       }
07576 
07577       vmminmessage = 0;
07578       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
07579          if (sscanf(s, "%d", &x) == 1) {
07580             vmminmessage = x;
07581             if (maxsilence <= vmminmessage)
07582                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
07583          } else {
07584             ast_log(LOG_WARNING, "Invalid min message time length\n");
07585          }
07586       }
07587       fmt = ast_variable_retrieve(cfg, "general", "format");
07588       if (!fmt)
07589          fmt = "wav";   
07590       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
07591 
07592       skipms = 3000;
07593       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
07594          if (sscanf(s, "%d", &x) == 1) {
07595             maxgreet = x;
07596          } else {
07597             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
07598          }
07599       }
07600 
07601       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
07602          if (sscanf(s, "%d", &x) == 1) {
07603             skipms = x;
07604          } else {
07605             ast_log(LOG_WARNING, "Invalid skipms value\n");
07606          }
07607       }
07608 
07609       maxlogins = 3;
07610       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
07611          if (sscanf(s, "%d", &x) == 1) {
07612             maxlogins = x;
07613          } else {
07614             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
07615          }
07616       }
07617 
07618       /* Force new user to record name ? */
07619       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
07620          astforcename = "no";
07621       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
07622 
07623       /* Force new user to record greetings ? */
07624       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
07625          astforcegreet = "no";
07626       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
07627 
07628       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
07629          if (option_debug > 2)
07630             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
07631          stringp = ast_strdupa(s);
07632          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
07633             if (!ast_strlen_zero(stringp)) {
07634                q = strsep(&stringp,",");
07635                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
07636                   q++;
07637                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
07638                if (option_debug > 2)
07639                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
07640             } else {
07641                cidinternalcontexts[x][0] = '\0';
07642             }
07643          }
07644       }
07645       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
07646          if (option_debug)
07647             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
07648          astreview = "no";
07649       }
07650       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
07651 
07652       /*Temperary greeting reminder */
07653       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
07654          if (option_debug)
07655             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
07656          asttempgreetwarn = "no";
07657       } else {
07658          if (option_debug)
07659             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
07660       }
07661       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
07662 
07663       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
07664          if (option_debug)
07665             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
07666          astcallop = "no";
07667       }
07668       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
07669 
07670       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
07671          if (option_debug)
07672             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
07673          astsaycid = "no";
07674       } 
07675       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
07676 
07677       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
07678          if (option_debug)
07679             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
07680          send_voicemail = "no";
07681       }
07682       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
07683    
07684       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
07685          if (option_debug)
07686             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
07687          asthearenv = "yes";
07688       }
07689       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
07690 
07691       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
07692          if (option_debug)
07693             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
07694          astsaydurationinfo = "yes";
07695       }
07696       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
07697 
07698       saydurationminfo = 2;
07699       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
07700          if (sscanf(astsaydurationminfo, "%d", &x) == 1) {
07701             saydurationminfo = x;
07702          } else {
07703             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
07704          }
07705       }
07706 
07707       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
07708          if (option_debug)
07709             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
07710          astskipcmd = "no";
07711       }
07712       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
07713 
07714       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
07715          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
07716          if (option_debug)
07717             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
07718       } else {
07719          dialcontext[0] = '\0';  
07720       }
07721       
07722       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
07723          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
07724          if (option_debug)
07725             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
07726       } else {
07727          callcontext[0] = '\0';
07728       }
07729 
07730       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
07731          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
07732          if (option_debug)
07733             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
07734       } else {
07735          exitcontext[0] = '\0';
07736       }
07737 
07738       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
07739          astdirfwd = "no";
07740       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
07741       if ((ucfg = ast_config_load("users.conf"))) {   
07742          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
07743             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
07744                continue;
07745             if ((cur = find_or_create(userscontext, cat))) {
07746                populate_defaults(cur);
07747                apply_options_full(cur, ast_variable_browse(ucfg, cat));
07748                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
07749             }
07750          }
07751          ast_config_destroy(ucfg);
07752       }
07753       cat = ast_category_browse(cfg, NULL);
07754       while (cat) {
07755          if (strcasecmp(cat, "general")) {
07756             var = ast_variable_browse(cfg, cat);
07757             if (strcasecmp(cat, "zonemessages")) {
07758                /* Process mailboxes in this context */
07759                while (var) {
07760                   append_mailbox(cat, var->name, var->value);
07761                   var = var->next;
07762                }
07763             } else {
07764                /* Timezones in this context */
07765                while (var) {
07766                   struct vm_zone *z;
07767                   if ((z = ast_malloc(sizeof(*z)))) {
07768                      char *msg_format, *timezone;
07769                      msg_format = ast_strdupa(var->value);
07770                      timezone = strsep(&msg_format, "|");
07771                      if (msg_format) {
07772                         ast_copy_string(z->name, var->name, sizeof(z->name));
07773                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
07774                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
07775                         AST_LIST_LOCK(&zones);
07776                         AST_LIST_INSERT_HEAD(&zones, z, list);
07777                         AST_LIST_UNLOCK(&zones);
07778                      } else {
07779                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
07780                         free(z);
07781                      }
07782                   } else {
07783                      free(z);
07784                      AST_LIST_UNLOCK(&users);
07785                      ast_config_destroy(cfg);
07786                      return -1;
07787                   }
07788                   var = var->next;
07789                }
07790             }
07791          }
07792          cat = ast_category_browse(cfg, cat);
07793       }
07794       memset(fromstring,0,sizeof(fromstring));
07795       memset(pagerfromstring,0,sizeof(pagerfromstring));
07796       memset(emailtitle,0,sizeof(emailtitle));
07797       strcpy(charset, "ISO-8859-1");
07798       if (emailbody) {
07799          free(emailbody);
07800          emailbody = NULL;
07801       }
07802       if (emailsubject) {
07803          free(emailsubject);
07804          emailsubject = NULL;
07805       }
07806       if (pagerbody) {
07807          free(pagerbody);
07808          pagerbody = NULL;
07809       }
07810       if (pagersubject) {
07811          free(pagersubject);
07812          pagersubject = NULL;
07813       }
07814       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
07815          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
07816       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
07817          ast_copy_string(fromstring,s,sizeof(fromstring));
07818       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
07819          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
07820       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
07821          ast_copy_string(charset,s,sizeof(charset));
07822       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
07823          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
07824          for (x = 0; x < 4; x++) {
07825             memcpy(&adsifdn[x], &tmpadsi[x], 1);
07826          }
07827       }
07828       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
07829          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
07830          for (x = 0; x < 4; x++) {
07831             memcpy(&adsisec[x], &tmpadsi[x], 1);
07832          }
07833       }
07834       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
07835          if (atoi(s)) {
07836             adsiver = atoi(s);
07837          }
07838       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
07839          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
07840          ast_copy_string(emailtitle,s,sizeof(emailtitle));
07841       }
07842       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
07843          emailsubject = ast_strdup(s);
07844       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
07845          char *tmpread, *tmpwrite;
07846          emailbody = ast_strdup(s);
07847 
07848          /* substitute strings \t and \n into the appropriate characters */
07849          tmpread = tmpwrite = emailbody;
07850          while ((tmpwrite = strchr(tmpread,'\\'))) {
07851             switch (tmpwrite[1]) {
07852             case 'r':
07853                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07854                *tmpwrite = '\r';
07855                break;
07856             case 'n':
07857                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07858                *tmpwrite = '\n';
07859                break;
07860             case 't':
07861                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07862                *tmpwrite = '\t';
07863                break;
07864             default:
07865                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
07866             }
07867             tmpread = tmpwrite + 1;
07868          }
07869       }
07870       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
07871          pagersubject = ast_strdup(s);
07872       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
07873          char *tmpread, *tmpwrite;
07874          pagerbody = ast_strdup(s);
07875 
07876          /* substitute strings \t and \n into the appropriate characters */
07877          tmpread = tmpwrite = pagerbody;
07878          while ((tmpwrite = strchr(tmpread, '\\'))) {
07879             switch (tmpwrite[1]) {
07880             case 'r':
07881                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07882                *tmpwrite = '\r';
07883                break;
07884             case 'n':
07885                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07886                *tmpwrite = '\n';
07887                break;
07888             case 't':
07889                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
07890                *tmpwrite = '\t';
07891                break;
07892             default:
07893                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
07894             }
07895             tmpread = tmpwrite + 1;
07896          }
07897       }
07898       AST_LIST_UNLOCK(&users);
07899       ast_config_destroy(cfg);
07900       return 0;
07901    } else {
07902       AST_LIST_UNLOCK(&users);
07903       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
07904       return 0;
07905    }
07906 }

static int load_module ( void   )  [static]

Definition at line 7929 of file app_voicemail.c.

References app, app2, app3, app4, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, 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().

07930 {
07931    int res;
07932    char *adsi_loaded = ast_module_helper("", "res_adsi.so", 0, 0, 0, 0);
07933    free(adsi_loaded);
07934    if (!adsi_loaded) {
07935       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
07936       return AST_MODULE_LOAD_DECLINE;
07937    }
07938 
07939    my_umask = umask(0);
07940    umask(my_umask);
07941    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
07942    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
07943    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
07944    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
07945    if (res)
07946       return(res);
07947 
07948    if ((res=load_config())) {
07949       return(res);
07950    }
07951 
07952    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
07953 
07954    /* compute the location of the voicemail spool directory */
07955    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
07956 
07957    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
07958 
07959    return res;
07960 }

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

Definition at line 878 of file app_voicemail.c.

References VM_SPOOL_DIR.

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

00879 {
00880    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00881 }

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 1784 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(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

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

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

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

00915 {
00916    return snprintf(dest, len, "%s/msg%04d", dir, num);
00917 }

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

Definition at line 2142 of file app_voicemail.c.

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

02143 {
02144    static const char *msgs[] = {
02145       "INBOX",
02146       "Old",
02147       "Work",
02148       "Family",
02149       "Friends",
02150       "Cust1",
02151       "Cust2",
02152       "Cust3",
02153       "Cust4",
02154       "Cust5",
02155    };
02156    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
02157 }

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

Definition at line 2664 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

02665 {
02666    return __has_voicemail(context, mailbox, folder, 0);
02667 }

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

03935 {
03936    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
03937    int newmsgs = 0, oldmsgs = 0;
03938    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
03939 
03940    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
03941    make_file(fn, sizeof(fn), todir, msgnum);
03942    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
03943 
03944    if (!ast_strlen_zero(vmu->attachfmt)) {
03945       if (strstr(fmt, vmu->attachfmt)) {
03946          fmt = vmu->attachfmt;
03947       } else {
03948          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);
03949       }
03950    }
03951 
03952    /* Attach only the first format */
03953    fmt = ast_strdupa(fmt);
03954    stringp = fmt;
03955    strsep(&stringp, "|");
03956 
03957    if (!ast_strlen_zero(vmu->email)) {
03958       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
03959       char *myserveremail = serveremail;
03960       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
03961       if (!ast_strlen_zero(vmu->serveremail))
03962          myserveremail = vmu->serveremail;
03963       
03964       if (attach_user_voicemail)
03965          RETRIEVE(todir, msgnum);
03966 
03967       /*XXX possible imap issue, should category be NULL XXX*/
03968       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
03969 
03970       if (attach_user_voicemail)
03971          DISPOSE(todir, msgnum);
03972    }
03973 
03974    if (!ast_strlen_zero(vmu->pager)) {
03975       char *myserveremail = serveremail;
03976       if (!ast_strlen_zero(vmu->serveremail))
03977          myserveremail = vmu->serveremail;
03978       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, cidnum, cidname, duration, vmu, category);
03979    }
03980 
03981    if (ast_test_flag(vmu, VM_DELETE)) {
03982       DELETE(todir, msgnum, fn);
03983    }
03984 
03985 #ifdef IMAP_STORAGE
03986    DELETE(todir, msgnum, fn);
03987 #endif
03988    /* Leave voicemail for someone */
03989    if (ast_app_has_voicemail(ext_context, NULL)) {
03990       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
03991    }
03992    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);
03993    run_externnotify(vmu->context, vmu->mailbox);
03994    return 0;
03995 }

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

Definition at line 1623 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

01624 {
01625    if (bio->linelength>=BASELINELEN) {
01626       if (fputs(eol,so)==EOF)
01627          return -1;
01628 
01629       bio->linelength= 0;
01630    }
01631 
01632    if (putc(((unsigned char)c),so)==EOF)
01633       return -1;
01634 
01635    bio->linelength++;
01636 
01637    return 1;
01638 }

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

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

04864 {
04865    int res = 0;
04866    int count_msg, last_msg;
04867 
04868    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
04869    
04870    /* Rename the member vmbox HERE so that we don't try to return before
04871     * we know what's going on.
04872     */
04873    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
04874    
04875    /* Faster to make the directory than to check if it exists. */
04876    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
04877 
04878    count_msg = count_messages(vmu, vms->curdir);
04879    if (count_msg < 0)
04880       return count_msg;
04881    else
04882       vms->lastmsg = count_msg - 1;
04883 
04884    /*
04885    The following test is needed in case sequencing gets messed up.
04886    There appears to be more than one way to mess up sequence, so
04887    we will not try to find all of the root causes--just fix it when
04888    detected.
04889    */
04890 
04891    last_msg = last_message_index(vmu, vms->curdir);
04892    if (last_msg < 0)
04893       return last_msg;
04894    else if (vms->lastmsg != last_msg)
04895    {
04896       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
04897       res = resequence_mailbox(vmu, vms->curdir);
04898       if (res)
04899          return res;
04900    }
04901 
04902    return 0;
04903 }

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

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

02077 {
02078    int res = -2;
02079 
02080 #ifdef ODBC_STORAGE
02081    int success = 
02082 #endif
02083    RETRIEVE(filename, -1);
02084    if (ast_fileexists(filename, NULL, NULL) > 0) {
02085       res = ast_streamfile(chan, filename, chan->language);
02086       if (res > -1) 
02087          res = ast_waitstream(chan, ecodes);
02088 #ifdef ODBC_STORAGE
02089       if (success == -1) {
02090          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
02091          if (option_debug)
02092             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
02093          store_file(filename, vmu->mailbox, vmu->context, -1);
02094       }
02095 #endif
02096    }
02097    DISPOSE(filename, -1);
02098 
02099    return res;
02100 }

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

Definition at line 4618 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_es(), vm_browse_messages_gr(), vm_browse_messages_it(), vm_browse_messages_pt(), and vm_execmain().

04619 {
04620    int res = 0;
04621    char filename[256], *cid;
04622    const char *origtime, *context, *category, *duration;
04623    struct ast_config *msg_cfg;
04624 
04625    vms->starting = 0; 
04626    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04627    adsi_message(chan, vms);
04628    if (!vms->curmsg)
04629       res = wait_file2(chan, vms, "vm-first");  /* "First" */
04630    else if (vms->curmsg == vms->lastmsg)
04631       res = wait_file2(chan, vms, "vm-last");      /* "last" */
04632    if (!res) {
04633       /* POLISH syntax */
04634       if (!strcasecmp(chan->language, "pl")) { 
04635          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04636             int ten, one;
04637             char nextmsg[256];
04638             ten = (vms->curmsg + 1) / 10;
04639             one = (vms->curmsg + 1) % 10;
04640             
04641             if (vms->curmsg < 20) {
04642                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
04643                res = wait_file2(chan, vms, nextmsg);
04644             } else {
04645                snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
04646                res = wait_file2(chan, vms, nextmsg);
04647                if (one > 0) {
04648                   if (!res) {
04649                      snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
04650                      res = wait_file2(chan, vms, nextmsg);
04651                   }
04652                }
04653             }
04654          }
04655          if (!res)
04656             res = wait_file2(chan, vms, "vm-message");
04657       } else {
04658          if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
04659             res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
04660          else /* DEFAULT syntax */
04661             res = wait_file2(chan, vms, "vm-message");
04662          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
04663             if (!res)
04664                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
04665          }
04666       }
04667    }
04668 
04669    /* Retrieve info from VM attribute file */
04670    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
04671    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
04672    RETRIEVE(vms->curdir, vms->curmsg);
04673    msg_cfg = ast_config_load(filename);
04674    if (!msg_cfg) {
04675       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
04676       return 0;
04677    }
04678 
04679    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
04680       ast_log(LOG_WARNING, "No origtime?!\n");
04681       DISPOSE(vms->curdir, vms->curmsg);
04682       ast_config_destroy(msg_cfg);
04683       return 0;
04684    }
04685 
04686    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
04687    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
04688    category = ast_variable_retrieve(msg_cfg, "message", "category");
04689 
04690    context = ast_variable_retrieve(msg_cfg, "message", "context");
04691    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
04692       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
04693    if (!res)
04694       res = play_message_category(chan, category);
04695    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
04696       res = play_message_datetime(chan, vmu, origtime, filename);
04697    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
04698       res = play_message_callerid(chan, vms, cid, context, 0);
04699    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
04700       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
04701    /* Allow pressing '1' to skip envelope / callerid */
04702    if (res == '1')
04703       res = 0;
04704    ast_config_destroy(msg_cfg);
04705 
04706    if (!res) {
04707       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
04708       vms->heard[vms->curmsg] = 1;
04709       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
04710          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
04711          res = 0;
04712       }
04713    }
04714    DISPOSE(vms->curdir, vms->curmsg);
04715    return res;
04716 }

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

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

04367 {
04368    int res = 0;
04369    int i;
04370    char *callerid, *name;
04371    char prefile[PATH_MAX] = "";
04372    
04373 
04374    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
04375    /* 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 */
04376    if ((cid == NULL)||(context == NULL))
04377       return res;
04378 
04379    /* Strip off caller ID number from name */
04380    if (option_debug > 2)
04381       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
04382    ast_callerid_parse(cid, &name, &callerid);
04383    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
04384       /* Check for internal contexts and only */
04385       /* say extension when the call didn't come from an internal context in the list */
04386       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
04387          if (option_debug > 2)
04388             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
04389          if ((strcmp(cidinternalcontexts[i], context) == 0))
04390             break;
04391       }
04392       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
04393          if (!res) {
04394             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
04395             if (!ast_strlen_zero(prefile)) {
04396             /* See if we can find a recorded name for this person instead of their extension number */
04397                if (ast_fileexists(prefile, NULL, NULL) > 0) {
04398                   if (option_verbose > 2)
04399                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
04400                   if (!callback)
04401                      res = wait_file2(chan, vms, "vm-from");
04402                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
04403                } else {
04404                   if (option_verbose > 2)
04405                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
04406                   /* BB: Say "from extension" as one saying to sound smoother */
04407                   if (!callback)
04408                      res = wait_file2(chan, vms, "vm-from-extension");
04409                   res = ast_say_digit_str(chan, callerid, "", chan->language);
04410                }
04411             }
04412          }
04413       }
04414 
04415       else if (!res){
04416          if (option_debug > 2)
04417             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
04418          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
04419          if (!callback)
04420             res = wait_file2(chan, vms, "vm-from-phonenumber");
04421          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
04422       }
04423    } else {
04424       /* Number unknown */
04425       if (option_debug)
04426          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
04427       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
04428       res = wait_file2(chan, vms, "vm-unknown-caller");
04429    }
04430    return res;
04431 }

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

Definition at line 4281 of file app_voicemail.c.

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

Referenced by play_message().

04282 {
04283    int res = 0;
04284 
04285    if (!ast_strlen_zero(category))
04286       res = ast_play_and_wait(chan, category);
04287 
04288    if (res) {
04289       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
04290       res = 0;
04291    }
04292 
04293    return res;
04294 }

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

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

Referenced by advanced_options(), and play_message().

04297 {
04298    int res = 0;
04299    struct vm_zone *the_zone = NULL;
04300    time_t t;
04301 
04302    if (ast_get_time_t(origtime, &t, 0, NULL)) {
04303       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
04304       return 0;
04305    }
04306 
04307    /* Does this user have a timezone specified? */
04308    if (!ast_strlen_zero(vmu->zonetag)) {
04309       /* Find the zone in the list */
04310       struct vm_zone *z;
04311       AST_LIST_LOCK(&zones);
04312       AST_LIST_TRAVERSE(&zones, z, list) {
04313          if (!strcmp(z->name, vmu->zonetag)) {
04314             the_zone = z;
04315             break;
04316          }
04317       }
04318       AST_LIST_UNLOCK(&zones);
04319    }
04320 
04321 /* No internal variable parsing for now, so we'll comment it out for the time being */
04322 #if 0
04323    /* Set the DIFF_* variables */
04324    ast_localtime(&t, &time_now, NULL);
04325    tv_now = ast_tvnow();
04326    tnow = tv_now.tv_sec;
04327    ast_localtime(&tnow, &time_then, NULL);
04328 
04329    /* Day difference */
04330    if (time_now.tm_year == time_then.tm_year)
04331       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
04332    else
04333       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
04334    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
04335 
04336    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
04337 #endif
04338    if (the_zone)
04339       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
04340    else if (!strcasecmp(chan->language,"pl"))       /* POLISH syntax */
04341       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
04342    else if (!strcasecmp(chan->language,"se"))       /* SWEDISH syntax */
04343       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
04344    else if (!strcasecmp(chan->language,"no"))       /* NORWEGIAN syntax */
04345       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04346    else if (!strcasecmp(chan->language,"de"))       /* GERMAN syntax */
04347       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
04348    else if (!strcasecmp(chan->language,"nl"))      /* DUTCH syntax */
04349       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
04350    else if (!strcasecmp(chan->language,"it"))      /* ITALIAN syntax */
04351       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);
04352    else if (!strcasecmp(chan->language,"gr"))
04353       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
04354    else if (!strcasecmp(chan->language,"pt_BR"))
04355       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);      
04356    else
04357       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
04358 #if 0
04359    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
04360 #endif
04361    return res;
04362 }

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

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

04434 {
04435    int res = 0;
04436    int durationm;
04437    int durations;
04438    /* Verify that we have a duration for the message */
04439    if (duration == NULL)
04440       return res;
04441 
04442    /* Convert from seconds to minutes */
04443    durations=atoi(duration);
04444    durationm=(durations / 60);
04445 
04446    if (option_debug > 2)
04447       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
04448 
04449    if ((!res) && (durationm >= minduration)) {
04450       res = wait_file2(chan, vms, "vm-duration");
04451 
04452       /* POLISH syntax */
04453       if (!strcasecmp(chan->language, "pl")) {
04454          div_t num = div(durationm, 10);
04455 
04456          if (durationm == 1) {
04457             res = ast_play_and_wait(chan, "digits/1z");
04458             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
04459          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
04460             if (num.rem == 2) {
04461                if (!num.quot) {
04462                   res = ast_play_and_wait(chan, "digits/2-ie");
04463                } else {
04464                   res = say_and_wait(chan, durationm - 2 , chan->language);
04465                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
04466                }
04467             } else {
04468                res = say_and_wait(chan, durationm, chan->language);
04469             }
04470             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
04471          } else {
04472             res = say_and_wait(chan, durationm, chan->language);
04473             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
04474          }
04475       /* DEFAULT syntax */
04476       } else {
04477          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
04478          res = wait_file2(chan, vms, "vm-minutes");
04479       }
04480    }
04481    return res;
04482 }

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

08269 {
08270    /* Record message & let caller review or re-record it, or set options if applicable */
08271    int res = 0;
08272    int cmd = 0;
08273    int max_attempts = 3;
08274    int attempts = 0;
08275    int recorded = 0;
08276    int message_exists = 0;
08277    signed char zero_gain = 0;
08278    char tempfile[PATH_MAX];
08279    char *acceptdtmf = "#";
08280    char *canceldtmf = "";
08281 
08282    /* Note that urgent and private are for flagging messages as such in the future */
08283 
08284    /* barf if no pointer passed to store duration in */
08285    if (duration == NULL) {
08286       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
08287       return -1;
08288    }
08289 
08290    if (!outsidecaller)
08291       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
08292    else
08293       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
08294 
08295    cmd = '3';  /* Want to start by recording */
08296 
08297    while ((cmd >= 0) && (cmd != 't')) {
08298       switch (cmd) {
08299       case '1':
08300          if (!message_exists) {
08301             /* In this case, 1 is to record a message */
08302             cmd = '3';
08303             break;
08304          } else {
08305             /* Otherwise 1 is to save the existing message */
08306             if (option_verbose > 2)
08307                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
08308             if (!outsidecaller)
08309                ast_filerename(tempfile, recordfile, NULL);
08310             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
08311             if (!outsidecaller) {
08312                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
08313                DISPOSE(recordfile, -1);
08314             }
08315             cmd = 't';
08316             return res;
08317          }
08318       case '2':
08319          /* Review */
08320          if (option_verbose > 2)
08321             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
08322          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
08323          break;
08324       case '3':
08325          message_exists = 0;
08326          /* Record */
08327          if (recorded == 1) {
08328             if (option_verbose > 2)
08329                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
08330          } else { 
08331             if (option_verbose > 2)
08332                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
08333          }
08334          if (recorded && outsidecaller) {
08335             cmd = ast_play_and_wait(chan, INTRO);
08336             cmd = ast_play_and_wait(chan, "beep");
08337          }
08338          recorded = 1;
08339          /* 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 */
08340          if (record_gain)
08341             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
08342          if (ast_test_flag(vmu, VM_OPERATOR))
08343             canceldtmf = "0";
08344          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
08345          if (record_gain)
08346             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
08347          if (cmd == -1) {
08348             /* User has hung up, no options to give */
08349             if (!outsidecaller) {
08350                /* user was recording a greeting and they hung up, so let's delete the recording. */
08351                ast_filedelete(tempfile, NULL);
08352             }
08353             return cmd;
08354          }
08355          if (cmd == '0') {
08356             break;
08357          } else if (cmd == '*') {
08358             break;
08359          } 
08360 #if 0       
08361          else if (vmu->review && (*duration < 5)) {
08362             /* Message is too short */
08363             if (option_verbose > 2)
08364                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
08365             cmd = ast_play_and_wait(chan, "vm-tooshort");
08366             cmd = ast_filedelete(tempfile, NULL);
08367             break;
08368          }
08369          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
08370             /* Message is all silence */
08371             if (option_verbose > 2)
08372                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
08373             cmd = ast_filedelete(tempfile, NULL);
08374             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
08375             if (!cmd)
08376                cmd = ast_play_and_wait(chan, "vm-speakup");
08377             break;
08378          }
08379 #endif
08380          else {
08381             /* If all is well, a message exists */
08382             message_exists = 1;
08383             cmd = 0;
08384          }
08385          break;
08386       case '4':
08387       case '5':
08388       case '6':
08389       case '7':
08390       case '8':
08391       case '9':
08392       case '*':
08393       case '#':
08394          cmd = ast_play_and_wait(chan, "vm-sorry");
08395          break;
08396 #if 0 
08397 /*  XXX Commented out for the moment because of the dangers of deleting
08398     a message while recording (can put the message numbers out of sync) */
08399       case '*':
08400          /* Cancel recording, delete message, offer to take another message*/
08401          cmd = ast_play_and_wait(chan, "vm-deleted");
08402          cmd = ast_filedelete(tempfile, NULL);
08403          if (outsidecaller) {
08404             res = vm_exec(chan, NULL);
08405             return res;
08406          }
08407          else
08408             return 1;
08409 #endif
08410       case '0':
08411          if (!ast_test_flag(vmu, VM_OPERATOR)) {
08412             cmd = ast_play_and_wait(chan, "vm-sorry");
08413             break;
08414          }
08415          if (message_exists || recorded) {
08416             cmd = ast_play_and_wait(chan, "vm-saveoper");
08417             if (!cmd)
08418                cmd = ast_waitfordigit(chan, 3000);
08419             if (cmd == '1') {
08420                ast_play_and_wait(chan, "vm-msgsaved");
08421                cmd = '0';
08422             } else {
08423                ast_play_and_wait(chan, "vm-deleted");
08424                DELETE(recordfile, -1, recordfile);
08425                cmd = '0';
08426             }
08427          }
08428          return cmd;
08429       default:
08430          /* If the caller is an ouside caller, and the review option is enabled,
08431             allow them to review the message, but let the owner of the box review
08432             their OGM's */
08433          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
08434             return cmd;
08435          if (message_exists) {
08436             cmd = ast_play_and_wait(chan, "vm-review");
08437          }
08438          else {
08439             cmd = ast_play_and_wait(chan, "vm-torerecord");
08440             if (!cmd)
08441                cmd = ast_waitfordigit(chan, 600);
08442          }
08443          
08444          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
08445             cmd = ast_play_and_wait(chan, "vm-reachoper");
08446             if (!cmd)
08447                cmd = ast_waitfordigit(chan, 600);
08448          }
08449 #if 0
08450          if (!cmd)
08451             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
08452 #endif
08453          if (!cmd)
08454             cmd = ast_waitfordigit(chan, 6000);
08455          if (!cmd) {
08456             attempts++;
08457          }
08458          if (attempts > max_attempts) {
08459             cmd = 't';
08460          }
08461       }
08462    }
08463    if (outsidecaller)
08464       ast_play_and_wait(chan, "vm-goodbye");
08465    if (cmd == 't')
08466       cmd = 0;
08467    return cmd;
08468 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

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

00575 {
00576    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00577    if (saydurationminfo)
00578       vmu->saydurationm = saydurationminfo;
00579    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00580    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00581    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00582    if (maxmsg)
00583       vmu->maxmsg = maxmsg;
00584    vmu->volgain = volgain;
00585 }

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

01713 {
01714    char callerid[256];
01715    /* Prepare variables for substitution in email body and subject */
01716    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
01717    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
01718    snprintf(passdata, passdatasize, "%d", msgnum);
01719    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
01720    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
01721    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
01722    pbx_builtin_setvar_helper(ast, "VM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
01723    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (cidname ? cidname : "an unknown caller"));
01724    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
01725    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
01726    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
01727 }

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

Definition at line 1729 of file app_voicemail.c.

01730 {
01731    char *ptr = to;
01732    *ptr++ = '"';
01733    for (; ptr < to + len - 1; from++) {
01734       if (*from == '"')
01735          *ptr++ = '\\';
01736       else if (*from == '\0')
01737          break;
01738       *ptr++ = *from;
01739    }
01740    if (ptr < to + len - 1)
01741       *ptr++ = '"';
01742    *ptr = '\0';
01743    return to;
01744 }

static int reload ( void   )  [static]

Definition at line 7908 of file app_voicemail.c.

References load_config().

07909 {
07910    return(load_config());
07911 }

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

Definition at line 1483 of file app_voicemail.c.

References ast_filerename().

01484 {
01485    char stxt[PATH_MAX];
01486    char dtxt[PATH_MAX];
01487    ast_filerename(sfn,dfn,NULL);
01488    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
01489    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
01490    rename(stxt, dtxt);
01491 }

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

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

03213 {
03214    /* we know max messages, so stop process when number is hit */
03215 
03216    int x,dest;
03217    char sfn[PATH_MAX];
03218    char dfn[PATH_MAX];
03219 
03220    if (vm_lock_path(dir))
03221       return ERROR_LOCK_PATH;
03222 
03223    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
03224       make_file(sfn, sizeof(sfn), dir, x);
03225       if (EXISTS(dir, x, sfn, NULL)) {
03226          
03227          if (x != dest) {
03228             make_file(dfn, sizeof(dfn), dir, dest);
03229             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
03230          }
03231          
03232          dest++;
03233       }
03234    }
03235    ast_unlock_path(dir);
03236 
03237    return 0;
03238 }

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

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

00774 {
00775    /* This function could be made to generate one from a database, too */
00776    struct ast_vm_user *cur;
00777    int res = -1;
00778    AST_LIST_LOCK(&users);
00779    AST_LIST_TRAVERSE(&users, cur, list) {
00780       if ((!context || !strcasecmp(context, cur->context)) &&
00781          (!strcasecmp(mailbox, cur->mailbox)))
00782             break;
00783    }
00784    if (cur) {
00785       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00786       res = 0;
00787    }
00788    AST_LIST_UNLOCK(&users);
00789    return res;
00790 }

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

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

02766 {
02767    char arguments[255];
02768    char ext_context[256] = "";
02769    int newvoicemails = 0, oldvoicemails = 0;
02770    struct ast_smdi_mwi_message *mwi_msg;
02771 
02772    if (!ast_strlen_zero(context))
02773       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
02774    else
02775       ast_copy_string(ext_context, extension, sizeof(ext_context));
02776 
02777    if (!strcasecmp(externnotify, "smdi")) {
02778       if (ast_app_has_voicemail(ext_context, NULL)) 
02779          ast_smdi_mwi_set(smdi_iface, extension);
02780       else
02781          ast_smdi_mwi_unset(smdi_iface, extension);
02782 
02783       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
02784          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
02785          if (!strncmp(mwi_msg->cause, "INV", 3))
02786             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
02787          else if (!strncmp(mwi_msg->cause, "BLK", 3))
02788             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
02789          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
02790          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
02791       } else {
02792          if (option_debug)
02793             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
02794       }
02795    } else if (!ast_strlen_zero(externnotify)) {
02796       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
02797          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
02798       } else {
02799          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
02800          if (option_debug)
02801             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
02802          ast_safe_system(arguments);
02803       }
02804    }
02805 }

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

Definition at line 3248 of file app_voicemail.c.

References ast_log(), ast_unlock_path(), ast_vm_user::context, create_dirpath(), 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().

03249 {
03250 #ifdef IMAP_STORAGE
03251    /* we must use mbox(x) folder names, and copy the message there */
03252    /* simple. huh? */
03253    long res;
03254    char sequence[10];
03255 
03256    /* if save to Old folder, just leave in INBOX */
03257    if (box == 1) return 10;
03258    /* get the real IMAP message number for this message */
03259    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
03260    if (option_debug > 2)
03261       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
03262    res = mail_copy(vms->mailstream,sequence,(char *) mbox(box));
03263    if (res == 1) return 0;
03264    return 1;
03265 #else
03266    char *dir = vms->curdir;
03267    char *username = vms->username;
03268    char *context = vmu->context;
03269    char sfn[PATH_MAX];
03270    char dfn[PATH_MAX];
03271    char ddir[PATH_MAX];
03272    const char *dbox = mbox(box);
03273    int x;
03274    make_file(sfn, sizeof(sfn), dir, msg);
03275    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
03276 
03277    if (vm_lock_path(ddir))
03278       return ERROR_LOCK_PATH;
03279 
03280    for (x = 0; x < vmu->maxmsg; x++) {
03281       make_file(dfn, sizeof(dfn), ddir, x);
03282       if (!EXISTS(ddir, x, dfn, NULL))
03283          break;
03284    }
03285    if (x >= vmu->maxmsg) {
03286       ast_unlock_path(ddir);
03287       return ERROR_MAILBOX_FULL;
03288    }
03289    if (strcmp(sfn, dfn)) {
03290       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
03291    }
03292    ast_unlock_path(ddir);
03293 #endif
03294    return 0;
03295 }

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

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

03242 {
03243    int d;
03244    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
03245    return d;
03246 }

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

01951 {
01952    FILE *p=NULL;
01953    char tmp[80] = "/tmp/astmail-XXXXXX";
01954    char tmp2[256];
01955 
01956    if (vmu && ast_strlen_zero(vmu->email)) {
01957       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
01958       return(0);
01959    }
01960    if (!strcmp(format, "wav49"))
01961       format = "WAV";
01962    if (option_debug > 2)
01963       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));
01964    /* Make a temporary file instead of piping directly to sendmail, in case the mail
01965       command hangs */
01966    if ((p = vm_mkftemp(tmp)) == NULL) {
01967       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
01968       return -1;
01969    } else {
01970       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
01971       fclose(p);
01972       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
01973       ast_safe_system(tmp2);
01974       if (option_debug > 2)
01975          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
01976    }
01977    return 0;
01978 }

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

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

static int unload_module ( void   )  [static]

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

07914 {
07915    int res;
07916    
07917    res = ast_unregister_application(app);
07918    res |= ast_unregister_application(app2);
07919    res |= ast_unregister_application(app3);
07920    res |= ast_unregister_application(app4);
07921    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
07922    ast_uninstall_vm_functions();
07923    
07924    ast_module_user_hangup_all();
07925 
07926    return res;
07927 }

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

06348 {
06349    int useadsi=0, valid=0, logretries=0;
06350    char password[AST_MAX_EXTENSION]="", *passptr;
06351    struct ast_vm_user vmus, *vmu = NULL;
06352 
06353    /* If ADSI is supported, setup login screen */
06354    adsi_begin(chan, &useadsi);
06355    if (!skipuser && useadsi)
06356       adsi_login(chan);
06357    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
06358       ast_log(LOG_WARNING, "Couldn't stream login file\n");
06359       return -1;
06360    }
06361    
06362    /* Authenticate them and get their mailbox/password */
06363    
06364    while (!valid && (logretries < maxlogins)) {
06365       /* Prompt for, and read in the username */
06366       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
06367          ast_log(LOG_WARNING, "Couldn't read username\n");
06368          return -1;
06369       }
06370       if (ast_strlen_zero(mailbox)) {
06371          if (chan->cid.cid_num) {
06372             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
06373          } else {
06374             if (option_verbose > 2)
06375                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
06376             return -1;
06377          }
06378       }
06379       if (useadsi)
06380          adsi_password(chan);
06381 
06382       if (!ast_strlen_zero(prefix)) {
06383          char fullusername[80] = "";
06384          ast_copy_string(fullusername, prefix, sizeof(fullusername));
06385          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
06386          ast_copy_string(mailbox, fullusername, mailbox_size);
06387       }
06388 
06389       if (option_debug)
06390          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
06391       vmu = find_user(&vmus, context, mailbox);
06392       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
06393          /* saved password is blank, so don't bother asking */
06394          password[0] = '\0';
06395       } else {
06396          if (ast_streamfile(chan, "vm-password", chan->language)) {
06397             ast_log(LOG_WARNING, "Unable to stream password file\n");
06398             return -1;
06399          }
06400          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
06401             ast_log(LOG_WARNING, "Unable to read password\n");
06402             return -1;
06403          }
06404       }
06405 
06406       if (vmu) {
06407          passptr = vmu->password;
06408          if (passptr[0] == '-') passptr++;
06409       }
06410       if (vmu && !strcmp(passptr, password))
06411          valid++;
06412       else {
06413          if (option_verbose > 2)
06414             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
06415          if (!ast_strlen_zero(prefix))
06416             mailbox[0] = '\0';
06417       }
06418       logretries++;
06419       if (!valid) {
06420          if (skipuser || logretries >= maxlogins) {
06421             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
06422                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
06423                return -1;
06424             }
06425          } else {
06426             if (useadsi)
06427                adsi_login(chan);
06428             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
06429                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
06430                return -1;
06431             }
06432          }
06433          if (ast_waitstream(chan, "")) /* Channel is hung up */
06434             return -1;
06435       }
06436    }
06437    if (!valid && (logretries >= maxlogins)) {
06438       ast_stopstream(chan);
06439       ast_play_and_wait(chan, "vm-goodbye");
06440       return -1;
06441    }
06442    if (vmu && !skipuser) {
06443       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
06444    }
06445    return 0;
06446 }

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

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

07160 {
07161    struct ast_module_user *u;
07162    struct ast_vm_user svm;
07163    char *context, *box;
07164    int priority_jump = 0;
07165    AST_DECLARE_APP_ARGS(args,
07166       AST_APP_ARG(mbox);
07167       AST_APP_ARG(options);
07168    );
07169 
07170    if (ast_strlen_zero(data)) {
07171       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
07172       return -1;
07173    }
07174 
07175    u = ast_module_user_add(chan);
07176 
07177    box = ast_strdupa(data);
07178 
07179    AST_STANDARD_APP_ARGS(args, box);
07180 
07181    if (args.options) {
07182       if (strchr(args.options, 'j'))
07183          priority_jump = 1;
07184    }
07185 
07186    if ((context = strchr(args.mbox, '@'))) {
07187       *context = '\0';
07188       context++;
07189    }
07190 
07191    if (find_user(&svm, context, args.mbox)) {
07192       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
07193       if (priority_jump || ast_opt_priority_jumping)
07194          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
07195             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);
07196    } else
07197       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
07198    ast_module_user_remove(u);
07199    return 0;
07200 }

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

Definition at line 6330 of file app_voicemail.c.

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

Referenced by vm_execmain().

06331 {
06332    if (!strcasecmp(chan->language, "es")) {  /* SPANISH */
06333       return vm_browse_messages_es(chan, vms, vmu);
06334    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
06335       return vm_browse_messages_it(chan, vms, vmu);
06336    } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {   /* PORTUGUESE */
06337       return vm_browse_messages_pt(chan, vms, vmu);
06338    } else if (!strcasecmp(chan->language, "gr")){
06339       return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
06340    } else { /* Default to English syntax */
06341       return vm_browse_messages_en(chan, vms, vmu);
06342    }
06343 }

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

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

06254 {
06255    int cmd=0;
06256 
06257    if (vms->lastmsg > -1) {
06258       cmd = play_message(chan, vmu, vms);
06259    } else {
06260       cmd = ast_play_and_wait(chan, "vm-youhave");
06261       if (!cmd) 
06262          cmd = ast_play_and_wait(chan, "vm-no");
06263       if (!cmd) {
06264          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06265          cmd = ast_play_and_wait(chan, vms->fn);
06266       }
06267       if (!cmd)
06268          cmd = ast_play_and_wait(chan, "vm-messages");
06269    }
06270    return cmd;
06271 }

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

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

06294 {
06295    int cmd=0;
06296 
06297    if (vms->lastmsg > -1) {
06298       cmd = play_message(chan, vmu, vms);
06299    } else {
06300       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06301       if (!cmd)
06302          cmd = ast_play_and_wait(chan, "vm-messages");
06303       if (!cmd) {
06304          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06305          cmd = ast_play_and_wait(chan, vms->fn);
06306       }
06307    }
06308    return cmd;
06309 }

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

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

06226 {
06227    int cmd=0;
06228 
06229    if (vms->lastmsg > -1) {
06230       cmd = play_message(chan, vmu, vms);
06231    } else {
06232       cmd = ast_play_and_wait(chan, "vm-youhaveno");
06233       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
06234          if (!cmd) {
06235             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
06236             cmd = ast_play_and_wait(chan, vms->fn);
06237          }
06238          if (!cmd)
06239             cmd = ast_play_and_wait(chan, "vm-messages");
06240       } else {
06241          if (!cmd)
06242             cmd = ast_play_and_wait(chan, "vm-messages");
06243          if (!cmd) {
06244             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06245             cmd = ast_play_and_wait(chan, vms->fn);
06246          }
06247       }
06248    } 
06249    return cmd;
06250 }

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

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

06275 {
06276    int cmd=0;
06277 
06278    if (vms->lastmsg > -1) {
06279       cmd = play_message(chan, vmu, vms);
06280    } else {
06281       cmd = ast_play_and_wait(chan, "vm-no");
06282       if (!cmd)
06283          cmd = ast_play_and_wait(chan, "vm-message");
06284       if (!cmd) {
06285          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06286          cmd = ast_play_and_wait(chan, vms->fn);
06287       }
06288    }
06289    return cmd;
06290 }

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

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

06313 {
06314    int cmd=0;
06315 
06316    if (vms->lastmsg > -1) {
06317       cmd = play_message(chan, vmu, vms);
06318    } else {
06319       cmd = ast_play_and_wait(chan, "vm-no");
06320       if (!cmd) {
06321          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
06322          cmd = ast_play_and_wait(chan, vms->fn);
06323       }
06324       if (!cmd)
06325          cmd = ast_play_and_wait(chan, "vm-messages");
06326    }
06327    return cmd;
06328 }

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

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

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

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

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

00868 {
00869    char buf[255];
00870    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00871    if (!ast_safe_system(buf)) {
00872       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00873       /* Reset the password in memory, too */
00874       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00875    }
00876 }

static int vm_delete ( char *  file  )  [static]

Definition at line 1577 of file app_voicemail.c.

References ast_filedelete().

Referenced by forward_message().

01578 {
01579    char *txt;
01580    int txtsize = 0;
01581 
01582    txtsize = (strlen(file) + 5)*sizeof(char);
01583    txt = alloca(txtsize);
01584    /* Sprintf here would safe because we alloca'd exactly the right length,
01585     * but trying to eliminate all sprintf's anyhow
01586     */
01587    snprintf(txt, txtsize, "%s.txt", file);
01588    unlink(txt);
01589    return ast_filedelete(file, NULL);
01590 }

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

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

07013 {
07014    int res = 0;
07015    struct ast_module_user *u;
07016    char *tmp;
07017    struct leave_vm_options leave_options;
07018    struct ast_flags flags = { 0 };
07019    static int deprecate_warning = 0;
07020    char *opts[OPT_ARG_ARRAY_SIZE];
07021    AST_DECLARE_APP_ARGS(args,
07022       AST_APP_ARG(argv0);
07023       AST_APP_ARG(argv1);
07024    );
07025 
07026    u = ast_module_user_add(chan);
07027    
07028    memset(&leave_options, 0, sizeof(leave_options));
07029 
07030    if (chan->_state != AST_STATE_UP)
07031       ast_answer(chan);
07032 
07033    if (!ast_strlen_zero(data)) {
07034       tmp = ast_strdupa(data);
07035       AST_STANDARD_APP_ARGS(args, tmp);
07036       if (args.argc == 2) {
07037          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07038             ast_module_user_remove(u);
07039             return -1;
07040          }
07041          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07042          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07043             int gain;
07044 
07045             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
07046                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07047                ast_module_user_remove(u);
07048                return -1;
07049             } else {
07050                leave_options.record_gain = (signed char) gain;
07051             }
07052          }
07053       } else {
07054          /* old style options parsing */
07055          int old = 0;
07056          char *orig_argv0 = args.argv0;
07057          while (*(args.argv0)) {
07058             if (*(args.argv0) == 's') {
07059                old = 1;
07060                ast_set_flag(&leave_options, OPT_SILENT);
07061             } else if (*(args.argv0) == 'b') {
07062                old = 1;
07063                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07064             } else if (*(args.argv0) == 'u') {
07065                old = 1;
07066                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07067             } else if (*(args.argv0) == 'j') {
07068                old = 1;
07069                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07070             } else
07071                break;
07072             (args.argv0)++;
07073          }
07074          if (!deprecate_warning && old) {
07075             deprecate_warning = 1;
07076             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07077             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07078          }
07079       }
07080    } else {
07081       char tmp[256];
07082       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07083       if (res < 0) {
07084          ast_module_user_remove(u);
07085          return res;
07086       }
07087       if (ast_strlen_zero(tmp)) {
07088          ast_module_user_remove(u);
07089          return 0;
07090       }
07091       args.argv0 = ast_strdupa(tmp);
07092    }
07093 
07094    res = leave_voicemail(chan, args.argv0, &leave_options);
07095 
07096    if (res == ERROR_LOCK_PATH) {
07097       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07098       /*Send the call to n+101 priority, where n is the current priority*/
07099       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07100          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07101             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07102       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07103       res = 0;
07104    }
07105    
07106    ast_module_user_remove(u);
07107 
07108    return res;
07109 }

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

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

06449 {
06450    /* XXX This is, admittedly, some pretty horrendous code.  For some
06451       reason it just seemed a lot easier to do with GOTO's.  I feel
06452       like I'm back in my GWBASIC days. XXX */
06453    int res=-1;
06454    int cmd=0;
06455    int valid = 0;
06456    struct ast_module_user *u;
06457    char prefixstr[80] ="";
06458    char ext_context[256]="";
06459    int box;
06460    int useadsi = 0;
06461    int skipuser = 0;
06462    struct vm_state vms;
06463    struct ast_vm_user *vmu = NULL, vmus;
06464    char *context=NULL;
06465    int silentexit = 0;
06466    struct ast_flags flags = { 0 };
06467    signed char record_gain = 0;
06468    int play_auto = 0;
06469    int play_folder = 0;
06470 #ifdef IMAP_STORAGE
06471    int deleted = 0;
06472 #endif
06473    u = ast_module_user_add(chan);
06474 
06475    /* Add the vm_state to the active list and keep it active */
06476    memset(&vms, 0, sizeof(vms));
06477    vms.lastmsg = -1;
06478 
06479    memset(&vmus, 0, sizeof(vmus));
06480 
06481    if (chan->_state != AST_STATE_UP) {
06482       if (option_debug)
06483          ast_log(LOG_DEBUG, "Before ast_answer\n");
06484       ast_answer(chan);
06485    }
06486 
06487    if (!ast_strlen_zero(data)) {
06488       char *opts[OPT_ARG_ARRAY_SIZE];
06489       char *parse;
06490       AST_DECLARE_APP_ARGS(args,
06491          AST_APP_ARG(argv0);
06492          AST_APP_ARG(argv1);
06493       );
06494 
06495       parse = ast_strdupa(data);
06496 
06497       AST_STANDARD_APP_ARGS(args, parse);
06498 
06499       if (args.argc == 2) {
06500          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
06501             ast_module_user_remove(u);
06502             return -1;
06503          }
06504          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
06505             int gain;
06506             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
06507                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
06508                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
06509                   ast_module_user_remove(u);
06510                   return -1;
06511                } else {
06512                   record_gain = (signed char) gain;
06513                }
06514             } else {
06515                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
06516             }
06517          }
06518          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
06519             play_auto = 1;
06520             if (opts[OPT_ARG_PLAYFOLDER]) {
06521                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
06522                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
06523                }
06524             } else {
06525                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
06526             }  
06527             if ( play_folder > 9 || play_folder < 0) {
06528                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
06529                play_folder = 0;
06530             }
06531          }
06532       } else {
06533          /* old style options parsing */
06534          while (*(args.argv0)) {
06535             if (*(args.argv0) == 's')
06536                ast_set_flag(&flags, OPT_SILENT);
06537             else if (*(args.argv0) == 'p')
06538                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
06539             else 
06540                break;
06541             (args.argv0)++;
06542          }
06543 
06544       }
06545 
06546       valid = ast_test_flag(&flags, OPT_SILENT);
06547 
06548       if ((context = strchr(args.argv0, '@')))
06549          *context++ = '\0';
06550 
06551       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
06552          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
06553       else
06554          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
06555 
06556       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
06557          skipuser++;
06558       else
06559          valid = 0;
06560    }
06561 
06562    if (!valid)
06563       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
06564 
06565    if (option_debug)
06566       ast_log(LOG_DEBUG, "After vm_authenticate\n");
06567    if (!res) {
06568       valid = 1;
06569       if (!skipuser)
06570          vmu = &vmus;
06571    } else {
06572       res = 0;
06573    }
06574 
06575    /* If ADSI is supported, setup login screen */
06576    adsi_begin(chan, &useadsi);
06577 
06578 #ifdef IMAP_STORAGE
06579    vms.interactive = 1;
06580    vms.updated = 1;
06581    vmstate_insert(&vms);
06582    init_vm_state(&vms);
06583 #endif
06584    if (!valid)
06585       goto out;
06586 
06587    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
06588       /* TODO: Handle memory allocation failure */
06589    }
06590    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
06591       /* TODO: Handle memory allocation failure */
06592    }
06593    
06594    /* Set language from config to override channel language */
06595    if (!ast_strlen_zero(vmu->language))
06596       ast_string_field_set(chan, language, vmu->language);
06597    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
06598    /* Retrieve old and new message counts */
06599    if (option_debug)
06600       ast_log(LOG_DEBUG, "Before open_mailbox\n");
06601    res = open_mailbox(&vms, vmu, 1);
06602    if (res == ERROR_LOCK_PATH)
06603       goto out;
06604    vms.oldmessages = vms.lastmsg + 1;
06605    if (option_debug > 2)
06606       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
06607    /* Start in INBOX */
06608    res = open_mailbox(&vms, vmu, 0);
06609    if (res == ERROR_LOCK_PATH)
06610       goto out;
06611    vms.newmessages = vms.lastmsg + 1;
06612    if (option_debug > 2)
06613       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
06614       
06615    /* Select proper mailbox FIRST!! */
06616    if (play_auto) {
06617       res = open_mailbox(&vms, vmu, play_folder);
06618       if (res == ERROR_LOCK_PATH)
06619          goto out;
06620 
06621       /* If there are no new messages, inform the user and hangup */
06622       if (vms.lastmsg == -1) {
06623          cmd = vm_browse_messages(chan, &vms, vmu);
06624          res = 0;
06625          goto out;
06626       }
06627    } else {
06628       if (!vms.newmessages && vms.oldmessages) {
06629          /* If we only have old messages start here */
06630          res = open_mailbox(&vms, vmu, 1);
06631          play_folder = 1;
06632          if (res == ERROR_LOCK_PATH)
06633             goto out;
06634       }
06635    }
06636 
06637    if (useadsi)
06638       adsi_status(chan, &vms);
06639    res = 0;
06640 
06641    /* Check to see if this is a new user */
06642    if (!strcasecmp(vmu->mailbox, vmu->password) && 
06643       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
06644       if (ast_play_and_wait(chan, "vm-newuser") == -1)
06645          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
06646       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
06647       if ((cmd == 't') || (cmd == '#')) {
06648          /* Timeout */
06649          res = 0;
06650          goto out;
06651       } else if (cmd < 0) {
06652          /* Hangup */
06653          res = -1;
06654          goto out;
06655       }
06656    }
06657 #ifdef IMAP_STORAGE
06658       if (option_debug > 2)
06659          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
06660       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
06661          if (option_debug)
06662             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
06663          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06664       }
06665       if (option_debug > 2)
06666          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
06667       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
06668          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
06669          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06670       }
06671 #endif
06672    if (play_auto) {
06673       cmd = '1';
06674    } else {
06675       cmd = vm_intro(chan, vmu, &vms);
06676    }
06677 
06678    vms.repeats = 0;
06679    vms.starting = 1;
06680    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
06681       /* Run main menu */
06682       switch (cmd) {
06683       case '1':
06684          vms.curmsg = 0;
06685          /* Fall through */
06686       case '5':
06687          cmd = vm_browse_messages(chan, &vms, vmu);
06688          break;
06689       case '2': /* Change folders */
06690          if (useadsi)
06691             adsi_folders(chan, 0, "Change to folder...");
06692          cmd = get_folder2(chan, "vm-changeto", 0);
06693          if (cmd == '#') {
06694             cmd = 0;
06695          } else if (cmd > 0) {
06696             cmd = cmd - '0';
06697             res = close_mailbox(&vms, vmu);
06698             if (res == ERROR_LOCK_PATH)
06699                goto out;
06700             res = open_mailbox(&vms, vmu, cmd);
06701             if (res == ERROR_LOCK_PATH)
06702                goto out;
06703             play_folder = cmd;
06704             cmd = 0;
06705          }
06706          if (useadsi)
06707             adsi_status2(chan, &vms);
06708             
06709          if (!cmd)
06710             cmd = vm_play_folder_name(chan, vms.vmbox);
06711 
06712          vms.starting = 1;
06713          break;
06714       case '3': /* Advanced options */
06715          cmd = 0;
06716          vms.repeats = 0;
06717          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
06718             switch (cmd) {
06719             case '1': /* Reply */
06720                if (vms.lastmsg > -1 && !vms.starting) {
06721                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
06722                   if (cmd == ERROR_LOCK_PATH) {
06723                      res = cmd;
06724                      goto out;
06725                   }
06726                } else
06727                   cmd = ast_play_and_wait(chan, "vm-sorry");
06728                cmd = 't';
06729                break;
06730             case '2': /* Callback */
06731                if (option_verbose > 2 && !vms.starting)
06732                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
06733                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
06734                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
06735                   if (cmd == 9) {
06736                      silentexit = 1;
06737                      goto out;
06738                   } else if (cmd == ERROR_LOCK_PATH) {
06739                      res = cmd;
06740                      goto out;
06741                   }
06742                }
06743                else 
06744                   cmd = ast_play_and_wait(chan, "vm-sorry");
06745                cmd = 't';
06746                break;
06747             case '3': /* Envelope */
06748                if (vms.lastmsg > -1 && !vms.starting) {
06749                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
06750                   if (cmd == ERROR_LOCK_PATH) {
06751                      res = cmd;
06752                      goto out;
06753                   }
06754                } else
06755                   cmd = ast_play_and_wait(chan, "vm-sorry");
06756                cmd = 't';
06757                break;
06758             case '4': /* Dialout */
06759                if (!ast_strlen_zero(vmu->dialout)) {
06760                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
06761                   if (cmd == 9) {
06762                      silentexit = 1;
06763                      goto out;
06764                   }
06765                }
06766                else 
06767                   cmd = ast_play_and_wait(chan, "vm-sorry");
06768                cmd = 't';
06769                break;
06770 
06771             case '5': /* Leave VoiceMail */
06772                if (ast_test_flag(vmu, VM_SVMAIL)) {
06773                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
06774                   if (cmd == ERROR_LOCK_PATH) {
06775                      res = cmd;
06776                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
06777                      goto out;
06778                   }
06779                } else
06780                   cmd = ast_play_and_wait(chan,"vm-sorry");
06781                cmd='t';
06782                break;
06783                
06784             case '*': /* Return to main menu */
06785                cmd = 't';
06786                break;
06787 
06788             default:
06789                cmd = 0;
06790                if (!vms.starting) {
06791                   cmd = ast_play_and_wait(chan, "vm-toreply");
06792                }
06793                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
06794                   cmd = ast_play_and_wait(chan, "vm-tocallback");
06795                }
06796                if (!cmd && !vms.starting) {
06797                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
06798                }
06799                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
06800                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
06801                }
06802                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
06803                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
06804                if (!cmd)
06805                   cmd = ast_play_and_wait(chan, "vm-starmain");
06806                if (!cmd)
06807                   cmd = ast_waitfordigit(chan,6000);
06808                if (!cmd)
06809                   vms.repeats++;
06810                if (vms.repeats > 3)
06811                   cmd = 't';
06812             }
06813          }
06814          if (cmd == 't') {
06815             cmd = 0;
06816             vms.repeats = 0;
06817          }
06818          break;
06819       case '4':
06820          if (vms.curmsg > 0) {
06821             vms.curmsg--;
06822             cmd = play_message(chan, vmu, &vms);
06823          } else {
06824             cmd = ast_play_and_wait(chan, "vm-nomore");
06825          }
06826          break;
06827       case '6':
06828          if (vms.curmsg < vms.lastmsg) {
06829             vms.curmsg++;
06830             cmd = play_message(chan, vmu, &vms);
06831          } else {
06832             cmd = ast_play_and_wait(chan, "vm-nomore");
06833          }
06834          break;
06835       case '7':
06836          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
06837             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
06838             if (useadsi)
06839                adsi_delete(chan, &vms);
06840             if (vms.deleted[vms.curmsg]) {
06841                if (play_folder == 0)
06842                   vms.newmessages--;
06843                else if (play_folder == 1)
06844                   vms.oldmessages--;
06845                cmd = ast_play_and_wait(chan, "vm-deleted");
06846             }
06847             else {
06848                if (play_folder == 0)
06849                   vms.newmessages++;
06850                else if (play_folder == 1)
06851                   vms.oldmessages++;
06852                cmd = ast_play_and_wait(chan, "vm-undeleted");
06853             }
06854             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
06855                if (vms.curmsg < vms.lastmsg) {
06856                   vms.curmsg++;
06857                   cmd = play_message(chan, vmu, &vms);
06858                } else {
06859                   cmd = ast_play_and_wait(chan, "vm-nomore");
06860                }
06861             }
06862          } else /* Delete not valid if we haven't selected a message */
06863             cmd = 0;
06864 #ifdef IMAP_STORAGE
06865          deleted = 1;
06866 #endif
06867          break;
06868    
06869       case '8':
06870          if (vms.lastmsg > -1) {
06871             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
06872             if (cmd == ERROR_LOCK_PATH) {
06873                res = cmd;
06874                goto out;
06875             }
06876          } else
06877             cmd = ast_play_and_wait(chan, "vm-nomore");
06878          break;
06879       case '9':
06880          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
06881             /* No message selected */
06882             cmd = 0;
06883             break;
06884          }
06885          if (useadsi)
06886             adsi_folders(chan, 1, "Save to folder...");
06887          cmd = get_folder2(chan, "vm-savefolder", 1);
06888          box = 0; /* Shut up compiler */
06889          if (cmd == '#') {
06890             cmd = 0;
06891             break;
06892          } else if (cmd > 0) {
06893             box = cmd = cmd - '0';
06894             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
06895             if (cmd == ERROR_LOCK_PATH) {
06896                res = cmd;
06897                goto out;
06898 #ifdef IMAP_STORAGE
06899             } else if (cmd == 10) {
06900                goto out;
06901 #endif
06902             } else if (!cmd) {
06903                vms.deleted[vms.curmsg] = 1;
06904             } else {
06905                vms.deleted[vms.curmsg] = 0;
06906                vms.heard[vms.curmsg] = 0;
06907             }
06908          }
06909          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
06910          if (useadsi)
06911             adsi_message(chan, &vms);
06912          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
06913          if (!cmd) {
06914             cmd = ast_play_and_wait(chan, "vm-message");
06915             if (!cmd)
06916                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
06917             if (!cmd)
06918                cmd = ast_play_and_wait(chan, "vm-savedto");
06919             if (!cmd)
06920                cmd = vm_play_folder_name(chan, vms.fn);
06921          } else {
06922             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
06923          }
06924          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
06925             if (vms.curmsg < vms.lastmsg) {
06926                vms.curmsg++;
06927                cmd = play_message(chan, vmu, &vms);
06928             } else {
06929                cmd = ast_play_and_wait(chan, "vm-nomore");
06930             }
06931          }
06932          break;
06933       case '*':
06934          if (!vms.starting) {
06935             cmd = ast_play_and_wait(chan, "vm-onefor");
06936             if (!cmd)
06937                cmd = vm_play_folder_name(chan, vms.vmbox);
06938             if (!cmd)
06939                cmd = ast_play_and_wait(chan, "vm-opts");
06940             if (!cmd)
06941                cmd = vm_instructions(chan, &vms, 1);
06942          } else
06943             cmd = 0;
06944          break;
06945       case '0':
06946          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
06947          if (useadsi)
06948             adsi_status(chan, &vms);
06949          break;
06950       default: /* Nothing */
06951          cmd = vm_instructions(chan, &vms, 0);
06952          break;
06953       }
06954    }
06955    if ((cmd == 't') || (cmd == '#')) {
06956       /* Timeout */
06957       res = 0;
06958    } else {
06959       /* Hangup */
06960       res = -1;
06961    }
06962 
06963 out:
06964    if (res > -1) {
06965       ast_stopstream(chan);
06966       adsi_goodbye(chan);
06967       if (valid) {
06968          if (silentexit)
06969             res = ast_play_and_wait(chan, "vm-dialout");
06970          else 
06971             res = ast_play_and_wait(chan, "vm-goodbye");
06972          if (res > 0)
06973             res = 0;
06974       }
06975       if (useadsi)
06976          ast_adsi_unload_session(chan);
06977    }
06978    if (vmu)
06979       close_mailbox(&vms, vmu);
06980    if (valid) {
06981       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
06982       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
06983       run_externnotify(vmu->context, vmu->mailbox);
06984    }
06985 #ifdef IMAP_STORAGE
06986    /* expunge message - use UID Expunge if supported on IMAP server*/
06987    if (option_debug > 2)
06988       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
06989    if (vmu && deleted == 1 && expungeonhangup == 1) {
06990 #ifdef HAVE_IMAP_TK2006
06991       if (LEVELUIDPLUS (vms.mailstream)) {
06992          mail_expunge_full(vms.mailstream,NIL,EX_UID);
06993       } else 
06994 #endif
06995          mail_expunge(vms.mailstream);
06996    }
06997    /*  before we delete the state, we should copy pertinent info
06998     *  back to the persistent model */
06999    vmstate_delete(&vms);
07000 #endif
07001    if (vmu)
07002       free_user(vmu);
07003    if (vms.deleted)
07004       free(vms.deleted);
07005    if (vms.heard)
07006       free(vms.heard);
07007    ast_module_user_remove(u);
07008 
07009    return res;
07010 }

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 3831 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(), ast_vm_user::mailbox, make_file(), maxsilence, silencethreshold, and STORE.

Referenced by forward_message().

03833 {
03834    int cmd = 0;
03835    int retries = 0, prepend_duration = 0, already_recorded = 0;
03836    signed char zero_gain = 0;
03837    struct ast_config *msg_cfg;
03838    const char *duration_str;
03839    char msgfile[PATH_MAX], backup[PATH_MAX];
03840    char textfile[PATH_MAX];
03841 
03842    /* Must always populate duration correctly */
03843    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
03844    strcpy(textfile, msgfile);
03845    strcpy(backup, msgfile);
03846    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
03847    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
03848 
03849    if (!(msg_cfg = ast_config_load(textfile))) {
03850       return -1;
03851    }
03852 
03853    *duration = 0;
03854    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
03855       *duration = atoi(duration_str);
03856 
03857    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
03858       if (cmd)
03859          retries = 0;
03860       switch (cmd) {
03861       case '1': 
03862          /* prepend a message to the current message, update the metadata and return */
03863       {
03864          prepend_duration = 0;
03865 
03866          /* if we can't read the message metadata, stop now */
03867          if (!msg_cfg) {
03868             cmd = 0;
03869             break;
03870          }
03871 
03872          /* Back up the original file, so we can retry the prepend */
03873          if (already_recorded)
03874             ast_filecopy(backup, msgfile, NULL);
03875          else
03876             ast_filecopy(msgfile, backup, NULL);
03877          already_recorded = 1;
03878 
03879          if (record_gain)
03880             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
03881 
03882          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
03883          if (record_gain)
03884             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
03885 
03886          if (prepend_duration) {
03887             struct ast_category *msg_cat;
03888             /* need enough space for a maximum-length message duration */
03889             char duration_str[12];
03890 
03891             prepend_duration += *duration;
03892             msg_cat = ast_category_get(msg_cfg, "message");
03893             snprintf(duration_str, 11, "%d", prepend_duration);
03894             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
03895                config_text_file_save(textfile, msg_cfg, "app_voicemail");
03896                STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, prepend_duration, vms);
03897             }
03898          }
03899 
03900          break;
03901       }
03902       case '2': 
03903          cmd = 't';
03904          break;
03905       case '*':
03906          cmd = '*';
03907          break;
03908       default: 
03909          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
03910             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
03911          if (!cmd)
03912             cmd = ast_play_and_wait(chan,"vm-starmain");
03913             /* "press star to return to the main menu" */
03914          if (!cmd)
03915             cmd = ast_waitfordigit(chan,6000);
03916          if (!cmd)
03917             retries++;
03918          if (retries > 3)
03919             cmd = 't';
03920       }
03921    }
03922 
03923    ast_config_destroy(msg_cfg);
03924    if (already_recorded)
03925       ast_filedelete(backup, NULL);
03926    if (prepend_duration)
03927       *duration = prepend_duration;
03928 
03929    if (cmd == 't' || cmd == 'S')
03930       cmd = 0;
03931    return cmd;
03932 }

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

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

05893 {
05894    int res = 0;
05895    /* Play instructions and wait for new command */
05896    while (!res) {
05897       if (vms->starting) {
05898          if (vms->lastmsg > -1) {
05899             res = ast_play_and_wait(chan, "vm-onefor");
05900             if (!res)
05901                res = vm_play_folder_name(chan, vms->vmbox);
05902          }
05903          if (!res)
05904             res = ast_play_and_wait(chan, "vm-opts");
05905       } else {
05906          if (vms->curmsg)
05907             res = ast_play_and_wait(chan, "vm-prev");
05908          if (!res && !skipadvanced)
05909             res = ast_play_and_wait(chan, "vm-advopts");
05910          if (!res)
05911             res = ast_play_and_wait(chan, "vm-repeat");
05912          if (!res && (vms->curmsg != vms->lastmsg))
05913             res = ast_play_and_wait(chan, "vm-next");
05914          if (!res) {
05915             if (!vms->deleted[vms->curmsg])
05916                res = ast_play_and_wait(chan, "vm-delete");
05917             else
05918                res = ast_play_and_wait(chan, "vm-undelete");
05919             if (!res)
05920                res = ast_play_and_wait(chan, "vm-toforward");
05921             if (!res)
05922                res = ast_play_and_wait(chan, "vm-savemessage");
05923          }
05924       }
05925       if (!res)
05926          res = ast_play_and_wait(chan, "vm-helpexit");
05927       if (!res)
05928          res = ast_waitfordigit(chan, 6000);
05929       if (!res) {
05930          vms->repeats++;
05931          if (vms->repeats > 2) {
05932             res = 't';
05933          }
05934       }
05935    }
05936    return res;
05937 }

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

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

05848 {
05849    char prefile[256];
05850    
05851    /* Notify the user that the temp greeting is set and give them the option to remove it */
05852    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
05853    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
05854       if (ast_fileexists(prefile, NULL, NULL) > 0)
05855          ast_play_and_wait(chan, "vm-tempgreetactive");
05856    }
05857 
05858    /* Play voicemail intro - syntax is different for different languages */
05859    if (!strcasecmp(chan->language, "de")) {  /* GERMAN syntax */
05860       return vm_intro_de(chan, vms);
05861    } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
05862       return vm_intro_es(chan, vms);
05863    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
05864       return vm_intro_it(chan, vms);
05865    } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
05866       return vm_intro_fr(chan, vms);
05867    } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
05868       return vm_intro_nl(chan, vms);
05869    } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
05870       return vm_intro_pt(chan, vms);
05871    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
05872       return vm_intro_pt_BR(chan, vms);      
05873    } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
05874       return vm_intro_cz(chan, vms);
05875    } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
05876       return vm_intro_gr(chan, vms);
05877    } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */
05878       return vm_intro_pl(chan, vms);
05879    } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
05880       return vm_intro_se(chan, vms);
05881    } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
05882       return vm_intro_no(chan, vms);
05883    } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */
05884       return vm_intro_ru(chan, vms);
05885    } else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */
05886       return vm_intro_ua(chan, vms);
05887    } else {             /* Default to ENGLISH */
05888       return vm_intro_en(chan, vms);
05889    }
05890 }

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

Definition at line 5642 of file app_voicemail.c.

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

Referenced by vm_intro().

05643 {
05644    int res;
05645    res = ast_play_and_wait(chan, "vm-youhave");
05646    if (!res) {
05647       if (vms->newmessages) {
05648          if (vms->newmessages == 1) {
05649             res = ast_play_and_wait(chan, "digits/jednu");
05650          } else {
05651             res = say_and_wait(chan, vms->newmessages, chan->language);
05652          }
05653          if (!res) {
05654             if ((vms->newmessages == 1))
05655                res = ast_play_and_wait(chan, "vm-novou");
05656             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05657                res = ast_play_and_wait(chan, "vm-nove");
05658             if (vms->newmessages > 4)
05659                res = ast_play_and_wait(chan, "vm-novych");
05660          }
05661          if (vms->oldmessages && !res)
05662             res = ast_play_and_wait(chan, "vm-and");
05663          else if (!res) {
05664             if ((vms->newmessages == 1))
05665                res = ast_play_and_wait(chan, "vm-zpravu");
05666             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
05667                res = ast_play_and_wait(chan, "vm-zpravy");
05668             if (vms->newmessages > 4)
05669                res = ast_play_and_wait(chan, "vm-zprav");
05670          }
05671       }
05672       if (!res && vms->oldmessages) {
05673          res = say_and_wait(chan, vms->oldmessages, chan->language);
05674          if (!res) {
05675             if ((vms->oldmessages == 1))
05676                res = ast_play_and_wait(chan, "vm-starou");
05677             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05678                res = ast_play_and_wait(chan, "vm-stare");
05679             if (vms->oldmessages > 4)
05680                res = ast_play_and_wait(chan, "vm-starych");
05681          }
05682          if (!res) {
05683             if ((vms->oldmessages == 1))
05684                res = ast_play_and_wait(chan, "vm-zpravu");
05685             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
05686                res = ast_play_and_wait(chan, "vm-zpravy");
05687             if (vms->oldmessages > 4)
05688                res = ast_play_and_wait(chan, "vm-zprav");
05689          }
05690       }
05691       if (!res) {
05692          if (!vms->oldmessages && !vms->newmessages) {
05693             res = ast_play_and_wait(chan, "vm-no");
05694             if (!res)
05695                res = ast_play_and_wait(chan, "vm-zpravy");
05696          }
05697       }
05698    }
05699    return res;
05700 }

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

Definition at line 5335 of file app_voicemail.c.

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

Referenced by vm_intro().

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

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

Definition at line 5097 of file app_voicemail.c.

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

Referenced by vm_intro().

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

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

Definition at line 5384 of file app_voicemail.c.

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

Referenced by vm_intro().

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

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

Definition at line 5485 of file app_voicemail.c.

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

Referenced by vm_intro().

05486 {
05487    /* Introduce messages they have */
05488    int res;
05489    res = ast_play_and_wait(chan, "vm-youhave");
05490    if (!res) {
05491       if (vms->newmessages) {
05492          res = say_and_wait(chan, vms->newmessages, chan->language);
05493          if (!res)
05494             res = ast_play_and_wait(chan, "vm-INBOX");
05495          if (vms->oldmessages && !res)
05496             res = ast_play_and_wait(chan, "vm-and");
05497          else if (!res) {
05498             if ((vms->newmessages == 1))
05499                res = ast_play_and_wait(chan, "vm-message");
05500             else
05501                res = ast_play_and_wait(chan, "vm-messages");
05502          }
05503             
05504       }
05505       if (!res && vms->oldmessages) {
05506          res = say_and_wait(chan, vms->oldmessages, chan->language);
05507          if (!res)
05508             res = ast_play_and_wait(chan, "vm-Old");
05509          if (!res) {
05510             if (vms->oldmessages == 1)
05511                res = ast_play_and_wait(chan, "vm-message");
05512             else
05513                res = ast_play_and_wait(chan, "vm-messages");
05514          }
05515       }
05516       if (!res) {
05517          if (!vms->oldmessages && !vms->newmessages) {
05518             res = ast_play_and_wait(chan, "vm-no");
05519             if (!res)
05520                res = ast_play_and_wait(chan, "vm-messages");
05521          }
05522       }
05523    }
05524    return res;
05525 }

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

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

05060 {
05061    int res = 0;
05062 
05063    if (vms->newmessages) {
05064       res = ast_play_and_wait(chan, "vm-youhave");
05065       if (!res) 
05066          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05067       if (!res) {
05068          if ((vms->newmessages == 1)) {
05069             res = ast_play_and_wait(chan, "vm-INBOX");
05070             if (!res)
05071                res = ast_play_and_wait(chan, "vm-message");
05072          } else {
05073             res = ast_play_and_wait(chan, "vm-INBOXs");
05074             if (!res)
05075                res = ast_play_and_wait(chan, "vm-messages");
05076          }
05077       }
05078    } else if (vms->oldmessages){
05079       res = ast_play_and_wait(chan, "vm-youhave");
05080       if (!res)
05081          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05082       if ((vms->oldmessages == 1)){
05083          res = ast_play_and_wait(chan, "vm-Old");
05084          if (!res)
05085             res = ast_play_and_wait(chan, "vm-message");
05086       } else {
05087          res = ast_play_and_wait(chan, "vm-Olds");
05088          if (!res)
05089             res = ast_play_and_wait(chan, "vm-messages");
05090       }
05091    } else if (!vms->oldmessages && !vms->newmessages) 
05092       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05093    return res;
05094 }

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

Definition at line 5141 of file app_voicemail.c.

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

Referenced by vm_intro().

05142 {
05143    /* Introduce messages they have */
05144    int res;
05145    if (!vms->oldmessages && !vms->newmessages)
05146       res = ast_play_and_wait(chan, "vm-no") ||
05147          ast_play_and_wait(chan, "vm-message");
05148    else
05149       res = ast_play_and_wait(chan, "vm-youhave");
05150    if (!res && vms->newmessages) {
05151       res = (vms->newmessages == 1) ?
05152          ast_play_and_wait(chan, "digits/un") ||
05153          ast_play_and_wait(chan, "vm-nuovo") ||
05154          ast_play_and_wait(chan, "vm-message") :
05155          /* 2 or more new messages */
05156          say_and_wait(chan, vms->newmessages, chan->language) ||
05157          ast_play_and_wait(chan, "vm-nuovi") ||
05158          ast_play_and_wait(chan, "vm-messages");
05159       if (!res && vms->oldmessages)
05160          res = ast_play_and_wait(chan, "vm-and");
05161    }
05162    if (!res && vms->oldmessages) {
05163       res = (vms->oldmessages == 1) ?
05164          ast_play_and_wait(chan, "digits/un") ||
05165          ast_play_and_wait(chan, "vm-vecchio") ||
05166          ast_play_and_wait(chan, "vm-message") :
05167          /* 2 or more old messages */
05168          say_and_wait(chan, vms->oldmessages, chan->language) ||
05169          ast_play_and_wait(chan, "vm-vecchi") ||
05170          ast_play_and_wait(chan, "vm-messages");
05171    }
05172    return res ? -1 : 0;
05173 }

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

Definition at line 5528 of file app_voicemail.c.

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

Referenced by vm_intro().

05529 {
05530    /* Introduce messages they have */
05531    int res;
05532    res = ast_play_and_wait(chan, "vm-youhave");
05533    if (!res) {
05534       if (vms->newmessages) {
05535          res = say_and_wait(chan, vms->newmessages, chan->language);
05536          if (!res) {
05537             if (vms->newmessages == 1)
05538                res = ast_play_and_wait(chan, "vm-INBOXs");
05539             else
05540                res = ast_play_and_wait(chan, "vm-INBOX");
05541          }
05542          if (vms->oldmessages && !res)
05543             res = ast_play_and_wait(chan, "vm-and");
05544          else if (!res) {
05545             if ((vms->newmessages == 1))
05546                res = ast_play_and_wait(chan, "vm-message");
05547             else
05548                res = ast_play_and_wait(chan, "vm-messages");
05549          }
05550             
05551       }
05552       if (!res && vms->oldmessages) {
05553          res = say_and_wait(chan, vms->oldmessages, chan->language);
05554          if (!res) {
05555             if (vms->oldmessages == 1)
05556                res = ast_play_and_wait(chan, "vm-Olds");
05557             else
05558                res = ast_play_and_wait(chan, "vm-Old");
05559          }
05560          if (!res) {
05561             if (vms->oldmessages == 1)
05562                res = ast_play_and_wait(chan, "vm-message");
05563             else
05564                res = ast_play_and_wait(chan, "vm-messages");
05565          }
05566       }
05567       if (!res) {
05568          if (!vms->oldmessages && !vms->newmessages) {
05569             res = ast_play_and_wait(chan, "vm-no");
05570             if (!res)
05571                res = ast_play_and_wait(chan, "vm-messages");
05572          }
05573       }
05574    }
05575    return res;
05576 }

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

Definition at line 5291 of file app_voicemail.c.

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

Referenced by vm_intro().

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

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

Definition at line 5176 of file app_voicemail.c.

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

Referenced by vm_intro().

05177 {
05178    /* Introduce messages they have */
05179    int res;
05180    div_t num;
05181 
05182    if (!vms->oldmessages && !vms->newmessages) {
05183       res = ast_play_and_wait(chan, "vm-no");
05184       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05185       return res;
05186    } else {
05187       res = ast_play_and_wait(chan, "vm-youhave");
05188    }
05189 
05190    if (vms->newmessages) {
05191       num = div(vms->newmessages, 10);
05192       if (vms->newmessages == 1) {
05193          res = ast_play_and_wait(chan, "digits/1-a");
05194          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
05195          res = res ? res : ast_play_and_wait(chan, "vm-message");
05196       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05197          if (num.rem == 2) {
05198             if (!num.quot) {
05199                res = ast_play_and_wait(chan, "digits/2-ie");
05200             } else {
05201                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
05202                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05203             }
05204          } else {
05205             res = say_and_wait(chan, vms->newmessages, chan->language);
05206          }
05207          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
05208          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05209       } else {
05210          res = say_and_wait(chan, vms->newmessages, chan->language);
05211          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
05212          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05213       }
05214       if (!res && vms->oldmessages)
05215          res = ast_play_and_wait(chan, "vm-and");
05216    }
05217    if (!res && vms->oldmessages) {
05218       num = div(vms->oldmessages, 10);
05219       if (vms->oldmessages == 1) {
05220          res = ast_play_and_wait(chan, "digits/1-a");
05221          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
05222          res = res ? res : ast_play_and_wait(chan, "vm-message");
05223       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05224          if (num.rem == 2) {
05225             if (!num.quot) {
05226                res = ast_play_and_wait(chan, "digits/2-ie");
05227             } else {
05228                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
05229                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05230             }
05231          } else {
05232             res = say_and_wait(chan, vms->oldmessages, chan->language);
05233          }
05234          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
05235          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05236       } else {
05237          res = say_and_wait(chan, vms->oldmessages, chan->language);
05238          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
05239          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05240       }
05241    }
05242 
05243    return res;
05244 }

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

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

05580 {
05581    /* Introduce messages they have */
05582    int res;
05583    res = ast_play_and_wait(chan, "vm-youhave");
05584    if (!res) {
05585       if (vms->newmessages) {
05586          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05587          if (!res) {
05588             if ((vms->newmessages == 1)) {
05589                res = ast_play_and_wait(chan, "vm-message");
05590                if (!res)
05591                   res = ast_play_and_wait(chan, "vm-INBOXs");
05592             } else {
05593                res = ast_play_and_wait(chan, "vm-messages");
05594                if (!res)
05595                   res = ast_play_and_wait(chan, "vm-INBOX");
05596             }
05597          }
05598          if (vms->oldmessages && !res)
05599             res = ast_play_and_wait(chan, "vm-and");
05600       }
05601       if (!res && vms->oldmessages) {
05602          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05603          if (!res) {
05604             if (vms->oldmessages == 1) {
05605                res = ast_play_and_wait(chan, "vm-message");
05606                if (!res)
05607                   res = ast_play_and_wait(chan, "vm-Olds");
05608             } else {
05609                res = ast_play_and_wait(chan, "vm-messages");
05610                if (!res)
05611                   res = ast_play_and_wait(chan, "vm-Old");
05612             }
05613          }
05614       }
05615       if (!res) {
05616          if (!vms->oldmessages && !vms->newmessages) {
05617             res = ast_play_and_wait(chan, "vm-no");
05618             if (!res)
05619                res = ast_play_and_wait(chan, "vm-messages");
05620          }
05621       }
05622    }
05623    return res;
05624 }

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

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

05437                                                                          {
05438    /* Introduce messages they have */
05439    int res;
05440    if (!vms->oldmessages && !vms->newmessages) {
05441       res = ast_play_and_wait(chan, "vm-nomessages");
05442       return res;
05443    }
05444    else {
05445       res = ast_play_and_wait(chan, "vm-youhave");
05446    }
05447    if (vms->newmessages) {
05448       if (!res)
05449          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
05450       if ((vms->newmessages == 1)) {
05451          if (!res)
05452             res = ast_play_and_wait(chan, "vm-message");
05453          if (!res)
05454             res = ast_play_and_wait(chan, "vm-INBOXs");
05455       }
05456       else {
05457          if (!res)
05458             res = ast_play_and_wait(chan, "vm-messages");
05459          if (!res)
05460             res = ast_play_and_wait(chan, "vm-INBOX");
05461       }
05462       if (vms->oldmessages && !res)
05463          res = ast_play_and_wait(chan, "vm-and");
05464    }
05465    if (vms->oldmessages) {
05466       if (!res)
05467          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
05468       if (vms->oldmessages == 1) {
05469          if (!res)
05470             res = ast_play_and_wait(chan, "vm-message");
05471          if (!res)
05472             res = ast_play_and_wait(chan, "vm-Olds");
05473       }
05474       else {
05475          if (!res)
05476       res = ast_play_and_wait(chan, "vm-messages");
05477          if (!res)
05478             res = ast_play_and_wait(chan, "vm-Old");
05479       }
05480    }
05481    return res;
05482 }

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

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

05709 {
05710    int res;
05711    int lastnum = 0;
05712    int dcnum;
05713 
05714    res = ast_play_and_wait(chan, "vm-youhave");
05715    if (!res && vms->newmessages) {
05716       lastnum = get_lastdigits(vms->newmessages);
05717       dcnum = vms->newmessages - lastnum;
05718       if (dcnum)
05719          res = say_and_wait(chan, dcnum, chan->language);
05720       if (!res && lastnum) {
05721          if (lastnum == 1) 
05722             res = ast_play_and_wait(chan, "digits/ru/odno");
05723          else
05724             res = say_and_wait(chan, lastnum, chan->language);
05725       }
05726 
05727       if (!res)
05728          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-novoe" : "vm-novyh");
05729 
05730       if (!res && vms->oldmessages)
05731          res = ast_play_and_wait(chan, "vm-and");
05732    }
05733 
05734    if (!res && vms->oldmessages) {
05735       lastnum = get_lastdigits(vms->oldmessages);
05736       dcnum = vms->oldmessages - lastnum;
05737       if (dcnum)
05738          res = say_and_wait(chan, dcnum, chan->language);
05739       if (!res && lastnum) {
05740          if (lastnum == 1) 
05741             res = ast_play_and_wait(chan, "digits/ru/odno");
05742          else
05743             res = say_and_wait(chan, lastnum, chan->language);
05744       }
05745 
05746       if (!res)
05747          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-staroe" : "vm-staryh");
05748    }
05749 
05750    if (!res && !vms->newmessages && !vms->oldmessages) {
05751       lastnum = 0;
05752       res = ast_play_and_wait(chan, "vm-no");
05753    }
05754 
05755    if (!res) {
05756       switch (lastnum) {
05757       case 1:
05758          res = ast_play_and_wait(chan, "vm-soobshenie");
05759          break;
05760       case 2:
05761       case 3:
05762       case 4:
05763          res = ast_play_and_wait(chan, "vm-soobsheniya");
05764          break;
05765       default:
05766          res = ast_play_and_wait(chan, "vm-soobsheniy");
05767          break;
05768       }
05769    }
05770 
05771    return res;
05772 }

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

Definition at line 5247 of file app_voicemail.c.

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

Referenced by vm_intro().

05248 {
05249    /* Introduce messages they have */
05250    int res;
05251 
05252    res = ast_play_and_wait(chan, "vm-youhave");
05253    if (res)
05254       return res;
05255 
05256    if (!vms->oldmessages && !vms->newmessages) {
05257       res = ast_play_and_wait(chan, "vm-no");
05258       res = res ? res : ast_play_and_wait(chan, "vm-messages");
05259       return res;
05260    }
05261 
05262    if (vms->newmessages) {
05263       if ((vms->newmessages == 1)) {
05264          res = ast_play_and_wait(chan, "digits/ett");
05265          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
05266          res = res ? res : ast_play_and_wait(chan, "vm-message");
05267       } else {
05268          res = say_and_wait(chan, vms->newmessages, chan->language);
05269          res = res ? res : ast_play_and_wait(chan, "vm-nya");
05270          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05271       }
05272       if (!res && vms->oldmessages)
05273          res = ast_play_and_wait(chan, "vm-and");
05274    }
05275    if (!res && vms->oldmessages) {
05276       if (vms->oldmessages == 1) {
05277          res = ast_play_and_wait(chan, "digits/ett");
05278          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
05279          res = res ? res : ast_play_and_wait(chan, "vm-message");
05280       } else {
05281          res = say_and_wait(chan, vms->oldmessages, chan->language);
05282          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
05283          res = res ? res : ast_play_and_wait(chan, "vm-messages");
05284       }
05285    }
05286 
05287    return res;
05288 }

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

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

05783 {
05784    int res;
05785    int lastnum = 0;
05786    int dcnum;
05787 
05788    res = ast_play_and_wait(chan, "vm-youhave");
05789    if (!res && vms->newmessages) {
05790       lastnum = get_lastdigits(vms->newmessages);
05791       dcnum = vms->newmessages - lastnum;
05792       if (dcnum)
05793          res = say_and_wait(chan, dcnum, chan->language);
05794       if (!res && lastnum) {
05795          if (lastnum == 1) 
05796             res = ast_play_and_wait(chan, "digits/ua/1e");
05797          else
05798             res = say_and_wait(chan, lastnum, chan->language);
05799       }
05800 
05801       if (!res)
05802          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-nove" : "vm-INBOX");
05803 
05804       if (!res && vms->oldmessages)
05805          res = ast_play_and_wait(chan, "vm-and");
05806    }
05807 
05808    if (!res && vms->oldmessages) {
05809       lastnum = get_lastdigits(vms->oldmessages);
05810       dcnum = vms->oldmessages - lastnum;
05811       if (dcnum)
05812          res = say_and_wait(chan, dcnum, chan->language);
05813       if (!res && lastnum) {
05814          if (lastnum == 1) 
05815             res = ast_play_and_wait(chan, "digits/ua/1e");
05816          else
05817             res = say_and_wait(chan, lastnum, chan->language);
05818       }
05819 
05820       if (!res)
05821          res = ast_play_and_wait(chan, (lastnum == 1) ? "vm-stare" : "vm-Old");
05822    }
05823 
05824    if (!res && !vms->newmessages && !vms->oldmessages) {
05825       lastnum = 0;
05826       res = ast_play_and_wait(chan, "vm-no");
05827    }
05828 
05829    if (!res) {
05830       switch (lastnum) {
05831       case 1:
05832       case 2:
05833       case 3:
05834       case 4:
05835          res = ast_play_and_wait(chan, "vm-message");
05836          break;
05837       default:
05838          res = ast_play_and_wait(chan, "vm-messages");
05839          break;
05840       }
05841    }
05842 
05843    return res;
05844 }

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

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

00959 {
00960    switch (ast_lock_path(path)) {
00961    case AST_LOCK_TIMEOUT:
00962       return -1;
00963    default:
00964       return 0;
00965    }
00966 }

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

Definition at line 1769 of file app_voicemail.c.

References my_umask, and VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

01770 {
01771    FILE *p = NULL;
01772    int pfd = mkstemp(template);
01773    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
01774    if (pfd > -1) {
01775       p = fdopen(pfd, "w+");
01776       if (!p) {
01777          close(pfd);
01778          pfd = -1;
01779       }
01780    }
01781    return p;
01782 }

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

05940 {
05941    int cmd = 0;
05942    int duration = 0;
05943    int tries = 0;
05944    char newpassword[80] = "";
05945    char newpassword2[80] = "";
05946    char prefile[PATH_MAX] = "";
05947    unsigned char buf[256];
05948    int bytes=0;
05949 
05950    if (ast_adsi_available(chan)) {
05951       bytes += adsi_logo(buf + bytes);
05952       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
05953       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
05954       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05955       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05956       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05957    }
05958 
05959    /* First, have the user change their password 
05960       so they won't get here again */
05961    for (;;) {
05962       newpassword[1] = '\0';
05963       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
05964       if (cmd == '#')
05965          newpassword[0] = '\0';
05966       if (cmd < 0 || cmd == 't' || cmd == '#')
05967          return cmd;
05968       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
05969       if (cmd < 0 || cmd == 't' || cmd == '#')
05970          return cmd;
05971       newpassword2[1] = '\0';
05972       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
05973       if (cmd == '#')
05974          newpassword2[0] = '\0';
05975       if (cmd < 0 || cmd == 't' || cmd == '#')
05976          return cmd;
05977       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
05978       if (cmd < 0 || cmd == 't' || cmd == '#')
05979          return cmd;
05980       if (!strcmp(newpassword, newpassword2))
05981          break;
05982       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
05983       cmd = ast_play_and_wait(chan, "vm-mismatch");
05984       if (++tries == 3)
05985          return -1;
05986    }
05987    if (ast_strlen_zero(ext_pass_cmd)) 
05988       vm_change_password(vmu,newpassword);
05989    else 
05990       vm_change_password_shell(vmu,newpassword);
05991    if (option_debug > 2)
05992       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
05993    cmd = ast_play_and_wait(chan,"vm-passchanged");
05994 
05995    /* If forcename is set, have the user record their name */  
05996    if (ast_test_flag(vmu, VM_FORCENAME)) {
05997       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
05998       if (ast_fileexists(prefile, NULL, NULL) < 1) {
05999 #ifndef IMAP_STORAGE
06000          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06001 #else
06002          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06003 #endif
06004          if (cmd < 0 || cmd == 't' || cmd == '#')
06005             return cmd;
06006       }
06007    }
06008 
06009    /* If forcegreetings is set, have the user record their greetings */
06010    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06011       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06012       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06013 #ifndef IMAP_STORAGE
06014          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06015 #else
06016          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06017 #endif
06018          if (cmd < 0 || cmd == 't' || cmd == '#')
06019             return cmd;
06020       }
06021 
06022       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06023       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06024 #ifndef IMAP_STORAGE
06025          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06026 #else
06027          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06028 #endif
06029          if (cmd < 0 || cmd == 't' || cmd == '#')
06030             return cmd;
06031       }
06032    }
06033 
06034    return cmd;
06035 }

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

06038 {
06039    int cmd = 0;
06040    int retries = 0;
06041    int duration = 0;
06042    char newpassword[80] = "";
06043    char newpassword2[80] = "";
06044    char prefile[PATH_MAX] = "";
06045    unsigned char buf[256];
06046    int bytes=0;
06047 
06048    if (ast_adsi_available(chan))
06049    {
06050       bytes += adsi_logo(buf + bytes);
06051       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06052       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06053       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06054       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06055       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06056    }
06057    while ((cmd >= 0) && (cmd != 't')) {
06058       if (cmd)
06059          retries = 0;
06060       switch (cmd) {
06061       case '1':
06062          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06063 #ifndef IMAP_STORAGE
06064          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06065 #else
06066          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06067 #endif
06068          break;
06069       case '2': 
06070          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06071 #ifndef IMAP_STORAGE
06072          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06073 #else
06074          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06075 #endif
06076          break;
06077       case '3': 
06078          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06079 #ifndef IMAP_STORAGE
06080          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06081 #else
06082          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06083 #endif
06084          break;
06085       case '4': 
06086          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06087          break;
06088       case '5':
06089          if (vmu->password[0] == '-') {
06090             cmd = ast_play_and_wait(chan, "vm-no");
06091             break;
06092          }
06093          newpassword[1] = '\0';
06094          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06095          if (cmd == '#')
06096             newpassword[0] = '\0';
06097          else {
06098             if (cmd < 0)
06099                break;
06100             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06101                break;
06102             }
06103          }
06104          newpassword2[1] = '\0';
06105          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06106          if (cmd == '#')
06107             newpassword2[0] = '\0';
06108          else {
06109             if (cmd < 0)
06110                break;
06111 
06112             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#"))) {
06113                break;
06114             }
06115          }
06116          if (strcmp(newpassword, newpassword2)) {
06117             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06118             cmd = ast_play_and_wait(chan, "vm-mismatch");
06119             break;
06120          }
06121          if (ast_strlen_zero(ext_pass_cmd)) 
06122             vm_change_password(vmu,newpassword);
06123          else 
06124             vm_change_password_shell(vmu,newpassword);
06125          if (option_debug > 2)
06126             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06127          cmd = ast_play_and_wait(chan,"vm-passchanged");
06128          break;
06129       case '*': 
06130          cmd = 't';
06131          break;
06132       default: 
06133          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06134          if (ast_fileexists(prefile, NULL, NULL))
06135             cmd = ast_play_and_wait(chan, "vm-tmpexists");
06136          if (!cmd)
06137             cmd = ast_play_and_wait(chan, "vm-options");
06138          if (!cmd)
06139             cmd = ast_waitfordigit(chan,6000);
06140          if (!cmd)
06141             retries++;
06142          if (retries > 3)
06143             cmd = 't';
06144       }
06145    }
06146    if (cmd == 't')
06147       cmd = 0;
06148    return cmd;
06149 }

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

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

05029 {
05030    int cmd;
05031 
05032    if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
05033       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05034       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05035    } else if (!strcasecmp(chan->language, "gr")){
05036       return vm_play_folder_name_gr(chan, mbox);
05037    } else if (!strcasecmp(chan->language, "pl")){
05038       return vm_play_folder_name_pl(chan, mbox);
05039    } else if (!strcasecmp(chan->language, "ua")){  /* Ukrainian syntax */
05040       return vm_play_folder_name_ua(chan, mbox);
05041    } else {  /* Default English */
05042       cmd = ast_play_and_wait(chan, mbox);
05043       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05044    }
05045 }

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

Definition at line 4981 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

04982 {
04983    int cmd;
04984    char *buf;
04985 
04986    buf = alloca(strlen(mbox)+2); 
04987    strcpy(buf, mbox);
04988    strcat(buf,"s");
04989 
04990    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
04991       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
04992       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04993    } else {
04994       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
04995       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
04996    }
04997 }

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

Definition at line 4999 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05000 {
05001    int cmd;
05002 
05003    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05004       if (!strcasecmp(mbox, "vm-INBOX"))
05005          cmd = ast_play_and_wait(chan, "vm-new-e");
05006       else
05007          cmd = ast_play_and_wait(chan, "vm-old-e");
05008       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05009    } else {
05010       cmd = ast_play_and_wait(chan, "vm-messages");
05011       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05012    }
05013 }

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

Definition at line 5015 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05016 {
05017    int cmd;
05018 
05019    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05020       cmd = ast_play_and_wait(chan, "vm-messages");
05021       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05022    } else {
05023       cmd = ast_play_and_wait(chan, mbox);
05024       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05025    }
05026 }

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

06152 {
06153    int res;
06154    int cmd = 0;
06155    int retries = 0;
06156    int duration = 0;
06157    char prefile[PATH_MAX] = "";
06158    unsigned char buf[256];
06159    char dest[PATH_MAX];
06160    int bytes = 0;
06161 
06162    if (ast_adsi_available(chan)) {
06163       bytes += adsi_logo(buf + bytes);
06164       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
06165       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06166       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06167       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06168       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06169    }
06170 
06171    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06172    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
06173       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
06174       return -1;
06175    }
06176    while ((cmd >= 0) && (cmd != 't')) {
06177       if (cmd)
06178          retries = 0;
06179       RETRIEVE(prefile, -1);
06180       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
06181 #ifndef IMAP_STORAGE
06182          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06183 #else
06184          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06185 #endif
06186          cmd = 't';  
06187       } else {
06188          switch (cmd) {
06189          case '1':
06190 #ifndef IMAP_STORAGE
06191             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, NULL);
06192 #else
06193             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06194 #endif
06195             break;
06196          case '2':
06197             DELETE(prefile, -1, prefile);
06198             ast_play_and_wait(chan, "vm-tempremoved");
06199             cmd = 't';  
06200             break;
06201          case '*': 
06202             cmd = 't';
06203             break;
06204          default:
06205             cmd = ast_play_and_wait(chan,
06206                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
06207                   "vm-tempgreeting2" : "vm-tempgreeting");
06208             if (!cmd)
06209                cmd = ast_waitfordigit(chan,6000);
06210             if (!cmd)
06211                retries++;
06212             if (retries > 3)
06213                cmd = 't';
06214          }
06215       }
06216       DISPOSE(prefile, -1);
06217    }
06218    if (cmd == 't')
06219       cmd = 0;
06220    return cmd;
06221 }

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

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

07203 {
07204    struct ast_module_user *u;
07205    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
07206    struct ast_vm_user vmus;
07207    char *options = NULL;
07208    int silent = 0, skipuser = 0;
07209    int res = -1;
07210 
07211    u = ast_module_user_add(chan);
07212    
07213    if (s) {
07214       s = ast_strdupa(s);
07215       user = strsep(&s, "|");
07216       options = strsep(&s, "|");
07217       if (user) {
07218          s = user;
07219          user = strsep(&s, "@");
07220          context = strsep(&s, "");
07221          if (!ast_strlen_zero(user))
07222             skipuser++;
07223          ast_copy_string(mailbox, user, sizeof(mailbox));
07224       }
07225    }
07226 
07227    if (options) {
07228       silent = (strchr(options, 's')) != NULL;
07229    }
07230 
07231    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
07232       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
07233       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
07234       ast_play_and_wait(chan, "auth-thankyou");
07235       res = 0;
07236    }
07237 
07238    ast_module_user_remove(u);
07239    return res;
07240 }

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

Definition at line 1749 of file app_voicemail.c.

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

Referenced by make_email_file(), and sendpage().

01750 {
01751    const struct vm_zone *z = NULL;
01752    time_t t = time(NULL);
01753 
01754    /* Does this user have a timezone specified? */
01755    if (!ast_strlen_zero(vmu->zonetag)) {
01756       /* Find the zone in the list */
01757       AST_LIST_LOCK(&zones);
01758       AST_LIST_TRAVERSE(&zones, z, list) {
01759          if (!strcmp(z->name, vmu->zonetag))
01760             break;
01761       }
01762       AST_LIST_UNLOCK(&zones);
01763    }
01764    ast_localtime(&t, tm, z ? z->timezone : NULL);
01765    return tm;
01766 }

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

Definition at line 4276 of file app_voicemail.c.

References ast_control_streamfile(), and skipms.

04277 {
04278    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
04279 }

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

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

04269 {
04270    int res;
04271    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
04272       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
04273    return res;
04274 }


Variable Documentation

char* addesc = "Comedian Mail" [static]

Definition at line 448 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 7344 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 7349 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 7354 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 453 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 434 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 436 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 450 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 446 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 432 of file app_voicemail.c.

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

char vmfmts[80] [static]

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

double volgain [static]

Definition at line 541 of file app_voicemail.c.

Referenced by load_config().


Generated on Mon Mar 31 07:38:54 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1