Thu Jul 9 13:40:50 2009

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.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 "asterisk/event.h"

Go to the source code of this file.

Data Structures

struct  ast_vm_user
struct  baseio
struct  leave_vm_options
 Options for leaving voicemail with the voicemail() application. More...
struct  mwi_sub
 An MWI subscription. More...
struct  mwi_subs
struct  users
 list of users found in the config file More...
struct  vm_state
struct  vm_zone
struct  zones

Defines

#define ASTERISK_USERNAME   "asterisk"
#define BASELINELEN   72
#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 DEFAULT_LISTEN_CONTROL_FORWARD_KEY   "#"
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY   "0"
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY   "2"
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY   "*"
#define DEFAULT_LISTEN_CONTROL_STOP_KEY   "13456789"
#define DEFAULT_POLL_FREQ   30
#define DELETE(a, b, c, d)   (vm_delete(c))
#define DISPOSE(a, b)
#define ENDL   "\n"
#define eol   "\r\n"
#define ERROR_LOCK_PATH   -100
#define ERROR_MAILBOX_FULL   -200
#define EXISTS(a, b, c, d)   (ast_fileexists(c, NULL, d) > 0)
#define HVSU_OUTPUT_FORMAT   "%-10s %-5s %-25s %-10s %6s\n"
#define HVSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"
#define INTRO   "vm-intro"
#define MAX_DATETIME_FORMAT   512
#define MAX_NUM_CID_CONTEXTS   10
#define MAXMSG   100
#define MAXMSGLIMIT   9999
#define PWDCHANGE_EXTERNAL   (1 << 2)
#define PWDCHANGE_INTERNAL   (1 << 1)
#define RENAME(a, b, c, d, e, f, g, h)   (rename_file(g,h));
#define RETRIEVE(a, b, c, d)
#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 VALID_DTMF   "1234567890*#"
#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_MOVEHEARD   (1 << 16)
#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  {
  NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER,
  FRIENDS_FOLDER, GREETINGS_FOLDER
}
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_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7)
}
enum  { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 }

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
static void __reg_module (void)
static void __unreg_module (void)
static int acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len)
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 (const char *context, const char *mbox, const char *data)
static void apply_option (struct ast_vm_user *vmu, const char *var, const char *value)
static void apply_options (struct ast_vm_user *vmu, const char *options)
static void apply_options_full (struct ast_vm_user *retval, struct ast_variable *var)
static int base_encode (char *filename, FILE *so)
static int change_password_realtime (struct ast_vm_user *vmu, const char *password)
static int check_mime (const char *str)
 Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.
static int close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu)
static char * complete_voicemail_show_users (const char *line, const char *word, int pos, int state)
static int copy (char *infile, char *outfile)
static int copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir)
static void copy_plain_file (char *frompath, char *topath)
static int count_messages (struct ast_vm_user *vmu, char *dir)
static int create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder)
 basically mkdir -p $dest/$context/$ext/$folder
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static char * encode_mime_str (const char *start, char *end, size_t endsize, size_t preamble, size_t postamble)
 Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.
static struct ast_vm_userfind_or_create (const char *context, const char *mbox)
static struct ast_vm_userfind_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static struct ast_vm_userfind_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox)
static int forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain)
static void free_user (struct ast_vm_user *vmu)
static void free_vm_users (void)
 Free the users structure.
static void free_vm_zones (void)
 Free the zones structure.
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)
 get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized
static int get_folder2 (struct ast_channel *chan, char *fn, int start)
static char * handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Reload voicemail configuration from the CLI.
static char * handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show a list of voicemail users in the CLI.
static char * handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show a list of voicemail zones in the CLI.
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 is_valid_dtmf (const char *key)
static int last_message_index (struct ast_vm_user *vmu, char *dir)
 A negative return value indicates an error.
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
static int load_config (int reload)
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, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap)
 Creates the email file to be sent to indicate a new voicemail exists for a user.
static int make_file (char *dest, const int len, const char *dir, const int num)
 Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
static int manager_list_voicemail_users (struct mansession *s, const struct message *m)
 Manager list voicemail users command.
static void * mb_poll_thread (void *data)
static const char * mbox (int id)
static int messagecount (const char *context, const char *mailbox, const char *folder)
static void mwi_sub_destroy (struct mwi_sub *mwi_sub)
static void mwi_sub_event_cb (const struct ast_event *event, void *userdata)
static void mwi_unsub_event_cb (const struct ast_event *event, void *userdata)
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname)
static 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 poll_subscribed_mailboxes (void)
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, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, char *passdata, size_t passdatasize, const char *category)
static void queue_mwi_event (const char *mbox, int new, int old)
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, const char *fromfolder, 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, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category)
static char * show_users_realtime (int fd, const char *context)
static void start_poll_thread (void)
static void stop_poll_thread (void)
static char * strip_control (const char *input, char *buf, size_t buflen)
static char * substitute_escapes (const char *value)
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 int vm_browse_messages_tw (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)
 Removes the voicemail sound and information 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_instructions_en (struct ast_channel *chan, struct vm_state *vms, int skipadvanced)
static int vm_instructions_tw (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_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
static int vm_intro_nl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_no (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pl (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_se (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_tw (struct ast_channel *chan, struct vm_state *vms)
static int vm_lock_path (const char *path)
 Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason.
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 ast_tmvmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm)
 fill in *tm for current time according to the proper timezone, if any. Return tm so it can be used as a function argument.
static int wait_file (struct ast_channel *chan, struct vm_state *vms, char *file)
static int wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, .reload = reload, }
static char * addesc = "Comedian Mail"
static unsigned char adsifdn [4] = "\x00\x00\x00\x0F"
static unsigned char adsisec [4] = "\x9B\xDB\xF7\xAC"
static int adsiver = 1
static char * app = "VoiceMail"
static char * app2 = "VoiceMailMain"
static char * app3 = "MailboxExists"
static char * app4 = "VMAuthenticate"
static const struct ast_module_infoast_module_info = &__mod_info
static char callcontext [AST_MAX_CONTEXT] = ""
static char charset [32] = "ISO-8859-1"
static char cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64]
static struct ast_cli_entry cli_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 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 listen_control_forward_key [12]
static char listen_control_pause_key [12]
static char listen_control_restart_key [12]
static char listen_control_reverse_key [12]
static char listen_control_stop_key [12]
static struct ast_custom_function mailbox_exists_acf
static char mailcmd [160]
static int maxdeletedmsg
static int maxgreet
static int maxlogins
static int maxmsg
static int maxsilence
static struct ast_event_submwi_sub_sub
static struct ast_event_submwi_unsub_sub
static int my_umask
static char * pagerbody = NULL
static char pagerfromstring [100]
static char * pagersubject = NULL
static ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER
static unsigned int poll_freq
static ast_mutex_t poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static unsigned int poll_mailboxes
static pthread_t poll_thread = AST_PTHREADT_NULL
static unsigned char poll_thread_run
static int pwdchange = PWDCHANGE_INTERNAL
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 = "Leave a Voicemail message"
static char * synopsis_vm_box_exists
static char * synopsis_vmain = "Check Voicemail messages"
static char * synopsis_vmauthenticate = "Authenticate with Voicemail passwords"
static char userscontext [AST_MAX_EXTENSION] = "default"
static struct ast_app_option vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 },}
enum { ... }  vm_box
static char vm_mismatch [80] = "vm-mismatch"
static char vm_newpassword [80] = "vm-newpassword"
enum { ... }  vm_option_args
enum { ... }  vm_option_flags
static char vm_passchanged [80] = "vm-passchanged"
static char vm_password [80] = "vm-password"
static char vm_reenterpassword [80] = "vm-reenterpassword"
static char VM_SPOOL_DIR [PATH_MAX]
static char vmfmts [80]
static int vmmaxsecs
static int vmminsecs
static double volgain
static char zonetag [80]


Detailed Description

Comedian Mail - Voicemail System.

Author:
Mark Spencer <markster@digium.com>
ExtRef:
Unixodbc - http://www.unixodbc.org
ExtRef:
A source distribution of University of Washington's IMAP c-client (http://www.washington.edu/imap/
See also
Note:
For information about voicemail IMAP storage, read doc/imapstorage.txt

This module requires res_adsi to load. This needs to be optional during compilation.

This file is now almost impossible to work with, due to all #ifdefs. Feels like the database code before realtime. Someone - please come up with a plan to clean this up.

Definition in file app_voicemail.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 188 of file app_voicemail.c.

#define BASELINELEN   72

Definition at line 209 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 210 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 185 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 181 of file app_voicemail.c.

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

Definition at line 462 of file app_voicemail.c.

Referenced by copy_message(), and save_to_folder().

#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY   "#"

Definition at line 193 of file app_voicemail.c.

Referenced by load_config().

#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY   "0"

Definition at line 195 of file app_voicemail.c.

Referenced by load_config().

#define DEFAULT_LISTEN_CONTROL_RESTART_KEY   "2"

Definition at line 196 of file app_voicemail.c.

Referenced by load_config().

#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY   "*"

Definition at line 194 of file app_voicemail.c.

Referenced by load_config().

#define DEFAULT_LISTEN_CONTROL_STOP_KEY   "13456789"

Definition at line 197 of file app_voicemail.c.

Referenced by load_config().

#define DEFAULT_POLL_FREQ   30

By default, poll every 30 seconds

Definition at line 595 of file app_voicemail.c.

Referenced by load_config().

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

Definition at line 463 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 458 of file app_voicemail.c.

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

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 211 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 233 of file app_voicemail.c.

#define ERROR_MAILBOX_FULL   -200

Definition at line 234 of file app_voicemail.c.

Referenced by close_mailbox(), and save_to_folder().

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

Definition at line 460 of file app_voicemail.c.

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

#define HVSU_OUTPUT_FORMAT   "%-10s %-5s %-25s %-10s %6s\n"

Referenced by handle_voicemail_show_users().

#define HVSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"

Referenced by handle_voicemail_show_zones().

#define INTRO   "vm-intro"

Definition at line 204 of file app_voicemail.c.

Referenced by play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 213 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 214 of file app_voicemail.c.

#define MAXMSG   100

Definition at line 206 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 207 of file app_voicemail.c.

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

#define PWDCHANGE_EXTERNAL   (1 << 2)

Definition at line 474 of file app_voicemail.c.

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

#define PWDCHANGE_INTERNAL   (1 << 1)

Definition at line 473 of file app_voicemail.c.

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

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

Definition at line 461 of file app_voicemail.c.

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

#define RETRIEVE ( a,
b,
c,
 ) 

Definition at line 457 of file app_voicemail.c.

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

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

Definition at line 202 of file app_voicemail.c.

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 179 of file app_voicemail.c.

Referenced by run_externnotify().

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

Definition at line 459 of file app_voicemail.c.

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

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 483 of file app_voicemail.c.

#define VALID_DTMF   "1234567890*#"

Definition at line 198 of file app_voicemail.c.

Referenced by is_valid_dtmf().

#define VM_ALLOCED   (1 << 13)

Definition at line 229 of file app_voicemail.c.

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

#define VM_ATTACH   (1 << 11)

Definition at line 227 of file app_voicemail.c.

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

#define VM_DELETE   (1 << 12)

Definition at line 228 of file app_voicemail.c.

Referenced by apply_option(), manager_list_voicemail_users(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 226 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 220 of file app_voicemail.c.

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

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

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

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

#define VM_MOVEHEARD   (1 << 16)

Move a "heard" message to Old after listening to it

Definition at line 232 of file app_voicemail.c.

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

#define VM_OPERATOR   (1 << 1)

Definition at line 217 of file app_voicemail.c.

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

#define VM_PBXSKIP   (1 << 9)

Definition at line 225 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 216 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 218 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 221 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

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

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

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

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 187 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 183 of file app_voicemail.c.

#define VOICEMAIL_FILE_MODE   0666

Definition at line 184 of file app_voicemail.c.

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


Enumeration Type Documentation

anonymous enum

Enumerator:
NEW_FOLDER 
OLD_FOLDER 
WORK_FOLDER 
FAMILY_FOLDER 
FRIENDS_FOLDER 
GREETINGS_FOLDER 

Definition at line 237 of file app_voicemail.c.

00237      {
00238    NEW_FOLDER,
00239    OLD_FOLDER,
00240    WORK_FOLDER,
00241    FAMILY_FOLDER,
00242    FRIENDS_FOLDER,
00243    GREETINGS_FOLDER
00244 } vm_box;

anonymous enum

Enumerator:
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_AUTOPLAY 
OPT_DTMFEXIT 

Definition at line 246 of file app_voicemail.c.

00246      {
00247    OPT_SILENT =           (1 << 0),
00248    OPT_BUSY_GREETING =    (1 << 1),
00249    OPT_UNAVAIL_GREETING = (1 << 2),
00250    OPT_RECORDGAIN =       (1 << 3),
00251    OPT_PREPEND_MAILBOX =  (1 << 4),
00252    OPT_AUTOPLAY =         (1 << 6),
00253    OPT_DTMFEXIT =         (1 << 7),
00254 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_DTMFEXIT 
OPT_ARG_ARRAY_SIZE 

Definition at line 256 of file app_voicemail.c.

00256      {
00257    OPT_ARG_RECORDGAIN = 0,
00258    OPT_ARG_PLAYFOLDER = 1,
00259    OPT_ARG_DTMFEXIT   = 2,
00260    /* This *must* be the last value in this enum! */
00261    OPT_ARG_ARRAY_SIZE = 3,
00262 } vm_option_args;


Function Documentation

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

Definition at line 4119 of file app_voicemail.c.

References ast_strlen_zero().

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

04120    {
04121       DIR *dir;
04122       struct dirent *de;
04123       char fn[256];
04124       int ret = 0;
04125 
04126       /* If no mailbox, return immediately */
04127       if (ast_strlen_zero(mailbox))
04128          return 0;
04129 
04130       if (ast_strlen_zero(folder))
04131          folder = "INBOX";
04132       if (ast_strlen_zero(context))
04133          context = "default";
04134 
04135       snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
04136 
04137       if (!(dir = opendir(fn)))
04138          return 0;
04139 
04140       while ((de = readdir(dir))) {
04141          if (!strncasecmp(de->d_name, "msg", 3)) {
04142             if (shortcircuit) {
04143                ret = 1;
04144                break;
04145             } else if (!strncasecmp(de->d_name + 8, "txt", 3))
04146                ret++;
04147          }
04148       }
04149 
04150       closedir(dir);
04151 
04152       return ret;
04153    }

static void __reg_module ( void   )  [static]

Definition at line 10218 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 10218 of file app_voicemail.c.

static int acf_mailbox_exists ( struct ast_channel chan,
const char *  cmd,
char *  args,
char *  buf,
size_t  len 
) [static]

Definition at line 8517 of file app_voicemail.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), find_user(), and LOG_ERROR.

08518 {
08519    struct ast_vm_user svm;
08520    AST_DECLARE_APP_ARGS(arg,
08521       AST_APP_ARG(mbox);
08522       AST_APP_ARG(context);
08523    );
08524 
08525    AST_NONSTANDARD_APP_ARGS(arg, args, '@');
08526 
08527    if (ast_strlen_zero(arg.mbox)) {
08528       ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n");
08529       return -1;
08530    }
08531 
08532    ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len);
08533    return 0;
08534 }

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

Definition at line 4963 of file app_voicemail.c.

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

Referenced by vm_authenticate(), and vm_execmain().

04964    {
04965       int x;
04966       if (!ast_adsi_available(chan))
04967          return;
04968       x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04969       if (x < 0)
04970          return;
04971       if (!x) {
04972          if (adsi_load_vmail(chan, useadsi)) {
04973             ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04974             return;
04975          }
04976       } else
04977          *useadsi = 1;
04978    }

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

Definition at line 5152 of file app_voicemail.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available, chan, and vm_state::curmsg.

Referenced by vm_execmain().

05153    {
05154       int bytes = 0;
05155       unsigned char buf[256];
05156       unsigned char keys[8];
05157 
05158       int x;
05159 
05160       if (!ast_adsi_available(chan))
05161          return;
05162 
05163       /* New meaning for keys */
05164       for (x = 0; x < 5; x++)
05165          keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
05166 
05167       keys[6] = 0x0;
05168       keys[7] = 0x0;
05169 
05170       if (!vms->curmsg) {
05171          /* No prev key, provide "Folder" instead */
05172          keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05173       }
05174       if (vms->curmsg >= vms->lastmsg) {
05175          /* If last message ... */
05176          if (vms->curmsg) {
05177             /* but not only message, provide "Folder" instead */
05178             keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05179          } else {
05180             /* Otherwise if only message, leave blank */
05181             keys[3] = 1;
05182          }
05183       }
05184 
05185       /* If deleted, show "undeleted" */
05186       if (vms->deleted[vms->curmsg]) 
05187          keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
05188 
05189       /* Except "Exit" */
05190       keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
05191       bytes += ast_adsi_set_keys(buf + bytes, keys);
05192       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05193 
05194       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05195    }

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

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

Referenced by vm_execmain().

05029    {
05030       unsigned char buf[256];
05031       int bytes = 0;
05032       unsigned char keys[8];
05033       int x, y;
05034 
05035       if (!ast_adsi_available(chan))
05036          return;
05037 
05038       for (x = 0; x < 5; x++) {
05039          y = ADSI_KEY_APPS + 12 + start + x;
05040          if (y > ADSI_KEY_APPS + 12 + 4)
05041             y = 0;
05042          keys[x] = ADSI_KEY_SKT | y;
05043       }
05044       keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
05045       keys[6] = 0;
05046       keys[7] = 0;
05047 
05048       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
05049       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
05050       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05051       bytes += ast_adsi_set_keys(buf + bytes, keys);
05052       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05053 
05054       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05055    }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 5300 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, ast_adsi_voice_mode, and chan.

Referenced by vm_execmain().

05301    {
05302       unsigned char buf[256];
05303       int bytes = 0;
05304 
05305       if (!ast_adsi_available(chan))
05306          return;
05307       bytes += adsi_logo(buf + bytes);
05308       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
05309       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
05310       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05311       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05312 
05313       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05314    }

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

Definition at line 4834 of file app_voicemail.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, 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_debug, chan, mbox(), and num.

Referenced by adsi_begin().

04835    {
04836       unsigned char buf[256];
04837       int bytes = 0;
04838       int x;
04839       char num[5];
04840 
04841       *useadsi = 0;
04842       bytes += ast_adsi_data_mode(buf + bytes);
04843       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04844 
04845       bytes = 0;
04846       bytes += adsi_logo(buf);
04847       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04848 #ifdef DISPLAY
04849       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04850 #endif
04851       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04852       bytes += ast_adsi_data_mode(buf + bytes);
04853       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04854 
04855       if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04856          bytes = 0;
04857          bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04858          bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04859          bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04860          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04861          ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04862          return 0;
04863       }
04864 
04865 #ifdef DISPLAY
04866       /* Add a dot */
04867       bytes = 0;
04868       bytes += ast_adsi_logo(buf);
04869       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04870       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04871       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04872       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04873 #endif
04874       bytes = 0;
04875       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04876       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04877       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04878       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04879       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04880       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04881       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04882 
04883 #ifdef DISPLAY
04884       /* Add another dot */
04885       bytes = 0;
04886       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04887       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04888 
04889       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04890       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04891 #endif
04892 
04893       bytes = 0;
04894       /* These buttons we load but don't use yet */
04895       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04896       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04897       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04898       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04899       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04900       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04901       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04902 
04903 #ifdef DISPLAY
04904       /* Add another dot */
04905       bytes = 0;
04906       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04907       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04908       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04909 #endif
04910 
04911       bytes = 0;
04912       for (x = 0; x < 5; x++) {
04913          snprintf(num, sizeof(num), "%d", x);
04914          bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04915       }
04916       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04917       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04918 
04919 #ifdef DISPLAY
04920       /* Add another dot */
04921       bytes = 0;
04922       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04923       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04924       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04925 #endif
04926 
04927       if (ast_adsi_end_download(chan)) {
04928          bytes = 0;
04929          bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04930          bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04931          bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04932          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04933          ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04934          return 0;
04935       }
04936       bytes = 0;
04937       bytes += ast_adsi_download_disconnect(buf + bytes);
04938       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04939       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04940 
04941       ast_debug(1, "Done downloading scripts...\n");
04942 
04943 #ifdef DISPLAY
04944       /* Add last dot */
04945       bytes = 0;
04946       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04947       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04948 #endif
04949       ast_debug(1, "Restarting session...\n");
04950 
04951       bytes = 0;
04952       /* Load the session now */
04953       if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04954          *useadsi = 1;
04955          bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04956       } else
04957          bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04958 
04959       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04960       return 0;
04961    }

static void adsi_login ( struct ast_channel chan  )  [static]

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

Referenced by vm_authenticate().

04981    {
04982       unsigned char buf[256];
04983       int bytes = 0;
04984       unsigned char keys[8];
04985       int x;
04986       if (!ast_adsi_available(chan))
04987          return;
04988 
04989       for (x = 0; x < 8; x++)
04990          keys[x] = 0;
04991       /* Set one key for next */
04992       keys[3] = ADSI_KEY_APPS + 3;
04993 
04994       bytes += adsi_logo(buf + bytes);
04995       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04996       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04997       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04998       bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04999       bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
05000       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
05001       bytes += ast_adsi_set_keys(buf + bytes, keys);
05002       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05003       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05004    }

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

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

04827    {
04828       int bytes = 0;
04829       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04830       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04831       return bytes;
04832    }

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

Definition at line 5057 of file app_voicemail.c.

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

Referenced by play_message(), and vm_execmain().

05058    {
05059       int bytes = 0;
05060       unsigned char buf[256]; 
05061       char buf1[256], buf2[256];
05062       char fn2[PATH_MAX];
05063 
05064       char cid[256] = "";
05065       char *val;
05066       char *name, *num;
05067       char datetime[21] = "";
05068       FILE *f;
05069 
05070       unsigned char keys[8];
05071 
05072       int x;
05073 
05074       if (!ast_adsi_available(chan))
05075          return;
05076 
05077       /* Retrieve important info */
05078       snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
05079       f = fopen(fn2, "r");
05080       if (f) {
05081          while (!feof(f)) {   
05082             if (!fgets((char *)buf, sizeof(buf), f)) {
05083                continue;
05084             }
05085             if (!feof(f)) {
05086                char *stringp = NULL;
05087                stringp = (char *)buf;
05088                strsep(&stringp, "=");
05089                val = strsep(&stringp, "=");
05090                if (!ast_strlen_zero(val)) {
05091                   if (!strcmp((char *)buf, "callerid"))
05092                      ast_copy_string(cid, val, sizeof(cid));
05093                   if (!strcmp((char *)buf, "origdate"))
05094                      ast_copy_string(datetime, val, sizeof(datetime));
05095                }
05096             }
05097          }
05098          fclose(f);
05099       }
05100       /* New meaning for keys */
05101       for (x = 0; x < 5; x++)
05102          keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
05103       keys[6] = 0x0;
05104       keys[7] = 0x0;
05105 
05106       if (!vms->curmsg) {
05107          /* No prev key, provide "Folder" instead */
05108          keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05109       }
05110       if (vms->curmsg >= vms->lastmsg) {
05111          /* If last message ... */
05112          if (vms->curmsg) {
05113             /* but not only message, provide "Folder" instead */
05114             keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05115             bytes += ast_adsi_voice_mode(buf + bytes, 0);
05116 
05117          } else {
05118             /* Otherwise if only message, leave blank */
05119             keys[3] = 1;
05120          }
05121       }
05122 
05123       if (!ast_strlen_zero(cid)) {
05124          ast_callerid_parse(cid, &name, &num);
05125          if (!name)
05126             name = num;
05127       } else
05128          name = "Unknown Caller";
05129 
05130       /* If deleted, show "undeleted" */
05131 
05132       if (vms->deleted[vms->curmsg])
05133          keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
05134 
05135       /* Except "Exit" */
05136       keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
05137       snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
05138          strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
05139       snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
05140 
05141       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
05142       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
05143       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
05144       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
05145       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05146       bytes += ast_adsi_set_keys(buf + bytes, keys);
05147       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05148 
05149       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05150    }

static void adsi_password ( struct ast_channel chan  )  [static]

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

Referenced by vm_authenticate().

05007    {
05008       unsigned char buf[256];
05009       int bytes = 0;
05010       unsigned char keys[8];
05011       int x;
05012       if (!ast_adsi_available(chan))
05013          return;
05014 
05015       for (x = 0; x < 8; x++)
05016          keys[x] = 0;
05017       /* Set one key for next */
05018       keys[3] = ADSI_KEY_APPS + 3;
05019 
05020       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05021       bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
05022       bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
05023       bytes += ast_adsi_set_keys(buf + bytes, keys);
05024       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05025       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05026    }

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

Definition at line 5197 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, chan, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_execmain().

05198    {
05199       unsigned char buf[256] = "";
05200       char buf1[256] = "", buf2[256] = "";
05201       int bytes = 0;
05202       unsigned char keys[8];
05203       int x;
05204 
05205       char *newm = (vms->newmessages == 1) ? "message" : "messages";
05206       char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
05207       if (!ast_adsi_available(chan))
05208          return;
05209       if (vms->newmessages) {
05210          snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
05211          if (vms->oldmessages) {
05212             strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
05213             snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
05214          } else {
05215             snprintf(buf2, sizeof(buf2), "%s.", newm);
05216          }
05217       } else if (vms->oldmessages) {
05218          snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
05219          snprintf(buf2, sizeof(buf2), "%s.", oldm);
05220       } else {
05221          strcpy(buf1, "You have no messages.");
05222          buf2[0] = ' ';
05223          buf2[1] = '\0';
05224       }
05225       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
05226       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
05227       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05228 
05229       for (x = 0; x < 6; x++)
05230          keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
05231       keys[6] = 0;
05232       keys[7] = 0;
05233 
05234       /* Don't let them listen if there are none */
05235       if (vms->lastmsg < 0)
05236          keys[0] = 1;
05237       bytes += ast_adsi_set_keys(buf + bytes, keys);
05238 
05239       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05240 
05241       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05242    }

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

Definition at line 5244 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, chan, vm_state::curbox, and vm_state::lastmsg.

Referenced by vm_execmain().

05245    {
05246       unsigned char buf[256] = "";
05247       char buf1[256] = "", buf2[256] = "";
05248       int bytes = 0;
05249       unsigned char keys[8];
05250       int x;
05251 
05252       char *mess = (vms->lastmsg == 0) ? "message" : "messages";
05253 
05254       if (!ast_adsi_available(chan))
05255          return;
05256 
05257       /* Original command keys */
05258       for (x = 0; x < 6; x++)
05259          keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
05260 
05261       keys[6] = 0;
05262       keys[7] = 0;
05263 
05264       if ((vms->lastmsg + 1) < 1)
05265          keys[0] = 0;
05266 
05267       snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
05268          strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
05269 
05270       if (vms->lastmsg + 1)
05271          snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
05272       else
05273          strcpy(buf2, "no messages.");
05274       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
05275       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
05276       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
05277       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05278       bytes += ast_adsi_set_keys(buf + bytes, keys);
05279 
05280       bytes += ast_adsi_voice_mode(buf + bytes, 0);
05281 
05282       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05283       
05284    }

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 9826 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_verb, ast_waitfordigit(), ast_vm_user::callback, chan, CONFIG_FLAG_NOCACHE, 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(), ast_vm_user::mailbox, make_file(), name, num, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, and wait_file().

Referenced by vm_execmain().

09827 {
09828    int res = 0;
09829    char filename[PATH_MAX];
09830    struct ast_config *msg_cfg = NULL;
09831    const char *origtime, *context;
09832    char *name, *num;
09833    int retries = 0;
09834    char *cid;
09835    struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, };
09836 
09837    vms->starting = 0; 
09838 
09839    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09840 
09841    /* Retrieve info from VM attribute file */
09842 
09843    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
09844    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
09845    RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
09846    msg_cfg = ast_config_load(filename, config_flags);
09847    DISPOSE(vms->curdir, vms->curmsg);
09848    if (!msg_cfg) {
09849       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
09850       return 0;
09851    }
09852 
09853    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
09854       ast_config_destroy(msg_cfg);
09855       return 0;
09856    }
09857 
09858    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
09859 
09860    context = ast_variable_retrieve(msg_cfg, "message", "context");
09861    if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
09862       context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
09863    switch (option) {
09864    case 3:
09865       if (!res)
09866          res = play_message_datetime(chan, vmu, origtime, filename);
09867       if (!res)
09868          res = play_message_callerid(chan, vms, cid, context, 0);
09869 
09870       res = 't';
09871       break;
09872 
09873    case 2:  /* Call back */
09874 
09875       if (ast_strlen_zero(cid))
09876          break;
09877 
09878       ast_callerid_parse(cid, &name, &num);
09879       while ((res > -1) && (res != 't')) {
09880          switch (res) {
09881          case '1':
09882             if (num) {
09883                /* Dial the CID number */
09884                res = dialout(chan, vmu, num, vmu->callback);
09885                if (res) {
09886                   ast_config_destroy(msg_cfg);
09887                   return 9;
09888                }
09889             } else {
09890                res = '2';
09891             }
09892             break;
09893 
09894          case '2':
09895             /* Want to enter a different number, can only do this if there's a dialout context for this user */
09896             if (!ast_strlen_zero(vmu->dialout)) {
09897                res = dialout(chan, vmu, NULL, vmu->dialout);
09898                if (res) {
09899                   ast_config_destroy(msg_cfg);
09900                   return 9;
09901                }
09902             } else {
09903                ast_verb(3, "Caller can not specify callback number - no dialout context available\n");
09904                res = ast_play_and_wait(chan, "vm-sorry");
09905             }
09906             ast_config_destroy(msg_cfg);
09907             return res;
09908          case '*':
09909             res = 't';
09910             break;
09911          case '3':
09912          case '4':
09913          case '5':
09914          case '6':
09915          case '7':
09916          case '8':
09917          case '9':
09918          case '0':
09919 
09920             res = ast_play_and_wait(chan, "vm-sorry");
09921             retries++;
09922             break;
09923          default:
09924             if (num) {
09925                ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num);
09926                res = ast_play_and_wait(chan, "vm-num-i-have");
09927                if (!res)
09928                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
09929                if (!res)
09930                   res = ast_play_and_wait(chan, "vm-tocallnum");
09931                /* Only prompt for a caller-specified number if there is a dialout context specified */
09932                if (!ast_strlen_zero(vmu->dialout)) {
09933                   if (!res)
09934                      res = ast_play_and_wait(chan, "vm-calldiffnum");
09935                }
09936             } else {
09937                res = ast_play_and_wait(chan, "vm-nonumber");
09938                if (!ast_strlen_zero(vmu->dialout)) {
09939                   if (!res)
09940                      res = ast_play_and_wait(chan, "vm-toenternumber");
09941                }
09942             }
09943             if (!res)
09944                res = ast_play_and_wait(chan, "vm-star-cancel");
09945             if (!res)
09946                res = ast_waitfordigit(chan, 6000);
09947             if (!res) {
09948                retries++;
09949                if (retries > 3)
09950                   res = 't';
09951             }
09952             break; 
09953             
09954          }
09955          if (res == 't')
09956             res = 0;
09957          else if (res == '*')
09958             res = -1;
09959       }
09960       break;
09961       
09962    case 1:  /* Reply */
09963       /* Send reply directly to sender */
09964       if (ast_strlen_zero(cid))
09965          break;
09966 
09967       ast_callerid_parse(cid, &name, &num);
09968       if (!num) {
09969          ast_verb(3, "No CID number available, no reply sent\n");
09970          if (!res)
09971             res = ast_play_and_wait(chan, "vm-nonumber");
09972          ast_config_destroy(msg_cfg);
09973          return res;
09974       } else {
09975          struct ast_vm_user vmu2;
09976          if (find_user(&vmu2, vmu->context, num)) {
09977             struct leave_vm_options leave_options;
09978             char mailbox[AST_MAX_EXTENSION * 2 + 2];
09979             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
09980 
09981             ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
09982             
09983             memset(&leave_options, 0, sizeof(leave_options));
09984             leave_options.record_gain = record_gain;
09985             res = leave_voicemail(chan, mailbox, &leave_options);
09986             if (!res)
09987                res = 't';
09988             ast_config_destroy(msg_cfg);
09989             return res;
09990          } else {
09991             /* Sender has no mailbox, can't reply */
09992             ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
09993             ast_play_and_wait(chan, "vm-nobox");
09994             res = 't';
09995             ast_config_destroy(msg_cfg);
09996             return res;
09997          }
09998       } 
09999       res = 0;
10000 
10001       break;
10002    }
10003 
10004 #ifndef IMAP_STORAGE
10005    ast_config_destroy(msg_cfg);
10006 
10007    if (!res) {
10008       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
10009       vms->heard[msg] = 1;
10010       res = wait_file(chan, vms, vms->fn);
10011    }
10012 #endif
10013    return res;
10014 }

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

Definition at line 8437 of file app_voicemail.c.

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

Referenced by load_config().

08438 {
08439    /* Assumes lock is already held */
08440    char *tmp;
08441    char *stringp;
08442    char *s;
08443    struct ast_vm_user *vmu;
08444    char *mailbox_full;
08445    int new = 0, old = 0;
08446 
08447    tmp = ast_strdupa(data);
08448 
08449    if (!(vmu = find_or_create(context, mbox)))
08450       return -1;
08451    
08452    populate_defaults(vmu);
08453 
08454    stringp = tmp;
08455    if ((s = strsep(&stringp, ","))) 
08456       ast_copy_string(vmu->password, s, sizeof(vmu->password));
08457    if (stringp && (s = strsep(&stringp, ","))) 
08458       ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
08459    if (stringp && (s = strsep(&stringp, ","))) 
08460       ast_copy_string(vmu->email, s, sizeof(vmu->email));
08461    if (stringp && (s = strsep(&stringp, ","))) 
08462       ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
08463    if (stringp && (s = strsep(&stringp, ","))) 
08464       apply_options(vmu, s);
08465 
08466    mailbox_full = alloca(strlen(mbox) + strlen(context) + 1);
08467    strcpy(mailbox_full, mbox);
08468    strcat(mailbox_full, "@");
08469    strcat(mailbox_full, context);
08470 
08471    inboxcount(mailbox_full, &new, &old);
08472    queue_mwi_event(mailbox_full, new, old);
08473 
08474    return 0;
08475 }

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

Definition at line 715 of file app_voicemail.c.

References apply_options(), ast_copy_string(), ast_log(), ast_set2_flag, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::exit, ast_vm_user::language, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::saydurationm, ast_vm_user::serveremail, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MOVEHEARD, 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().

00716 {
00717    int x;
00718    if (!strcasecmp(var, "attach")) {
00719       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00720    } else if (!strcasecmp(var, "attachfmt")) {
00721       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00722    } else if (!strcasecmp(var, "serveremail")) {
00723       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00724    } else if (!strcasecmp(var, "language")) {
00725       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00726    } else if (!strcasecmp(var, "tz")) {
00727       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00728 #ifdef IMAP_STORAGE
00729    } else if (!strcasecmp(var, "imapuser")) {
00730       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00731    } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
00732       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00733    } else if (!strcasecmp(var, "imapvmshareid")) {
00734       ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
00735 #endif
00736    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00737       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00738    } else if (!strcasecmp(var, "saycid")) {
00739       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00740    } else if (!strcasecmp(var, "sendvoicemail")) {
00741       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00742    } else if (!strcasecmp(var, "review")) {
00743       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00744    } else if (!strcasecmp(var, "tempgreetwarn")) {
00745       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00746    } else if (!strcasecmp(var, "operator")) {
00747       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00748    } else if (!strcasecmp(var, "envelope")) {
00749       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00750    } else if (!strcasecmp(var, "moveheard")) {
00751       ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD);
00752    } else if (!strcasecmp(var, "sayduration")) {
00753       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00754    } else if (!strcasecmp(var, "saydurationm")) {
00755       if (sscanf(value, "%d", &x) == 1) {
00756          vmu->saydurationm = x;
00757       } else {
00758          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00759       }
00760    } else if (!strcasecmp(var, "forcename")) {
00761       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00762    } else if (!strcasecmp(var, "forcegreetings")) {
00763       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00764    } else if (!strcasecmp(var, "callback")) {
00765       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00766    } else if (!strcasecmp(var, "dialout")) {
00767       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00768    } else if (!strcasecmp(var, "exitcontext")) {
00769       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00770    } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) {
00771       if (vmu->maxsecs <= 0) {
00772          ast_log(LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs);
00773          vmu->maxsecs = vmmaxsecs;
00774       } else {
00775          vmu->maxsecs = atoi(value);
00776       }
00777       if (!strcasecmp(var, "maxmessage"))
00778          ast_log(LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'.  Please make that change in your voicemail config.\n");
00779    } else if (!strcasecmp(var, "maxmsg")) {
00780       vmu->maxmsg = atoi(value);
00781       if (vmu->maxmsg <= 0) {
00782          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG);
00783          vmu->maxmsg = MAXMSG;
00784       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00785          ast_log(LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00786          vmu->maxmsg = MAXMSGLIMIT;
00787       }
00788    } else if (!strcasecmp(var, "backupdeleted")) {
00789       if (sscanf(value, "%d", &x) == 1)
00790          vmu->maxdeletedmsg = x;
00791       else if (ast_true(value))
00792          vmu->maxdeletedmsg = MAXMSG;
00793       else
00794          vmu->maxdeletedmsg = 0;
00795 
00796       if (vmu->maxdeletedmsg < 0) {
00797          ast_log(LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG);
00798          vmu->maxdeletedmsg = MAXMSG;
00799       } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) {
00800          ast_log(LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value);
00801          vmu->maxdeletedmsg = MAXMSGLIMIT;
00802       }
00803    } else if (!strcasecmp(var, "volgain")) {
00804       sscanf(value, "%lf", &vmu->volgain);
00805    } else if (!strcasecmp(var, "options")) {
00806       apply_options(vmu, value);
00807    }
00808 }

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

Definition at line 826 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00827 {  /* Destructively Parse options and apply */
00828    char *stringp;
00829    char *s;
00830    char *var, *value;
00831    stringp = ast_strdupa(options);
00832    while ((s = strsep(&stringp, "|"))) {
00833       value = s;
00834       if ((var = strsep(&value, "=")) && value) {
00835          apply_option(vmu, var, value);
00836       }
00837    }  
00838 }

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

Definition at line 840 of file app_voicemail.c.

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

Referenced by find_user_realtime(), and load_config().

00841 {
00842    struct ast_variable *tmp;
00843    tmp = var;
00844    while (tmp) {
00845       if (!strcasecmp(tmp->name, "vmsecret")) {
00846          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00847       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00848          if (ast_strlen_zero(retval->password))
00849             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00850       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00851          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00852       } else if (!strcasecmp(tmp->name, "pager")) {
00853          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00854       } else if (!strcasecmp(tmp->name, "email")) {
00855          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00856       } else if (!strcasecmp(tmp->name, "fullname")) {
00857          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00858       } else if (!strcasecmp(tmp->name, "context")) {
00859          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00860 #ifdef IMAP_STORAGE
00861       } else if (!strcasecmp(tmp->name, "imapuser")) {
00862          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00863       } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) {
00864          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00865       } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
00866          ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
00867 #endif
00868       } else
00869          apply_option(retval, tmp->name, tmp->value);
00870       tmp = tmp->next;
00871    } 
00872 }

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

Definition at line 3220 of file app_voicemail.c.

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

03221 {
03222    static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
03223       'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
03224       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
03225       '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
03226    int i, hiteof = 0;
03227    FILE *fi;
03228    struct baseio bio;
03229 
03230    memset(&bio, 0, sizeof(bio));
03231    bio.iocp = BASEMAXINLINE;
03232 
03233    if (!(fi = fopen(filename, "rb"))) {
03234       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
03235       return -1;
03236    }
03237 
03238    while (!hiteof) {
03239       unsigned char igroup[3], ogroup[4];
03240       int c, n;
03241 
03242       igroup[0] = igroup[1] = igroup[2] = 0;
03243 
03244       for (n = 0; n < 3; n++) {
03245          if ((c = inchar(&bio, fi)) == EOF) {
03246             hiteof = 1;
03247             break;
03248          }
03249 
03250          igroup[n] = (unsigned char)c;
03251       }
03252 
03253       if (n > 0) {
03254          ogroup[0] = dtable[igroup[0] >> 2];
03255          ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
03256          ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
03257          ogroup[3] = dtable[igroup[2] & 0x3F];
03258 
03259          if (n < 3) {
03260             ogroup[3] = '=';
03261 
03262             if (n < 2)
03263                ogroup[2] = '=';
03264          }
03265 
03266          for (i = 0; i < 4; i++)
03267             ochar(&bio, ogroup[i], so);
03268       }
03269    }
03270 
03271    fclose(fi);
03272    
03273    if (fputs(eol, so) == EOF)
03274       return 0;
03275 
03276    return 1;
03277 }

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

Definition at line 810 of file app_voicemail.c.

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

Referenced by vm_change_password().

00811 {
00812    int res;
00813    if (!ast_strlen_zero(vmu->uniqueid)) {
00814       res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
00815       if (res > 0) {
00816          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00817          res = 0;
00818       } else if (!res) {
00819          res = -1;
00820       }
00821       return res;
00822    }
00823    return -1;
00824 }

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

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

Definition at line 3377 of file app_voicemail.c.

Referenced by make_email_file().

03378 {
03379    for (; *str; str++) {
03380       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03381          return 1;
03382       }
03383    }
03384    return 0;
03385 }

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

Definition at line 6213 of file app_voicemail.c.

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

Referenced by vm_execmain().

06214 {
06215    int x = 0;
06216 #ifndef IMAP_STORAGE
06217    int res = 0, nummsg;
06218 #endif
06219 
06220    if (vms->lastmsg <= -1)
06221       goto done;
06222 
06223    vms->curmsg = -1; 
06224 #ifndef IMAP_STORAGE
06225    /* Get the deleted messages fixed */ 
06226    if (vm_lock_path(vms->curdir))
06227       return ERROR_LOCK_PATH;
06228 
06229    for (x = 0; x < vmu->maxmsg; x++) { 
06230       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 
06231          /* Save this message.  It's not in INBOX or hasn't been heard */ 
06232          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
06233          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
06234             break;
06235          vms->curmsg++; 
06236          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
06237          if (strcmp(vms->fn, vms->fn2)) { 
06238             RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
06239          } 
06240       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 
06241          /* Move to old folder before deleting */ 
06242          res = save_to_folder(vmu, vms, x, 1);
06243          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
06244             /* If save failed do not delete the message */
06245             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
06246             vms->deleted[x] = 0;
06247             vms->heard[x] = 0;
06248             --x;
06249          }
06250       } else if (vms->deleted[x] && vmu->maxdeletedmsg) {
06251          /* Move to deleted folder */ 
06252          res = save_to_folder(vmu, vms, x, 10);
06253          if (res == ERROR_LOCK_PATH) {
06254             /* If save failed do not delete the message */
06255             vms->deleted[x] = 0;
06256             vms->heard[x] = 0;
06257             --x;
06258          }
06259       } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) {
06260          /* If realtime storage enabled - we should explicitly delete this message,
06261          cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */
06262          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
06263          if (EXISTS(vms->curdir, x, vms->fn, NULL))
06264             DELETE(vms->curdir, x, vms->fn, vmu);
06265       }
06266    } 
06267 
06268    /* Delete ALL remaining messages */
06269    nummsg = x - 1;
06270    for (x = vms->curmsg + 1; x <= nummsg; x++) {
06271       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
06272       if (EXISTS(vms->curdir, x, vms->fn, NULL))
06273          DELETE(vms->curdir, x, vms->fn, vmu);
06274    }
06275    ast_unlock_path(vms->curdir);
06276 #else
06277    if (vms->deleted) {
06278       for (x = 0; x < vmu->maxmsg; x++) { 
06279          if (vms->deleted[x]) { 
06280             ast_debug(3, "IMAP delete of %d\n", x);
06281             DELETE(vms->curdir, x, vms->fn, vmu);
06282          }
06283       }
06284    }
06285 #endif
06286 
06287 done:
06288    if (vms->deleted)
06289       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
06290    if (vms->heard)
06291       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
06292 
06293    return 0;
06294 }

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

Definition at line 8621 of file app_voicemail.c.

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

Referenced by handle_voicemail_show_users().

08622 {
08623    int which = 0;
08624    int wordlen;
08625    struct ast_vm_user *vmu;
08626    const char *context = "";
08627 
08628    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08629    if (pos > 4)
08630       return NULL;
08631    if (pos == 3)
08632       return (state == 0) ? ast_strdup("for") : NULL;
08633    wordlen = strlen(word);
08634    AST_LIST_TRAVERSE(&users, vmu, list) {
08635       if (!strncasecmp(word, vmu->context, wordlen)) {
08636          if (context && strcmp(context, vmu->context) && ++which > state)
08637             return ast_strdup(vmu->context);
08638          /* ignore repeated contexts ? */
08639          context = vmu->context;
08640       }
08641    }
08642    return NULL;
08643 }

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

Definition at line 3052 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

03053 {
03054    int ifd;
03055    int ofd;
03056    int res;
03057    int len;
03058    char buf[4096];
03059 
03060 #ifdef HARDLINK_WHEN_POSSIBLE
03061    /* Hard link if possible; saves disk space & is faster */
03062    if (link(infile, outfile)) {
03063 #endif
03064       if ((ifd = open(infile, O_RDONLY)) < 0) {
03065          ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
03066          return -1;
03067       }
03068       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
03069          ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
03070          close(ifd);
03071          return -1;
03072       }
03073       do {
03074          len = read(ifd, buf, sizeof(buf));
03075          if (len < 0) {
03076             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
03077             close(ifd);
03078             close(ofd);
03079             unlink(outfile);
03080          }
03081          if (len) {
03082             res = write(ofd, buf, len);
03083             if (errno == ENOMEM || errno == ENOSPC || res != len) {
03084                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
03085                close(ifd);
03086                close(ofd);
03087                unlink(outfile);
03088             }
03089          }
03090       } while (len);
03091       close(ifd);
03092       close(ofd);
03093       return 0;
03094 #ifdef HARDLINK_WHEN_POSSIBLE
03095    } else {
03096       /* Hard link succeeded */
03097       return 0;
03098    }
03099 #endif
03100 }

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

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

Referenced by forward_message().

04079    {
04080       char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
04081       const char *frombox = mbox(imbox);
04082       int recipmsgnum;
04083 
04084       ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
04085 
04086       create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
04087       
04088       if (!dir)
04089          make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
04090       else
04091          ast_copy_string(fromdir, dir, sizeof(fromdir));
04092 
04093       make_file(frompath, sizeof(frompath), fromdir, msgnum);
04094       make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
04095 
04096       if (vm_lock_path(todir))
04097          return ERROR_LOCK_PATH;
04098 
04099       recipmsgnum = last_message_index(recip, todir) + 1;
04100       if (recipmsgnum < recip->maxmsg) {
04101          make_file(topath, sizeof(topath), todir, recipmsgnum);
04102          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
04103       } else {
04104          ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
04105       }
04106       ast_unlock_path(todir);
04107       notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04108       
04109       return 0;
04110    }

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

Definition at line 3102 of file app_voicemail.c.

References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), exten, ast_variable::name, ast_variable::next, ast_variable::value, and var.

Referenced by forward_message().

03103 {
03104    char frompath2[PATH_MAX], topath2[PATH_MAX];
03105    struct ast_variable *tmp, *var = NULL;
03106    const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL;
03107    ast_filecopy(frompath, topath, NULL);
03108    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
03109    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
03110    if (ast_check_realtime("voicemail_data")) {
03111       var = ast_load_realtime("voicemail_data", "filename", frompath, NULL);
03112       /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */
03113       for (tmp = var; tmp; tmp = tmp->next) {
03114          if (!strcasecmp(tmp->name, "origmailbox")) {
03115             origmailbox = tmp->value;
03116          } else if (!strcasecmp(tmp->name, "context")) {
03117             context = tmp->value;
03118          } else if (!strcasecmp(tmp->name, "macrocontext")) {
03119             macrocontext = tmp->value;
03120          } else if (!strcasecmp(tmp->name, "exten")) {
03121             exten = tmp->value;
03122          } else if (!strcasecmp(tmp->name, "priority")) {
03123             priority = tmp->value;
03124          } else if (!strcasecmp(tmp->name, "callerchan")) {
03125             callerchan = tmp->value;
03126          } else if (!strcasecmp(tmp->name, "callerid")) {
03127             callerid = tmp->value;
03128          } else if (!strcasecmp(tmp->name, "origdate")) {
03129             origdate = tmp->value;
03130          } else if (!strcasecmp(tmp->name, "origtime")) {
03131             origtime = tmp->value;
03132          } else if (!strcasecmp(tmp->name, "category")) {
03133             category = tmp->value;
03134          } else if (!strcasecmp(tmp->name, "duration")) {
03135             duration = tmp->value;
03136          }
03137       }
03138       ast_store_realtime("voicemail_data", "filename", topath, "origmailbox", origmailbox, "context", context, "macrocontext", macrocontext, "exten", exten, "priority", priority, "callerchan", callerchan, "callerid", callerid, "origdate", origdate, "origtime", origtime, "category", category, "duration", duration, NULL);
03139    }
03140    copy(frompath2, topath2);
03141    ast_variables_destroy(var);
03142 }

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

Definition at line 2980 of file app_voicemail.c.

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

Referenced by manager_list_voicemail_users(), and open_mailbox().

02981 {
02982    /* Find all .txt files - even if they are not in sequence from 0000 */
02983 
02984    int vmcount = 0;
02985    DIR *vmdir = NULL;
02986    struct dirent *vment = NULL;
02987 
02988    if (vm_lock_path(dir))
02989       return ERROR_LOCK_PATH;
02990 
02991    if ((vmdir = opendir(dir))) {
02992       while ((vment = readdir(vmdir))) {
02993          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02994             vmcount++;
02995       }
02996       closedir(vmdir);
02997    }
02998    ast_unlock_path(dir);
02999    
03000    return vmcount;
03001 }

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

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

01091 {
01092    mode_t   mode = VOICEMAIL_DIR_MODE;
01093    int res;
01094 
01095    make_dir(dest, len, context, ext, folder);
01096    if ((res = ast_mkdir(dest, mode))) {
01097       ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res));
01098       return -1;
01099    }
01100    return 0;
01101 }

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

Definition at line 9769 of file app_voicemail.c.

References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verb, ast_waitfordigit(), chan, ast_channel::context, ast_channel::exten, and ast_channel::priority.

Referenced by advanced_options(), and vm_execmain().

09770 {
09771    int cmd = 0;
09772    char destination[80] = "";
09773    int retries = 0;
09774 
09775    if (!num) {
09776       ast_verb(3, "Destination number will be entered manually\n");
09777       while (retries < 3 && cmd != 't') {
09778          destination[1] = '\0';
09779          destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call");
09780          if (!cmd)
09781             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
09782          if (!cmd)
09783             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
09784          if (!cmd) {
09785             cmd = ast_waitfordigit(chan, 6000);
09786             if (cmd)
09787                destination[0] = cmd;
09788          }
09789          if (!cmd) {
09790             retries++;
09791          } else {
09792 
09793             if (cmd < 0)
09794                return 0;
09795             if (cmd == '*') {
09796                ast_verb(3, "User hit '*' to cancel outgoing call\n");
09797                return 0;
09798             }
09799             if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination)-1, 6000, 10000, "#")) < 0) 
09800                retries++;
09801             else
09802                cmd = 't';
09803          }
09804       }
09805       if (retries >= 3) {
09806          return 0;
09807       }
09808       
09809    } else {
09810       ast_verb(3, "Destination number is CID number '%s'\n", num);
09811       ast_copy_string(destination, num, sizeof(destination));
09812    }
09813 
09814    if (!ast_strlen_zero(destination)) {
09815       if (destination[strlen(destination) -1 ] == '*')
09816          return 0; 
09817       ast_verb(3, "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
09818       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
09819       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
09820       chan->priority = 0;
09821       return 9;
09822    }
09823    return 0;
09824 }

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

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

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

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

Definition at line 3403 of file app_voicemail.c.

References charset.

Referenced by make_email_file().

03404 {
03405    char tmp[80];
03406    int first_section = 1;
03407    size_t endlen = 0, tmplen = 0;
03408    *end = '\0';
03409 
03410    tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03411    for (; *start; start++) {
03412       int need_encoding = 0;
03413       if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
03414          need_encoding = 1;
03415       }
03416       if ((first_section && need_encoding && preamble + tmplen > 70) ||
03417          (first_section && !need_encoding && preamble + tmplen > 72) ||
03418          (!first_section && need_encoding && tmplen > 70) ||
03419          (!first_section && !need_encoding && tmplen > 72)) {
03420          /* Start new line */
03421          endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp);
03422          tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03423          first_section = 0;
03424       }
03425       if (need_encoding && *start == ' ') {
03426          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
03427       } else if (need_encoding) {
03428          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start);
03429       } else {
03430          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start);
03431       }
03432    }
03433    snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
03434    return end;
03435 }

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

Definition at line 8405 of file app_voicemail.c.

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

Referenced by append_mailbox(), and load_config().

08406 {
08407    struct ast_vm_user *vmu;
08408 
08409    AST_LIST_TRAVERSE(&users, vmu, list) {
08410       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
08411          if (strcasecmp(vmu->context, context)) {
08412             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
08413                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
08414                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
08415                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
08416          }
08417          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
08418          return NULL;
08419       }
08420       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
08421          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
08422          return NULL;
08423       }
08424    }
08425    
08426    if (!(vmu = ast_calloc(1, sizeof(*vmu))))
08427       return NULL;
08428    
08429    ast_copy_string(vmu->context, context, sizeof(vmu->context));
08430    ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
08431 
08432    AST_LIST_INSERT_TAIL(&users, vmu, list);
08433    
08434    return vmu;
08435 }

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

Definition at line 918 of file app_voicemail.c.

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

00919 {
00920    /* This function could be made to generate one from a database, too */
00921    struct ast_vm_user *vmu = NULL, *cur;
00922    AST_LIST_LOCK(&users);
00923 
00924    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00925       context = "default";
00926 
00927    AST_LIST_TRAVERSE(&users, cur, list) {
00928       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00929          break;
00930       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00931          break;
00932    }
00933    if (cur) {
00934       /* Make a copy, so that on a reload, we have no race */
00935       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00936          memcpy(vmu, cur, sizeof(*vmu));
00937          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00938          AST_LIST_NEXT(vmu, list) = NULL;
00939       }
00940    } else
00941       vmu = find_user_realtime(ivm, context, mailbox);
00942    AST_LIST_UNLOCK(&users);
00943    return vmu;
00944 }

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

Definition at line 889 of file app_voicemail.c.

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

00890 {
00891    struct ast_variable *var;
00892    struct ast_vm_user *retval;
00893 
00894    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00895       if (!ivm)
00896          ast_set_flag(retval, VM_ALLOCED);   
00897       else
00898          memset(retval, 0, sizeof(*retval));
00899       if (mailbox) 
00900          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00901       populate_defaults(retval);
00902       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00903          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00904       else
00905          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00906       if (var) {
00907          apply_options_full(retval, var);
00908          ast_variables_destroy(var);
00909       } else { 
00910          if (!ivm) 
00911             ast_free(retval);
00912          retval = NULL;
00913       }  
00914    } 
00915    return retval;
00916 }

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

References app, ast_clear_flag, ast_copy_string(), ast_fileexists(), 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_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), chan, 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::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_channel::language, leave_voicemail(), ast_app::list, LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, strsep(), vm_state::username, VM_ATTACH, VM_DIRECFORWARD, and vm_forwardoptions().

Referenced by vm_execmain().

05548    {
05549 #ifdef IMAP_STORAGE
05550       int todircount = 0;
05551       struct vm_state *dstvms;
05552 #endif
05553       char username[70] = "";
05554       char fn[PATH_MAX]; /* for playback of name greeting */
05555       char ecodes[16] = "#";
05556       int res = 0, cmd = 0;
05557       struct ast_vm_user *receiver = NULL, *vmtmp;
05558       AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
05559       char *stringp;
05560       const char *s;
05561       int saved_messages = 0, found = 0;
05562       int valid_extensions = 0;
05563       char *dir;
05564       int curmsg;
05565 
05566       if (vms == NULL) return -1;
05567       dir = vms->curdir;
05568       curmsg = vms->curmsg;
05569       
05570       while (!res && !valid_extensions) {
05571          int use_directory = 0;
05572          if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
05573             int done = 0;
05574             int retries = 0;
05575             cmd = 0;
05576             while ((cmd >= 0) && !done) {
05577                if (cmd)
05578                   retries = 0;
05579                switch (cmd) {
05580                case '1': 
05581                   use_directory = 0;
05582                   done = 1;
05583                   break;
05584                case '2': 
05585                   use_directory = 1;
05586                   done = 1;
05587                   break;
05588                case '*': 
05589                   cmd = 't';
05590                   done = 1;
05591                   break;
05592                default: 
05593                   /* Press 1 to enter an extension press 2 to use the directory */
05594                   cmd = ast_play_and_wait(chan, "vm-forward");
05595                   if (!cmd)
05596                      cmd = ast_waitfordigit(chan, 3000);
05597                   if (!cmd)
05598                      retries++;
05599                   if (retries > 3) {
05600                      cmd = 't';
05601                      done = 1;
05602                   }
05603                   
05604                }
05605             }
05606             if (cmd < 0 || cmd == 't')
05607                break;
05608          }
05609          
05610          if (use_directory) {
05611             /* use app_directory */
05612             
05613             char old_context[sizeof(chan->context)];
05614             char old_exten[sizeof(chan->exten)];
05615             int old_priority;
05616             struct ast_app* app;
05617 
05618             app = pbx_findapp("Directory");
05619             if (app) {
05620                char vmcontext[256];
05621                /* make backup copies */
05622                memcpy(old_context, chan->context, sizeof(chan->context));
05623                memcpy(old_exten, chan->exten, sizeof(chan->exten));
05624                old_priority = chan->priority;
05625                
05626                /* call the the Directory, changes the channel */
05627                snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
05628                res = pbx_exec(chan, app, vmcontext);
05629                
05630                ast_copy_string(username, chan->exten, sizeof(username));
05631                
05632                /* restore the old context, exten, and priority */
05633                memcpy(chan->context, old_context, sizeof(chan->context));
05634                memcpy(chan->exten, old_exten, sizeof(chan->exten));
05635                chan->priority = old_priority;
05636                
05637             } else {
05638                ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
05639                ast_clear_flag((&globalflags), VM_DIRECFORWARD);
05640             }
05641          } else {
05642             /* Ask for an extension */
05643             res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
05644             if (res)
05645                break;
05646             if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
05647                break;
05648          }
05649          
05650          /* start all over if no username */
05651          if (ast_strlen_zero(username))
05652             continue;
05653          stringp = username;
05654          s = strsep(&stringp, "*");
05655          /* start optimistic */
05656          valid_extensions = 1;
05657          while (s) {
05658             /* 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 */
05659             if ((flag == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
05660                AST_LIST_INSERT_HEAD(&extensions, receiver, list);
05661                found++;
05662             } else {
05663                while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) {
05664                   free_user(receiver);
05665                }
05666                ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
05667                valid_extensions = 0;
05668                break;
05669             }
05670 
05671             /* play name if available, else play extension number */
05672             snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s);
05673             RETRIEVE(fn, -1, s, receiver->context);
05674             if (ast_fileexists(fn, NULL, NULL) > 0) {
05675                res = ast_stream_and_wait(chan, fn, ecodes);
05676                if (res) {
05677                   DISPOSE(fn, -1);
05678                   return res;
05679                }
05680             } else {
05681                res = ast_say_digit_str(chan, s, ecodes, chan->language);
05682             }
05683             DISPOSE(fn, -1);
05684 
05685             s = strsep(&stringp, "*");
05686          }
05687          /* break from the loop of reading the extensions */
05688          if (valid_extensions)
05689             break;
05690          /* "I am sorry, that's not a valid extension.  Please try again." */
05691          res = ast_play_and_wait(chan, "pbx-invalid");
05692       }
05693       /* check if we're clear to proceed */
05694       if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
05695          return res;
05696       if (flag==1) {
05697          struct leave_vm_options leave_options;
05698          char mailbox[AST_MAX_EXTENSION * 2 + 2];
05699          /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
05700          if (context)
05701             snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
05702          else
05703             ast_copy_string(mailbox, username, sizeof(mailbox));
05704 
05705          /* Send VoiceMail */
05706          memset(&leave_options, 0, sizeof(leave_options));
05707          leave_options.record_gain = record_gain;
05708          cmd = leave_voicemail(chan, mailbox, &leave_options);
05709       } else {
05710          /* Forward VoiceMail */
05711          long duration = 0;
05712          char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
05713          struct vm_state vmstmp;
05714          memcpy(&vmstmp, vms, sizeof(vmstmp));
05715 
05716          make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
05717          create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
05718          make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
05719          
05720          RETRIEVE(dir, curmsg, sender->mailbox, sender->context);
05721          
05722          /* Alter a surrogate file, only */
05723          copy_plain_file(origmsgfile, msgfile);
05724 
05725          cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05726          if (!cmd) {
05727             AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05728 #ifdef IMAP_STORAGE
05729                char *myserveremail = serveremail;
05730                int attach_user_voicemail;
05731                /* get destination mailbox */
05732                dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, 0);
05733                if (!dstvms) {
05734                   dstvms = create_vm_state_from_user(vmtmp);
05735                }
05736                if (dstvms) {
05737                   init_mailstream(dstvms, 0);
05738                   if (!dstvms->mailstream) {
05739                      ast_log(LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox);
05740                   } else {
05741                      STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05742                      run_externnotify(vmtmp->context, vmtmp->mailbox); 
05743                   }
05744                } else {
05745                   ast_log(LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox);
05746                }
05747                if (!ast_strlen_zero(vmtmp->serveremail))
05748                   myserveremail = vmtmp->serveremail;
05749                attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05750                /* NULL category for IMAP storage */
05751                sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL);
05752 #else
05753                copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
05754 #endif
05755                saved_messages++;
05756                AST_LIST_REMOVE_CURRENT(list);
05757                free_user(vmtmp);
05758                if (res)
05759                   break;
05760             }
05761             AST_LIST_TRAVERSE_SAFE_END;
05762             if (saved_messages > 0) {
05763                /* give confirmation that the message was saved */
05764                /* commented out since we can't forward batches yet
05765                if (saved_messages == 1)
05766                   res = ast_play_and_wait(chan, "vm-message");
05767                else
05768                   res = ast_play_and_wait(chan, "vm-messages");
05769                if (!res)
05770                   res = ast_play_and_wait(chan, "vm-saved"); */
05771                res = ast_play_and_wait(chan, "vm-msgsaved");
05772             }  
05773          }
05774          /* Remove surrogate file */
05775          DISPOSE(dir, curmsg);
05776       }
05777 
05778       /* If anything failed above, we still have this list to free */
05779       while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
05780          free_user(vmtmp);
05781       return res ? res : cmd;
05782    }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 1126 of file app_voicemail.c.

References ast_free, ast_test_flag, and VM_ALLOCED.

01127 {
01128    if (ast_test_flag(vmu, VM_ALLOCED))
01129       ast_free(vmu);
01130 }

static void free_vm_users ( void   )  [static]

Free the users structure.

Definition at line 9051 of file app_voicemail.c.

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

Referenced by load_config(), and unload_module().

09052 {
09053    struct ast_vm_user *cur;
09054    AST_LIST_LOCK(&users);
09055    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
09056       ast_set_flag(cur, VM_ALLOCED);
09057       free_user(cur);
09058    }
09059    AST_LIST_UNLOCK(&users);
09060 }

static void free_vm_zones ( void   )  [static]

Free the zones structure.

Definition at line 9063 of file app_voicemail.c.

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

Referenced by load_config(), and unload_module().

09064 {
09065    struct vm_zone *zcur;
09066    AST_LIST_LOCK(&zones);
09067    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list)))
09068       free_zone(zcur);
09069    AST_LIST_UNLOCK(&zones);
09070 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3918 of file app_voicemail.c.

References ast_free.

03919 {
03920    ast_free(z);
03921 }

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

Definition at line 3855 of file app_voicemail.c.

References ast_localtime(), ast_strftime(), and ast_tvnow().

03856 {
03857    struct ast_tm tm;
03858    struct timeval t = ast_tvnow();
03859    
03860    ast_localtime(&t, &tm, "UTC");
03861 
03862    return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm);
03863 }

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

get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized

Definition at line 5320 of file app_voicemail.c.

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

Referenced by get_folder2().

05321    {
05322       int x;
05323       int d;
05324       char fn[PATH_MAX];
05325       d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
05326       if (d)
05327          return d;
05328       for (x = start; x < 5; x++) { /* For all folders */
05329          if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL)))
05330             return d;
05331          d = ast_play_and_wait(chan, "vm-for"); /* "for" */
05332          if (d)
05333             return d;
05334          snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
05335          d = vm_play_folder_name(chan, fn);
05336          if (d)
05337             return d;
05338          d = ast_waitfordigit(chan, 500);
05339          if (d)
05340             return d;
05341       }
05342       d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
05343       if (d)
05344          return d;
05345       d = ast_waitfordigit(chan, 4000);
05346       return d;
05347    }

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

Definition at line 5349 of file app_voicemail.c.

References ast_play_and_wait(), chan, and get_folder().

Referenced by vm_execmain().

05350    {
05351       int res = 0;
05352       res = ast_play_and_wait(chan, fn);  /* Folder name */
05353       while (((res < '0') || (res > '9')) &&
05354             (res != '#') && (res >= 0)) {
05355          res = get_folder(chan, 0);
05356       }
05357       return res;
05358    }

static char* handle_voicemail_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Reload voicemail configuration from the CLI.

Definition at line 8756 of file app_voicemail.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, load_config(), and ast_cli_entry::usage.

08757 {
08758    switch (cmd) {
08759    case CLI_INIT:
08760       e->command = "voicemail reload";
08761       e->usage =
08762          "Usage: voicemail reload\n"
08763          "       Reload voicemail configuration\n";
08764       return NULL;
08765    case CLI_GENERATE:
08766       return NULL;
08767    }
08768 
08769    if (a->argc != e->args)
08770       return CLI_SHOWUSAGE;
08771 
08772    ast_cli(a->fd, "Reloading voicemail configuration...\n");   
08773    load_config(1);
08774    
08775    return CLI_SUCCESS;
08776 }

static char* handle_voicemail_show_users ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show a list of voicemail users in the CLI.

Definition at line 8646 of file app_voicemail.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_check_realtime(), ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_voicemail_show_users(), ast_vm_user::context, ast_cli_args::fd, ast_vm_user::fullname, HVSU_OUTPUT_FORMAT, inboxcount(), ast_cli_args::line, ast_vm_user::list, ast_vm_user::mailbox, ast_cli_args::n, ast_cli_args::pos, show_users_realtime(), ast_cli_entry::usage, ast_cli_args::word, and ast_vm_user::zonetag.

08647 {
08648    struct ast_vm_user *vmu;
08649 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n"
08650    const char *context = NULL;
08651    int users_counter = 0;
08652 
08653    switch (cmd) {
08654    case CLI_INIT:
08655       e->command = "voicemail show users";
08656       e->usage =
08657          "Usage: voicemail show users [for <context>]\n"
08658          "       Lists all mailboxes currently set up\n";
08659       return NULL;
08660    case CLI_GENERATE:
08661       return complete_voicemail_show_users(a->line, a->word, a->pos, a->n);
08662    }  
08663 
08664    if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
08665       return CLI_SHOWUSAGE;
08666    if (a->argc == 5) {
08667       if (strcmp(a->argv[3], "for"))
08668          return CLI_SHOWUSAGE;
08669       context = a->argv[4];
08670    }
08671 
08672    if (ast_check_realtime("voicemail")) {
08673       if (!context) {
08674          ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n");
08675          return CLI_SHOWUSAGE;
08676       }
08677       return show_users_realtime(a->fd, context);
08678    }
08679 
08680    AST_LIST_LOCK(&users);
08681    if (AST_LIST_EMPTY(&users)) {
08682       ast_cli(a->fd, "There are no voicemail users currently defined\n");
08683       AST_LIST_UNLOCK(&users);
08684       return CLI_FAILURE;
08685    }
08686    if (a->argc == 3)
08687       ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg");
08688    else {
08689       int count = 0;
08690       AST_LIST_TRAVERSE(&users, vmu, list) {
08691          if (!strcmp(context, vmu->context))
08692             count++;
08693       }
08694       if (count) {
08695          ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg");
08696       } else {
08697          ast_cli(a->fd, "No such voicemail context \"%s\"\n", context);
08698          AST_LIST_UNLOCK(&users);
08699          return CLI_FAILURE;
08700       }
08701    }
08702    AST_LIST_TRAVERSE(&users, vmu, list) {
08703       int newmsgs = 0, oldmsgs = 0;
08704       char count[12], tmp[256] = "";
08705 
08706       if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) {
08707          snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08708          inboxcount(tmp, &newmsgs, &oldmsgs);
08709          snprintf(count, sizeof(count), "%d", newmsgs);
08710          ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08711          users_counter++;
08712       }
08713    }
08714    AST_LIST_UNLOCK(&users);
08715    ast_cli(a->fd, "%d voicemail users configured.\n", users_counter);
08716    return CLI_SUCCESS;
08717 }

static char* handle_voicemail_show_zones ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show a list of voicemail zones in the CLI.

Definition at line 8720 of file app_voicemail.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVSZ_OUTPUT_FORMAT, vm_zone::list, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.

08721 {
08722    struct vm_zone *zone;
08723 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
08724    char *res = CLI_SUCCESS;
08725 
08726    switch (cmd) {
08727    case CLI_INIT:
08728       e->command = "voicemail show zones";
08729       e->usage =
08730          "Usage: voicemail show zones\n"
08731          "       Lists zone message formats\n";
08732       return NULL;
08733    case CLI_GENERATE:
08734       return NULL;
08735    }
08736 
08737    if (a->argc != e->args)
08738       return CLI_SHOWUSAGE;
08739 
08740    AST_LIST_LOCK(&zones);
08741    if (!AST_LIST_EMPTY(&zones)) {
08742       ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format");
08743       AST_LIST_TRAVERSE(&zones, zone, list) {
08744          ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format);
08745       }
08746    } else {
08747       ast_cli(a->fd, "There are no voicemail zones currently defined\n");
08748       res = CLI_FAILURE;
08749    }
08750    AST_LIST_UNLOCK(&zones);
08751 
08752    return res;
08753 }

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

Definition at line 4156 of file app_voicemail.c.

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

04157    {
04158       char tmp[256], *tmp2 = tmp, *mbox, *context;
04159       ast_copy_string(tmp, mailbox, sizeof(tmp));
04160       while ((mbox = strsep(&tmp2, ","))) {
04161          if ((context = strchr(mbox, '@')))
04162             *context++ = '\0';
04163          else
04164             context = "default";
04165          if (__has_voicemail(context, mbox, folder, 1))
04166             return 1;
04167       }
04168       return 0;
04169    }

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

Definition at line 4172 of file app_voicemail.c.

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

Referenced by append_mailbox(), handle_voicemail_show_users(), load_module(), manager_list_voicemail_users(), poll_subscribed_mailboxes(), and run_externnotify().

04173    {
04174       char tmp[256];
04175       char *context;
04176 
04177       /* If no mailbox, return immediately */
04178       if (ast_strlen_zero(mailbox))
04179          return 0;
04180 
04181       if (newmsgs)
04182          *newmsgs = 0;
04183       if (oldmsgs)
04184          *oldmsgs = 0;
04185 
04186       if (strchr(mailbox, ',')) {
04187          int tmpnew, tmpold;
04188          char *mb, *cur;
04189 
04190          ast_copy_string(tmp, mailbox, sizeof(tmp));
04191          mb = tmp;
04192          while ((cur = strsep(&mb, ", "))) {
04193             if (!ast_strlen_zero(cur)) {
04194                if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
04195                   return -1;
04196                else {
04197                   if (newmsgs)
04198                      *newmsgs += tmpnew; 
04199                   if (oldmsgs)
04200                      *oldmsgs += tmpold;
04201                }
04202             }
04203          }
04204          return 0;
04205       }
04206 
04207       ast_copy_string(tmp, mailbox, sizeof(tmp));
04208       
04209       if ((context = strchr(tmp, '@')))
04210          *context++ = '\0';
04211       else
04212          context = "default";
04213 
04214       if (newmsgs)
04215          *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
04216       if (oldmsgs)
04217          *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
04218 
04219       return 0;
04220    }

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

Definition at line 3172 of file app_voicemail.c.

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

Referenced by ast_eivr_getvariable(), ast_eivr_setvariable(), inchar(), and sip_addheader().

03173 {
03174    int l;
03175 
03176    if (bio->ateof)
03177       return 0;
03178 
03179    if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) {
03180       if (ferror(fi))
03181          return -1;
03182 
03183       bio->ateof = 1;
03184       return 0;
03185    }
03186 
03187    bio->iolen = l;
03188    bio->iocp = 0;
03189 
03190    return 1;
03191 }

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

Definition at line 3193 of file app_voicemail.c.

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

Referenced by base_encode().

03194 {
03195    if (bio->iocp >= bio->iolen) {
03196       if (!inbuf(bio, fi))
03197          return EOF;
03198    }
03199 
03200    return bio->iobuf[bio->iocp++];
03201 }

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

Definition at line 3890 of file app_voicemail.c.

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

03891 {
03892    int res;
03893    char fn[PATH_MAX];
03894    char dest[PATH_MAX];
03895 
03896    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
03897 
03898    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, ""))) {
03899       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
03900       return -1;
03901    }
03902 
03903    res = play_greeting(chan, vmu, fn, ecodes);
03904    if (res == -2) {
03905       /* File did not exist */
03906       res = ast_stream_and_wait(chan, "vm-theperson", ecodes);
03907       if (res)
03908          return res;
03909       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
03910    }
03911    if (res)
03912       return res;
03913 
03914    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes);
03915    return res;
03916 }

static int is_valid_dtmf ( const char *  key  )  [static]

Definition at line 874 of file app_voicemail.c.

References ast_log(), ast_strdupa, LOG_WARNING, and VALID_DTMF.

Referenced by load_config().

00875 {
00876    int i;
00877    char *local_key = ast_strdupa(key);
00878 
00879    for (i = 0; i < strlen(key); ++i) {
00880       if (!strchr(VALID_DTMF, *local_key)) {
00881          ast_log(LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key);
00882          return 0;
00883       }
00884       local_key++;
00885    }
00886    return 1;
00887 }

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

A negative return value indicates an error.

Note:
Should always be called with a lock already set on dir.

Definition at line 3022 of file app_voicemail.c.

References map, ast_vm_user::maxmsg, and MAXMSGLIMIT.

Referenced by copy_message(), open_mailbox(), and save_to_folder().

03023 {
03024    int x;
03025    unsigned char map[MAXMSGLIMIT] = "";
03026    DIR *msgdir;
03027    struct dirent *msgdirent;
03028    int msgdirint;
03029 
03030    /* Reading the entire directory into a file map scales better than
03031    * doing a stat repeatedly on a predicted sequence.  I suspect this
03032    * is partially due to stat(2) internally doing a readdir(2) itself to
03033    * find each file. */
03034    msgdir = opendir(dir);
03035    while ((msgdirent = readdir(msgdir))) {
03036       if (sscanf(msgdirent->d_name, "msg%d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT)
03037          map[msgdirint] = 1;
03038    }
03039    closedir(msgdir);
03040 
03041    for (x = 0; x < vmu->maxmsg; x++) {
03042       if (map[x] == 0)
03043          break;
03044    }
03045 
03046    return x - 1;
03047 }

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

Definition at line 4272 of file app_voicemail.c.

References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_fileexists(), ast_free, ast_log(), ast_str_buffer, ast_str_create(), ast_str_set(), ast_strlen_zero(), ast_test_flag, chan, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_vm_user::context, create_dirpath(), DISPOSE, ast_vm_user::exit, find_user(), ast_channel::macrocontext, ast_vm_user::mailbox, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), RETRIEVE, and VM_OPERATOR.

04273 {
04274 #ifdef IMAP_STORAGE
04275    int newmsgs, oldmsgs;
04276 #endif
04277    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
04278    struct vm_state *vms = NULL;
04279    char callerid[256];
04280    FILE *txt;
04281    char date[256];
04282    int txtdes;
04283    int res = 0;
04284    int msgnum;
04285    int duration = 0;
04286    int ausemacro = 0;
04287    int ousemacro = 0;
04288    int ouseexten = 0;
04289    int rtmsgid = 0;
04290    char tmpid[16];
04291    char tmpdur[16];
04292    char priority[16];
04293    char origtime[16];
04294    char dir[PATH_MAX], tmpdir[PATH_MAX];
04295    char fn[PATH_MAX];
04296    char prefile[PATH_MAX] = "";
04297    char tempfile[PATH_MAX] = "";
04298    char ext_context[256] = "";
04299    char fmt[80];
04300    char *context;
04301    char ecodes[17] = "#";
04302    char *tmpptr;
04303    struct ast_str *tmp = ast_str_create(16);
04304    struct ast_vm_user *vmu;
04305    struct ast_vm_user svm;
04306    const char *category = NULL, *code, *alldtmf = "0123456789ABCD*#";
04307 
04308    ast_str_set(&tmp, 0, "%s", ext);
04309    ext = ast_str_buffer(tmp);
04310    if ((context = strchr(ext, '@'))) {
04311       *context++ = '\0';
04312       tmpptr = strchr(context, '&');
04313    } else {
04314       tmpptr = strchr(ext, '&');
04315    }
04316 
04317    if (tmpptr) {
04318       *tmpptr++ = '\0';
04319    }
04320 
04321    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
04322 
04323    ast_debug(3, "Before find_user\n");
04324    if (!(vmu = find_user(&svm, context, ext))) {
04325       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
04326       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04327       ast_free(tmp);
04328       return res;
04329    }
04330    /* Setup pre-file if appropriate */
04331    if (strcmp(vmu->context, "default")) {
04332       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
04333    } else {
04334       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
04335    }
04336    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
04337       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
04338    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
04339       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
04340    }
04341    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
04342    if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) {
04343       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
04344       ast_free(tmp);
04345       return -1;
04346    }
04347    RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context);
04348    if (ast_fileexists(tempfile, NULL, NULL) > 0) {
04349       ast_copy_string(prefile, tempfile, sizeof(prefile));
04350    }
04351    DISPOSE(tempfile, -1);
04352    /* It's easier just to try to make it than to check for its existence */
04353    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
04354 
04355    /* Check current or macro-calling context for special extensions */
04356    if (ast_test_flag(vmu, VM_OPERATOR)) {
04357       if (!ast_strlen_zero(vmu->exit)) {
04358          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
04359             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04360             ouseexten = 1;
04361          }
04362       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
04363          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04364          ouseexten = 1;
04365       } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
04366          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04367          ousemacro = 1;
04368       }
04369    }
04370 
04371    if (!ast_strlen_zero(vmu->exit)) {
04372       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) {
04373          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04374       }
04375    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) {
04376       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04377    } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
04378       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04379       ausemacro = 1;
04380    }
04381 
04382    if (ast_test_flag(options, OPT_DTMFEXIT)) {
04383       for (code = alldtmf; *code; code++) {
04384          char e[2] = "";
04385          e[0] = *code;
04386          if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) {
04387             strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
04388          }
04389       }
04390    }
04391 
04392    /* Play the beginning intro if desired */
04393    if (!ast_strlen_zero(prefile)) {
04394       res = play_greeting(chan, vmu, prefile, ecodes);
04395       if (res == -2) {
04396          /* The file did not exist */
04397          ast_debug(1, "%s doesn't exist, doing what we can\n", prefile);
04398          res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
04399       }
04400       if (res < 0) {
04401          ast_debug(1, "Hang up during prefile playback\n");
04402          free_user(vmu);
04403          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04404          ast_free(tmp);
04405          return -1;
04406       }
04407    }
04408    if (res == '#') {
04409       /* On a '#' we skip the instructions */
04410       ast_set_flag(options, OPT_SILENT);
04411       res = 0;
04412    }
04413    if (!res && !ast_test_flag(options, OPT_SILENT)) {
04414       res = ast_stream_and_wait(chan, INTRO, ecodes);
04415       if (res == '#') {
04416          ast_set_flag(options, OPT_SILENT);
04417          res = 0;
04418       }
04419    }
04420    if (res > 0) {
04421       ast_stopstream(chan);
04422    }
04423    /* Check for a '*' here in case the caller wants to escape from voicemail to something
04424     * other than the operator -- an automated attendant or mailbox login for example */
04425    if (res == '*') {
04426       chan->exten[0] = 'a';
04427       chan->exten[1] = '\0';
04428       if (!ast_strlen_zero(vmu->exit)) {
04429          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04430       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
04431          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04432       }
04433       chan->priority = 0;
04434       free_user(vmu);
04435       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04436       ast_free(tmp);
04437       return 0;
04438    }
04439 
04440    /* Check for a '0' here */
04441    if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
04442 transfer:
04443       if (ouseexten || ousemacro) {
04444          chan->exten[0] = 'o';
04445          chan->exten[1] = '\0';
04446          if (!ast_strlen_zero(vmu->exit)) {
04447             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04448          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
04449             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04450          }
04451          ast_play_and_wait(chan, "transfer");
04452          chan->priority = 0;
04453          free_user(vmu);
04454          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04455       }
04456       ast_free(tmp);
04457       return 0;
04458    }
04459 
04460    /* Allow all other digits to exit Voicemail and return to the dialplan */
04461    if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) {
04462       if (!ast_strlen_zero(options->exitcontext)) {
04463          ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context));
04464       }
04465       free_user(vmu);
04466       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04467       return res;
04468    }
04469 
04470    if (res < 0) {
04471       free_user(vmu);
04472       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04473       ast_free(tmp);
04474       return -1;
04475    }
04476    /* The meat of recording the message...  All the announcements and beeps have been played*/
04477    ast_copy_string(fmt, vmfmts, sizeof(fmt));
04478    if (!ast_strlen_zero(fmt)) {
04479       msgnum = 0;
04480 
04481 #ifdef IMAP_STORAGE
04482       /* Is ext a mailbox? */
04483       /* must open stream for this user to get info! */
04484       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
04485       if (res < 0) {
04486          ast_log(LOG_NOTICE, "Can not leave voicemail, unable to count messages\n");
04487          ast_free(tmp);
04488          return -1;
04489       }
04490       if (!(vms = get_vm_state_by_mailbox(ext, 0))) {
04491          /* It is possible under certain circumstances that inboxcount did not
04492           * create a vm_state when it was needed. This is a catchall which will
04493           * rarely be used.
04494           */
04495          if (!(vms = create_vm_state_from_user(vmu))) {
04496             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
04497             ast_free(tmp);
04498             return -1;
04499          }
04500       }
04501       vms->newmessages++;
04502 
04503       /* here is a big difference! We add one to it later */
04504       msgnum = newmsgs + oldmsgs;
04505       ast_debug(3, "Messagecount set to %d\n", msgnum);
04506       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
04507       /* set variable for compatibility */
04508       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04509 
04510       /* Check if mailbox is full */
04511       check_quota(vms, imapfolder);
04512       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
04513          ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
04514          ast_play_and_wait(chan, "vm-mailboxfull");
04515          ast_free(tmp);
04516          return -1;
04517       }
04518 
04519       /* Check if we have exceeded maxmsg */
04520       if (msgnum >= vmu->maxmsg) {
04521          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
04522          ast_play_and_wait(chan, "vm-mailboxfull");
04523          ast_free(tmp);
04524          return -1;
04525       }
04526 #else
04527       if (count_messages(vmu, dir) >= vmu->maxmsg) {
04528          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04529          if (!res) {
04530             res = ast_waitstream(chan, "");
04531          }
04532          ast_log(LOG_WARNING, "No more messages possible\n");
04533          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04534          goto leave_vm_out;
04535       }
04536 
04537 #endif
04538       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
04539       txtdes = mkstemp(tmptxtfile);
04540       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
04541       if (txtdes < 0) {
04542          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04543          if (!res) {
04544             res = ast_waitstream(chan, "");
04545          }
04546          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
04547          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04548          goto leave_vm_out;
04549       }
04550 
04551       /* Now play the beep once we have the message number for our next message. */
04552       if (res >= 0) {
04553          /* Unless we're *really* silent, try to send the beep */
04554          res = ast_stream_and_wait(chan, "beep", "");
04555       }
04556 
04557       /* Store information in real-time storage */
04558       if (ast_check_realtime("voicemail_data")) {
04559          snprintf(priority, sizeof(priority), "%d", chan->priority);
04560          snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL));
04561          get_date(date, sizeof(date));
04562          rtmsgid = ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", category ? category : "", NULL);
04563       }
04564 
04565       /* Store information */
04566       txt = fdopen(txtdes, "w+");
04567       if (txt) {
04568          get_date(date, sizeof(date));
04569          fprintf(txt, 
04570             ";\n"
04571             "; Message Information file\n"
04572             ";\n"
04573             "[message]\n"
04574             "origmailbox=%s\n"
04575             "context=%s\n"
04576             "macrocontext=%s\n"
04577             "exten=%s\n"
04578             "priority=%d\n"
04579             "callerchan=%s\n"
04580             "callerid=%s\n"
04581             "origdate=%s\n"
04582             "origtime=%ld\n"
04583             "category=%s\n",
04584             ext,
04585             chan->context,
04586             chan->macrocontext, 
04587             chan->exten,
04588             chan->priority,
04589             chan->name,
04590             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
04591             date, (long)time(NULL),
04592             category ? category : "");
04593       } else {
04594          ast_log(LOG_WARNING, "Error opening text file for output\n");
04595       }
04596       res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
04597 
04598       if (txt) {
04599          if (duration < vmminsecs) {
04600             fclose(txt);
04601             ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs);
04602             ast_filedelete(tmptxtfile, NULL);
04603             unlink(tmptxtfile);
04604             if (ast_check_realtime("voicemail_data")) {
04605                snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
04606                ast_destroy_realtime("voicemail_data", "id", tmpid, NULL);
04607             }
04608          } else {
04609             fprintf(txt, "duration=%d\n", duration);
04610             fclose(txt);
04611             if (vm_lock_path(dir)) {
04612                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
04613                /* Delete files */
04614                ast_filedelete(tmptxtfile, NULL);
04615                unlink(tmptxtfile);
04616             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
04617                ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
04618                unlink(tmptxtfile);
04619                ast_unlock_path(dir);
04620                if (ast_check_realtime("voicemail_data")) {
04621                   snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
04622                   ast_destroy_realtime("voicemail_data", "id", tmpid, NULL);
04623                }
04624             } else {
04625 #ifndef IMAP_STORAGE
04626                msgnum = last_message_index(vmu, dir) + 1;
04627 #endif
04628                make_file(fn, sizeof(fn), dir, msgnum);
04629 
04630                /* assign a variable with the name of the voicemail file */ 
04631 #ifndef IMAP_STORAGE
04632                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
04633 #else
04634                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04635 #endif
04636 
04637                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
04638                ast_filerename(tmptxtfile, fn, NULL);
04639                rename(tmptxtfile, txtfile);
04640 
04641                /* Properly set permissions on voicemail text descriptor file.
04642                Unfortunately mkstemp() makes this file 0600 on most unix systems. */
04643                if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) {
04644                   ast_log(LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno));
04645                }
04646 
04647                ast_unlock_path(dir);
04648                if (ast_check_realtime("voicemail_data")) {
04649                   snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid);
04650                   snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
04651                   ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, NULL);
04652                }
04653                /* We must store the file first, before copying the message, because
04654                 * ODBC storage does the entire copy with SQL.
04655                 */
04656                if (ast_fileexists(fn, NULL, NULL) > 0) {
04657                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
04658                }
04659 
04660                /* Are there to be more recipients of this message? */
04661                while (tmpptr) {
04662                   struct ast_vm_user recipu, *recip;
04663                   char *exten, *context;
04664 
04665                   exten = strsep(&tmpptr, "&");
04666                   context = strchr(exten, '@');
04667                   if (context) {
04668                      *context = '\0';
04669                      context++;
04670                   }
04671                   if ((recip = find_user(&recipu, context, exten))) {
04672                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
04673                      free_user(recip);
04674                   }
04675                }
04676                /* Notification and disposal needs to happen after the copy, though. */
04677                if (ast_fileexists(fn, NULL, NULL)) {
04678 #ifdef IMAP_STORAGE
04679                   notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04680 #else
04681                   notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04682 #endif
04683                   DISPOSE(dir, msgnum);
04684                }
04685             }
04686          }
04687       }
04688       if (res == '0') {
04689          goto transfer;
04690       } else if (res > 0) {
04691          res = 0;
04692       }
04693 
04694       if (duration < vmminsecs) {
04695          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
04696          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04697       } else {
04698          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
04699       }
04700    } else {
04701       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
04702    }
04703 leave_vm_out:
04704    free_user(vmu);
04705 
04706    ast_free(tmp);
04707    return res;
04708 }

static int load_config ( int  reload  )  [static]

Definition at line 9117 of file app_voicemail.c.

References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_config_option(), ast_copy_string(), ast_debug, ast_false(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_LISTEN_CONTROL_FORWARD_KEY, DEFAULT_LISTEN_CONTROL_PAUSE_KEY, DEFAULT_LISTEN_CONTROL_RESTART_KEY, DEFAULT_LISTEN_CONTROL_REVERSE_KEY, DEFAULT_LISTEN_CONTROL_STOP_KEY, DEFAULT_POLL_FREQ, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), vm_zone::list, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, LOG_ERROR, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, vm_zone::msg_format, pagerbody, pagerfromstring, pagersubject, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, saydurationminfo, SENDMAIL, smdi_iface, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), vm_zone::timezone, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.

09118 {
09119    struct ast_vm_user *cur;
09120    struct ast_config *cfg, *ucfg;
09121    char *cat;
09122    struct ast_variable *var;
09123    const char *val;
09124    char *q, *stringp;
09125    int x;
09126    int tmpadsi[4];
09127    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
09128 
09129    if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
09130       if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
09131          return 0;
09132       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
09133       cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
09134    } else {
09135       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
09136       ucfg = ast_config_load("users.conf", config_flags);
09137    }
09138 #ifdef IMAP_STORAGE
09139    ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder));
09140 #endif
09141    /* set audio control prompts */
09142    strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY);
09143    strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY);
09144    strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY);
09145    strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY);
09146    strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY);
09147 
09148    /* Free all the users structure */  
09149    free_vm_users();
09150 
09151    /* Free all the zones structure */
09152    free_vm_zones();
09153 
09154    AST_LIST_LOCK(&users);  
09155 
09156    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
09157 
09158    if (cfg) {
09159       /* General settings */
09160 
09161       if (!(val = ast_variable_retrieve(cfg, "general", "userscontext")))
09162          val = "default";
09163       ast_copy_string(userscontext, val, sizeof(userscontext));
09164       /* Attach voice message to mail message ? */
09165       if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 
09166          val = "yes";
09167       ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 
09168 
09169       if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts")))
09170          val = "no";
09171       ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH);
09172 
09173       volgain = 0.0;
09174       if ((val = ast_variable_retrieve(cfg, "general", "volgain")))
09175          sscanf(val, "%lf", &volgain);
09176 
09177 #ifdef ODBC_STORAGE
09178       strcpy(odbc_database, "asterisk");
09179       if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
09180          ast_copy_string(odbc_database, val, sizeof(odbc_database));
09181       }
09182       strcpy(odbc_table, "voicemessages");
09183       if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) {
09184          ast_copy_string(odbc_table, val, sizeof(odbc_table));
09185       }
09186 #endif      
09187       /* Mail command */
09188       strcpy(mailcmd, SENDMAIL);
09189       if ((val = ast_variable_retrieve(cfg, "general", "mailcmd")))
09190          ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */
09191 
09192       maxsilence = 0;
09193       if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
09194          maxsilence = atoi(val);
09195          if (maxsilence > 0)
09196             maxsilence *= 1000;
09197       }
09198       
09199       if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
09200          maxmsg = MAXMSG;
09201       } else {
09202          maxmsg = atoi(val);
09203          if (maxmsg <= 0) {
09204             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG);
09205             maxmsg = MAXMSG;
09206          } else if (maxmsg > MAXMSGLIMIT) {
09207             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val);
09208             maxmsg = MAXMSGLIMIT;
09209          }
09210       }
09211 
09212       if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) {
09213          maxdeletedmsg = 0;
09214       } else {
09215          if (sscanf(val, "%d", &x) == 1)
09216             maxdeletedmsg = x;
09217          else if (ast_true(val))
09218             maxdeletedmsg = MAXMSG;
09219          else
09220             maxdeletedmsg = 0;
09221 
09222          if (maxdeletedmsg < 0) {
09223             ast_log(LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG);
09224             maxdeletedmsg = MAXMSG;
09225          } else if (maxdeletedmsg > MAXMSGLIMIT) {
09226             ast_log(LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val);
09227             maxdeletedmsg = MAXMSGLIMIT;
09228          }
09229       }
09230 
09231       /* Load date format config for voicemail mail */
09232       if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
09233          ast_copy_string(emaildateformat, val, sizeof(emaildateformat));
09234       }
09235 
09236       /* External password changing command */
09237       if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) {
09238          ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd));
09239          pwdchange = PWDCHANGE_EXTERNAL;
09240       } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) {
09241          ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd));
09242          pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL;
09243       }
09244 
09245 #ifdef IMAP_STORAGE
09246       /* IMAP server address */
09247       if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) {
09248          ast_copy_string(imapserver, val, sizeof(imapserver));
09249       } else {
09250          ast_copy_string(imapserver, "localhost", sizeof(imapserver));
09251       }
09252       /* IMAP server port */
09253       if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) {
09254          ast_copy_string(imapport, val, sizeof(imapport));
09255       } else {
09256          ast_copy_string(imapport, "143", sizeof(imapport));
09257       }
09258       /* IMAP server flags */
09259       if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) {
09260          ast_copy_string(imapflags, val, sizeof(imapflags));
09261       }
09262       /* IMAP server master username */
09263       if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) {
09264          ast_copy_string(authuser, val, sizeof(authuser));
09265       }
09266       /* IMAP server master password */
09267       if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) {
09268          ast_copy_string(authpassword, val, sizeof(authpassword));
09269       }
09270       /* Expunge on exit */
09271       if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
09272          if (ast_false(val))
09273             expungeonhangup = 0;
09274          else
09275             expungeonhangup = 1;
09276       } else {
09277          expungeonhangup = 1;
09278       }
09279       /* IMAP voicemail folder */
09280       if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
09281          ast_copy_string(imapfolder, val, sizeof(imapfolder));
09282       } else {
09283          ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder));
09284       }
09285       if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) {
09286          ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder));
09287       }
09288       if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) {
09289          imapgreetings = ast_true(val);
09290       } else {
09291          imapgreetings = 0;
09292       }
09293       if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) {
09294          ast_copy_string(greetingfolder, val, sizeof(greetingfolder));
09295       } else {
09296          ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder));
09297       }
09298 
09299       /* There is some very unorthodox casting done here. This is due
09300        * to the way c-client handles the argument passed in. It expects a 
09301        * void pointer and casts the pointer directly to a long without
09302        * first dereferencing it. */
09303       if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
09304          mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val)));
09305       } else {
09306          mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L);
09307       }
09308 
09309       if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
09310          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val)));
09311       } else {
09312          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L);
09313       }
09314 
09315       if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
09316          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val)));
09317       } else {
09318          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L);
09319       }
09320 
09321       if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
09322          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val)));
09323       } else {
09324          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L);
09325       }
09326 
09327 #endif
09328       /* External voicemail notify application */
09329       if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) {
09330          ast_copy_string(externnotify, val, sizeof(externnotify));
09331          ast_debug(1, "found externnotify: %s\n", externnotify);
09332       } else {
09333          externnotify[0] = '\0';
09334       }
09335 
09336       /* SMDI voicemail notification */
09337       if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) {
09338          ast_debug(1, "Enabled SMDI voicemail notification\n");
09339          if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) {
09340             smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find(val) : NULL;
09341          } else {
09342             ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n");
09343             smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find("/dev/ttyS0") : NULL;
09344          }
09345          if (!smdi_iface) {
09346             ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n");
09347          }
09348       }
09349 
09350       /* Silence treshold */
09351       silencethreshold = 256;
09352       if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold")))
09353          silencethreshold = atoi(val);
09354       
09355       if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 
09356          val = ASTERISK_USERNAME;
09357       ast_copy_string(serveremail, val, sizeof(serveremail));
09358       
09359       vmmaxsecs = 0;
09360       if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) {
09361          if (sscanf(val, "%d", &x) == 1) {
09362             vmmaxsecs = x;
09363          } else {
09364             ast_log(LOG_WARNING, "Invalid max message time length\n");
09365          }
09366       } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
09367          static int maxmessage_deprecate = 0;
09368          if (maxmessage_deprecate == 0) {
09369             maxmessage_deprecate = 1;
09370             ast_log(LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n");
09371          }
09372          if (sscanf(val, "%d", &x) == 1) {
09373             vmmaxsecs = x;
09374          } else {
09375             ast_log(LOG_WARNING, "Invalid max message time length\n");
09376          }
09377       }
09378 
09379       vmminsecs = 0;
09380       if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) {
09381          if (sscanf(val, "%d", &x) == 1) {
09382             vmminsecs = x;
09383             if (maxsilence <= vmminsecs)
09384                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
09385          } else {
09386             ast_log(LOG_WARNING, "Invalid min message time length\n");
09387          }
09388       } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) {
09389          static int maxmessage_deprecate = 0;
09390          if (maxmessage_deprecate == 0) {
09391             maxmessage_deprecate = 1;
09392             ast_log(LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n");
09393          }
09394          if (sscanf(val, "%d", &x) == 1) {
09395             vmminsecs = x;
09396             if (maxsilence <= vmminsecs)
09397                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
09398          } else {
09399             ast_log(LOG_WARNING, "Invalid min message time length\n");
09400          }
09401       }
09402 
09403       val = ast_variable_retrieve(cfg, "general", "format");
09404       if (!val)
09405          val = "wav";   
09406       ast_copy_string(vmfmts, val, sizeof(vmfmts));
09407 
09408       skipms = 3000;
09409       if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
09410          if (sscanf(val, "%d", &x) == 1) {
09411             maxgreet = x;
09412          } else {
09413             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
09414          }
09415       }
09416 
09417       if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) {
09418          if (sscanf(val, "%d", &x) == 1) {
09419             skipms = x;
09420          } else {
09421             ast_log(LOG_WARNING, "Invalid skipms value\n");
09422          }
09423       }
09424 
09425       maxlogins = 3;
09426       if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
09427          if (sscanf(val, "%d", &x) == 1) {
09428             maxlogins = x;
09429          } else {
09430             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
09431          }
09432       }
09433 
09434       /* Force new user to record name ? */
09435       if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 
09436          val = "no";
09437       ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME);
09438 
09439       /* Force new user to record greetings ? */
09440       if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
09441          val = "no";
09442       ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET);
09443 
09444       if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) {
09445          ast_debug(1, "VM_CID Internal context string: %s\n", val);
09446          stringp = ast_strdupa(val);
09447          for (x = 0; x < MAX_NUM_CID_CONTEXTS; x++) {
09448             if (!ast_strlen_zero(stringp)) {
09449                q = strsep(&stringp, ",");
09450                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
09451                   q++;
09452                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
09453                ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
09454             } else {
09455                cidinternalcontexts[x][0] = '\0';
09456             }
09457          }
09458       }
09459       if (!(val = ast_variable_retrieve(cfg, "general", "review"))) {
09460          ast_debug(1, "VM Review Option disabled globally\n");
09461          val = "no";
09462       }
09463       ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 
09464 
09465       /* Temporary greeting reminder */
09466       if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
09467          ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n");
09468          val = "no";
09469       } else {
09470          ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n");
09471       }
09472       ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN);
09473 
09474       if (!(val = ast_variable_retrieve(cfg, "general", "operator"))) {
09475          ast_debug(1, "VM Operator break disabled globally\n");
09476          val = "no";
09477       }
09478       ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR);  
09479 
09480       if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) {
09481          ast_debug(1, "VM CID Info before msg disabled globally\n");
09482          val = "no";
09483       } 
09484       ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 
09485 
09486       if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))) {
09487          ast_debug(1, "Send Voicemail msg disabled globally\n");
09488          val = "no";
09489       }
09490       ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL);
09491    
09492       if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) {
09493          ast_debug(1, "ENVELOPE before msg enabled globally\n");
09494          val = "yes";
09495       }
09496       ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE);  
09497 
09498       if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) {
09499          ast_debug(1, "Move Heard enabled globally\n");
09500          val = "yes";
09501       }
09502       ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 
09503 
09504       if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) {
09505          ast_debug(1, "Duration info before msg enabled globally\n");
09506          val = "yes";
09507       }
09508       ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION);  
09509 
09510       saydurationminfo = 2;
09511       if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
09512          if (sscanf(val, "%d", &x) == 1) {
09513             saydurationminfo = x;
09514          } else {
09515             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
09516          }
09517       }
09518 
09519       if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
09520          ast_debug(1, "We are not going to skip to the next msg after save/delete\n");
09521          val = "no";
09522       }
09523       ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD);
09524 
09525       if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) {
09526          ast_copy_string(dialcontext, val, sizeof(dialcontext));
09527          ast_debug(1, "found dialout context: %s\n", dialcontext);
09528       } else {
09529          dialcontext[0] = '\0';  
09530       }
09531       
09532       if ((val = ast_variable_retrieve(cfg, "general", "callback"))) {
09533          ast_copy_string(callcontext, val, sizeof(callcontext));
09534          ast_debug(1, "found callback context: %s\n", callcontext);
09535       } else {
09536          callcontext[0] = '\0';
09537       }
09538 
09539       if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
09540          ast_copy_string(exitcontext, val, sizeof(exitcontext));
09541          ast_debug(1, "found operator context: %s\n", exitcontext);
09542       } else {
09543          exitcontext[0] = '\0';
09544       }
09545       
09546       /* load password sounds configuration */
09547       if ((val = ast_variable_retrieve(cfg, "general", "vm-password")))
09548          ast_copy_string(vm_password, val, sizeof(vm_password));
09549       if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword")))
09550          ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword));
09551       if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged")))
09552          ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged));
09553       if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword")))
09554          ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword));
09555       if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch")))
09556          ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch));
09557       /* load configurable audio prompts */
09558       if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val))
09559          ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key));
09560       if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val))
09561          ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key));
09562       if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val))
09563          ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key));
09564       if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val))
09565          ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key));
09566       if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val))
09567          ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key));
09568 
09569       if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
09570          val = "no";
09571       ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 
09572 
09573       poll_freq = DEFAULT_POLL_FREQ;
09574       if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) {
09575          if (sscanf(val, "%u", &poll_freq) != 1) {
09576             poll_freq = DEFAULT_POLL_FREQ;
09577             ast_log(LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val);
09578          }
09579       }
09580 
09581       poll_mailboxes = 0;
09582       if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes")))
09583          poll_mailboxes = ast_true(val);
09584 
09585       if (ucfg) { 
09586          for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) {
09587             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
09588                continue;
09589             if ((cur = find_or_create(userscontext, cat))) {
09590                populate_defaults(cur);
09591                apply_options_full(cur, ast_variable_browse(ucfg, cat));
09592                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
09593             }
09594          }
09595          ast_config_destroy(ucfg);
09596       }
09597       cat = ast_category_browse(cfg, NULL);
09598       while (cat) {
09599          if (strcasecmp(cat, "general")) {
09600             var = ast_variable_browse(cfg, cat);
09601             if (strcasecmp(cat, "zonemessages")) {
09602                /* Process mailboxes in this context */
09603                while (var) {
09604                   append_mailbox(cat, var->name, var->value);
09605                   var = var->next;
09606                }
09607             } else {
09608                /* Timezones in this context */
09609                while (var) {
09610                   struct vm_zone *z;
09611                   if ((z = ast_malloc(sizeof(*z)))) {
09612                      char *msg_format, *timezone;
09613                      msg_format = ast_strdupa(var->value);
09614                      timezone = strsep(&msg_format, "|");
09615                      if (msg_format) {
09616                         ast_copy_string(z->name, var->name, sizeof(z->name));
09617                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
09618                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
09619                         AST_LIST_LOCK(&zones);
09620                         AST_LIST_INSERT_HEAD(&zones, z, list);
09621                         AST_LIST_UNLOCK(&zones);
09622                      } else {
09623                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
09624                         ast_free(z);
09625                      }
09626                   } else {
09627                      AST_LIST_UNLOCK(&users);
09628                      ast_config_destroy(cfg);
09629                      return -1;
09630                   }
09631                   var = var->next;
09632                }
09633             }
09634          }
09635          cat = ast_category_browse(cfg, cat);
09636       }
09637       memset(fromstring, 0, sizeof(fromstring));
09638       memset(pagerfromstring, 0, sizeof(pagerfromstring));
09639       strcpy(charset, "ISO-8859-1");
09640       if (emailbody) {
09641          ast_free(emailbody);
09642          emailbody = NULL;
09643       }
09644       if (emailsubject) {
09645          ast_free(emailsubject);
09646          emailsubject = NULL;
09647       }
09648       if (pagerbody) {
09649          ast_free(pagerbody);
09650          pagerbody = NULL;
09651       }
09652       if (pagersubject) {
09653          ast_free(pagersubject);
09654          pagersubject = NULL;
09655       }
09656       if ((val = ast_variable_retrieve(cfg, "general", "pbxskip")))
09657          ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP);
09658       if ((val = ast_variable_retrieve(cfg, "general", "fromstring")))
09659          ast_copy_string(fromstring, val, sizeof(fromstring));
09660       if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
09661          ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring));
09662       if ((val = ast_variable_retrieve(cfg, "general", "charset")))
09663          ast_copy_string(charset, val, sizeof(charset));
09664       if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
09665          sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
09666          for (x = 0; x < 4; x++) {
09667             memcpy(&adsifdn[x], &tmpadsi[x], 1);
09668          }
09669       }
09670       if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) {
09671          sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
09672          for (x = 0; x < 4; x++) {
09673             memcpy(&adsisec[x], &tmpadsi[x], 1);
09674          }
09675       }
09676       if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) {
09677          if (atoi(val)) {
09678             adsiver = atoi(val);
09679          }
09680       }
09681       if ((val = ast_variable_retrieve(cfg, "general", "tz"))) {
09682          ast_copy_string(zonetag, val, sizeof(zonetag));
09683       }
09684       if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) {
09685          emailsubject = ast_strdup(val);
09686       }
09687       if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) {
09688          emailbody = substitute_escapes(val);
09689       }
09690       if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) {
09691          pagersubject = ast_strdup(val);
09692       }
09693       if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
09694          pagerbody = substitute_escapes(val);
09695       }
09696       AST_LIST_UNLOCK(&users);
09697       ast_config_destroy(cfg);
09698 
09699       if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL)
09700          start_poll_thread();
09701       if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL)
09702          stop_poll_thread();;
09703 
09704       return 0;
09705    } else {
09706       AST_LIST_UNLOCK(&users);
09707       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
09708       if (ucfg)
09709          ast_config_destroy(ucfg);
09710       return 0;
09711    }
09712 }

static int load_module ( void   )  [static]

Definition at line 9741 of file app_voicemail.c.

References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_install_vm_functions(), ast_manager_register, ast_register_application, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().

09742 {
09743    int res;
09744    my_umask = umask(0);
09745    umask(my_umask);
09746 
09747    /* compute the location of the voicemail spool directory */
09748    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
09749 
09750    if ((res = load_config(0)))
09751       return res;
09752 
09753    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
09754    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
09755    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
09756    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
09757    res |= ast_custom_function_register(&mailbox_exists_acf);
09758    res |= ast_manager_register("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users, "List All Voicemail User Information");
09759    if (res)
09760       return res;
09761 
09762    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
09763 
09764    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
09765 
09766    return res;
09767 }

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

Definition at line 1046 of file app_voicemail.c.

01047 {
01048    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
01049 }

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

Creates the email file to be sent to indicate a new voicemail exists for a user.

Parameters:
p The output file to generate the email contents into.
srcemail The email address to send the email to, presumably the email address for the owner of the mailbox.
vmu The voicemail user who is sending the voicemail.
msgnum The message index in the mailbox folder.
context 
mailbox The voicemail box to read the voicemail to be notified in this email.
cidnum The caller ID number.
cidname The caller ID name.
attach the name of the sound file to be attached to the email, if attach_user_voicemail == 1.
format The message sound file format. i.e. .wav
duration The time of the message content, in seconds.
attach_user_voicemail if 1, the sound file is attached to the email.
chan 
category 
imap if == 1, indicates the target folder for the email notification to be sent to will be an IMAP mailstore. This causes additional mailbox headers to be set, which would facilitate searching for the email in the destination IMAP folder.
The email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email. That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function.

Definition at line 3457 of file app_voicemail.c.

References ast_channel_alloc, ast_channel_free(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), base_encode(), chan, charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, create_dirpath(), ast_vm_user::email, emailbody, emaildateformat, emailsubject, encode_mime_str(), ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), strip_control(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

03458 {
03459    char date[256];
03460    char host[MAXHOSTNAMELEN] = "";
03461    char who[256];
03462    char bound[256];
03463    char fname[256];
03464    char dur[256];
03465    char tmpcmd[256];
03466    struct ast_tm tm;
03467    char enc_cidnum[256] = "", enc_cidname[256] = "";
03468    char *passdata = NULL, *passdata2;
03469    size_t len_passdata = 0, len_passdata2, tmplen;
03470    char *greeting_attachment;
03471 
03472 #ifdef IMAP_STORAGE
03473 #define ENDL "\r\n"
03474 #else
03475 #define ENDL "\n"
03476 #endif
03477 
03478    /* One alloca for multiple fields */
03479    len_passdata2 = strlen(vmu->fullname);
03480    if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) {
03481       len_passdata2 = tmplen;
03482    }
03483    if ((tmplen = strlen(fromstring)) > len_passdata2) {
03484       len_passdata2 = tmplen;
03485    }
03486    len_passdata2 = len_passdata2 * 3 + 200;
03487    passdata2 = alloca(len_passdata2);
03488 
03489    if (!ast_strlen_zero(cidnum)) {
03490       strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum));
03491    }
03492    if (!ast_strlen_zero(cidname)) {
03493       strip_control(cidname, enc_cidname, sizeof(enc_cidname));
03494    }
03495    gethostname(host, sizeof(host) - 1);
03496 
03497    if (strchr(srcemail, '@'))
03498       ast_copy_string(who, srcemail, sizeof(who));
03499    else 
03500       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03501    
03502    greeting_attachment = strrchr(ast_strdupa(attach), '/');
03503    if (greeting_attachment)
03504       *greeting_attachment++ = '\0';
03505 
03506    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03507    ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03508    fprintf(p, "Date: %s" ENDL, date);
03509 
03510    /* Set date format for voicemail mail */
03511    ast_strftime(date, sizeof(date), emaildateformat, &tm);
03512 
03513    if (!ast_strlen_zero(fromstring)) {
03514       struct ast_channel *ast;
03515       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03516          char *ptr;
03517          memset(passdata2, 0, len_passdata2);
03518          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category);
03519          pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2);
03520          len_passdata = strlen(passdata2) * 3 + 300;
03521          passdata = alloca(len_passdata);
03522          if (check_mime(passdata2)) {
03523             int first_line = 1;
03524             encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3);
03525             while ((ptr = strchr(passdata, ' '))) {
03526                *ptr = '\0';
03527                fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata);
03528                first_line = 0;
03529                passdata = ptr + 1;
03530             }
03531             fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who);
03532          } else {
03533             fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who);
03534          }
03535          ast_channel_free(ast);
03536       } else {
03537          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03538       }
03539    } else {
03540       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
03541    }
03542 
03543    if (check_mime(vmu->fullname)) {
03544       int first_line = 1;
03545       char *ptr;
03546       encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3);
03547       while ((ptr = strchr(passdata2, ' '))) {
03548          *ptr = '\0';
03549          fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2);
03550          first_line = 0;
03551          passdata2 = ptr + 1;
03552       }
03553       fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email);
03554    } else {
03555       fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email);
03556    }
03557    if (!ast_strlen_zero(emailsubject)) {
03558       struct ast_channel *ast;
03559       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03560          int vmlen = strlen(emailsubject) * 3 + 200;
03561          /* Only allocate more space if the previous was not large enough */
03562          if (vmlen > len_passdata) {
03563             passdata = alloca(vmlen);
03564             len_passdata = vmlen;
03565          }
03566 
03567          memset(passdata, 0, len_passdata);
03568          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category);
03569          pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata);
03570          if (check_mime(passdata)) {
03571             int first_line = 1;
03572             char *ptr;
03573             encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0);
03574             while ((ptr = strchr(passdata2, ' '))) {
03575                *ptr = '\0';
03576                fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03577                first_line = 0;
03578                passdata2 = ptr + 1;
03579             }
03580             fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03581          } else {
03582             fprintf(p, "Subject: %s" ENDL, passdata);
03583          }
03584          ast_channel_free(ast);
03585       } else {
03586          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03587       }
03588    } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
03589       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03590    } else {
03591       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03592    }
03593 
03594    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
03595    if (imap) {
03596       /* additional information needed for IMAP searching */
03597       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
03598       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
03599       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
03600       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
03601 #ifdef IMAP_STORAGE
03602       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
03603 #else
03604       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
03605 #endif
03606       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
03607       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
03608       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
03609       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
03610       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
03611       if (!ast_strlen_zero(category)) {
03612          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
03613       } else {
03614          fprintf(p, "X-Asterisk-VM-Category: " ENDL);
03615       }
03616       fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment);
03617       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
03618       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
03619    }
03620    if (!ast_strlen_zero(cidnum)) {
03621       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
03622    }
03623    if (!ast_strlen_zero(cidname)) {
03624       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
03625    }
03626    fprintf(p, "MIME-Version: 1.0" ENDL);
03627    if (attach_user_voicemail) {
03628       /* Something unique. */
03629       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
03630 
03631       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
03632       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
03633       fprintf(p, "--%s" ENDL, bound);
03634    }
03635    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
03636    if (emailbody) {
03637       struct ast_channel *ast;
03638       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03639          char *passdata;
03640          int vmlen = strlen(emailbody) * 3 + 200;
03641          passdata = alloca(vmlen);
03642          memset(passdata, 0, vmlen);
03643          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03644          pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
03645          fprintf(p, "%s" ENDL, passdata);
03646          ast_channel_free(ast);
03647       } else
03648          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03649    } else if (msgnum > -1) {
03650       if (strcmp(vmu->mailbox, mailbox)) {
03651          /* Forwarded type */
03652          struct ast_config *msg_cfg;
03653          const char *v;
03654          int inttime;
03655          char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = "";
03656          struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
03657          /* Retrieve info from VM attribute file */
03658          make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03659          make_file(fromfile, sizeof(fromfile), fromdir, msgnum);
03660          if (strlen(fromfile) < sizeof(fromfile) - 5) {
03661             strcat(fromfile, ".txt");
03662          }
03663          if ((msg_cfg = ast_config_load(fromfile, config_flags))) {
03664             if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03665                ast_copy_string(origcallerid, v, sizeof(origcallerid));
03666             }
03667 
03668             /* You might be tempted to do origdate, except that a) it's in the wrong
03669              * format, and b) it's missing for IMAP recordings. */
03670             if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%d", &inttime) == 1) {
03671                struct timeval tv = { inttime, };
03672                struct ast_tm tm;
03673                ast_localtime(&tv, &tm, NULL);
03674                ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03675             }
03676             fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded"
03677                " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL
03678                "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a"
03679                " chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur,
03680                msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")),
03681                date, origcallerid, origdate);
03682             ast_config_destroy(msg_cfg);
03683          } else {
03684             goto plain_message;
03685          }
03686       } else {
03687 plain_message:
03688          fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a "
03689             "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL
03690             "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk"
03691             ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox,
03692             (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
03693       }
03694    } else {
03695       fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL
03696             "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date);
03697    }
03698    if (attach_user_voicemail) {
03699       /* Eww. We want formats to tell us their own MIME type */
03700       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
03701       char tmpdir[256], newtmp[256];
03702       int tmpfd = -1;
03703    
03704       if (vmu->volgain < -.001 || vmu->volgain > .001) {
03705          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
03706          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
03707          tmpfd = mkstemp(newtmp);
03708          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
03709          ast_debug(3, "newtmp: %s\n", newtmp);
03710          if (tmpfd > -1) {
03711             int soxstatus;
03712             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
03713             if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
03714                attach = newtmp;
03715                ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
03716             } else {
03717                ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
03718                   soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
03719                ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
03720             }
03721          }
03722       }
03723       fprintf(p, "--%s" ENDL, bound);
03724       if (msgnum > -1)
03725          fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
03726       else
03727          fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format);
03728       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
03729       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
03730       if (msgnum > -1)
03731          fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
03732       else
03733          fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format);
03734       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
03735       base_encode(fname, p);
03736       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
03737       if (tmpfd > -1) {
03738          unlink(fname);
03739          close(tmpfd);
03740          unlink(newtmp);
03741       }
03742    }
03743 #undef ENDL
03744 }

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

Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.

Parameters:
dest The variable to hold the output generated path expression. This buffer should be of size PATH_MAX.
len The length of the path string that was written out.
The path is constructed as VM_SPOOL_DIRcontext/ext/folder

Returns:
zero on success, -1 on error.

Definition at line 1061 of file app_voicemail.c.

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

01062 {
01063    return snprintf(dest, len, "%s/msg%04d", dir, num);
01064 }

static int manager_list_voicemail_users ( struct mansession s,
const struct message m 
) [static]

Manager list voicemail users command.

Definition at line 8949 of file app_voicemail.c.

References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_ack(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::context, count_messages(), ast_vm_user::dialout, ast_vm_user::email, ast_vm_user::exit, ast_vm_user::fullname, inboxcount(), ast_vm_user::language, ast_vm_user::list, ast_vm_user::mailbox, ast_vm_user::mailcmd, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, s, ast_vm_user::saydurationm, ast_vm_user::serveremail, ast_vm_user::uniqueid, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_OPERATOR, VM_REVIEW, VM_SAYCID, ast_vm_user::volgain, and ast_vm_user::zonetag.

Referenced by load_module().

08950 {
08951    struct ast_vm_user *vmu = NULL;
08952    const char *id = astman_get_header(m, "ActionID");
08953    char actionid[128] = "";
08954 
08955    if (!ast_strlen_zero(id))
08956       snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id);
08957 
08958    AST_LIST_LOCK(&users);
08959 
08960    if (AST_LIST_EMPTY(&users)) {
08961       astman_send_ack(s, m, "There are no voicemail users currently defined.");
08962       AST_LIST_UNLOCK(&users);
08963       astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid);
08964       return RESULT_SUCCESS;
08965    }
08966    
08967    astman_send_ack(s, m, "Voicemail user list will follow");
08968    
08969    AST_LIST_TRAVERSE(&users, vmu, list) {
08970       char dirname[256];
08971 
08972 #ifdef IMAP_STORAGE
08973       int new, old;
08974       inboxcount (vmu->mailbox, &new, &old);
08975 #endif
08976       
08977       make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX");
08978       astman_append(s,
08979          "%s"
08980          "Event: VoicemailUserEntry\r\n"
08981          "VMContext: %s\r\n"
08982          "VoiceMailbox: %s\r\n"
08983          "Fullname: %s\r\n"
08984          "Email: %s\r\n"
08985          "Pager: %s\r\n"
08986          "ServerEmail: %s\r\n"
08987          "MailCommand: %s\r\n"
08988          "Language: %s\r\n"
08989          "TimeZone: %s\r\n"
08990          "Callback: %s\r\n"
08991          "Dialout: %s\r\n"
08992          "UniqueID: %s\r\n"
08993          "ExitContext: %s\r\n"
08994          "SayDurationMinimum: %d\r\n"
08995          "SayEnvelope: %s\r\n"
08996          "SayCID: %s\r\n"
08997          "AttachMessage: %s\r\n"
08998          "AttachmentFormat: %s\r\n"
08999          "DeleteMessage: %s\r\n"
09000          "VolumeGain: %.2f\r\n"
09001          "CanReview: %s\r\n"
09002          "CallOperator: %s\r\n"
09003          "MaxMessageCount: %d\r\n"
09004          "MaxMessageLength: %d\r\n"
09005          "NewMessageCount: %d\r\n"
09006 #ifdef IMAP_STORAGE
09007          "OldMessageCount: %d\r\n"
09008          "IMAPUser: %s\r\n"
09009 #endif
09010          "\r\n",
09011          actionid,
09012          vmu->context,
09013          vmu->mailbox,
09014          vmu->fullname,
09015          vmu->email,
09016          vmu->pager,
09017          vmu->serveremail,
09018          vmu->mailcmd,
09019          vmu->language,
09020          vmu->zonetag,
09021          vmu->callback,
09022          vmu->dialout,
09023          vmu->uniqueid,
09024          vmu->exit,
09025          vmu->saydurationm,
09026          ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No",
09027          ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No",
09028          ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No",
09029          vmu->attachfmt,
09030          ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No",
09031          vmu->volgain,
09032          ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No",
09033          ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No",
09034          vmu->maxmsg,
09035          vmu->maxsecs,
09036 #ifdef IMAP_STORAGE
09037          new, old, vmu->imapuser
09038 #else
09039          count_messages(vmu, dirname)
09040 #endif
09041          );
09042    }     
09043    astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid);
09044 
09045    AST_LIST_UNLOCK(&users);
09046 
09047    return RESULT_SUCCESS;
09048 }

static void* mb_poll_thread ( void *  data  )  [static]

Definition at line 8806 of file app_voicemail.c.

References ast_cond_timedwait(), ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_lock, and poll_subscribed_mailboxes().

Referenced by start_poll_thread().

08807 {
08808    while (poll_thread_run) {
08809       struct timespec ts = { 0, };
08810       struct timeval tv;
08811 
08812       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1));
08813       ts.tv_sec = tv.tv_sec;
08814       ts.tv_nsec = tv.tv_usec * 1000;
08815 
08816       ast_mutex_lock(&poll_lock);
08817       ast_cond_timedwait(&poll_cond, &poll_lock, &ts);
08818       ast_mutex_unlock(&poll_lock);
08819 
08820       if (!poll_thread_run)
08821          break;
08822 
08823       poll_subscribed_mailboxes();
08824    }
08825 
08826    return NULL;
08827 }

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

Definition at line 1103 of file app_voicemail.c.

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

01104 {
01105    static const char *msgs[] = {
01106 #ifdef IMAP_STORAGE
01107       imapfolder,
01108 #else
01109       "INBOX",
01110 #endif
01111       "Old",
01112       "Work",
01113       "Family",
01114       "Friends",
01115       "Cust1",
01116       "Cust2",
01117       "Cust3",
01118       "Cust4",
01119       "Cust5",
01120       "Deleted",
01121       "Urgent"
01122    };
01123    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown";
01124 }

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

Definition at line 4113 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

04114    {
04115       return __has_voicemail(context, mailbox, folder, 0);
04116    }

static void mwi_sub_destroy ( struct mwi_sub mwi_sub  )  [static]

Definition at line 8829 of file app_voicemail.c.

References ast_free.

Referenced by mwi_unsub_event_cb().

08830 {
08831    ast_free(mwi_sub);
08832 }

static void mwi_sub_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 8861 of file app_voicemail.c.

References ast_calloc, ast_event_get_ie_str(), ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_SUB, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub::mailbox, and mwi_sub::uniqueid.

Referenced by start_poll_thread().

08862 {
08863    const char *mailbox;
08864    const char *context;
08865    uint32_t uniqueid;
08866    unsigned int len;
08867    struct mwi_sub *mwi_sub;
08868 
08869    if (ast_event_get_type(event) != AST_EVENT_SUB)
08870       return;
08871 
08872    if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI)
08873       return;
08874 
08875    mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
08876    context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
08877    uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID);
08878 
08879    len = sizeof(*mwi_sub);
08880    if (!ast_strlen_zero(mailbox))
08881       len += strlen(mailbox);
08882 
08883    if (!ast_strlen_zero(context))
08884       len += strlen(context) + 1; /* Allow for seperator */
08885 
08886    if (!(mwi_sub = ast_calloc(1, len)))
08887       return;
08888 
08889    mwi_sub->uniqueid = uniqueid;
08890    if (!ast_strlen_zero(mailbox))
08891       strcpy(mwi_sub->mailbox, mailbox);
08892 
08893    if (!ast_strlen_zero(context)) {
08894       strcat(mwi_sub->mailbox, "@");
08895       strcat(mwi_sub->mailbox, context);
08896    }
08897 
08898    AST_RWLIST_WRLOCK(&mwi_subs);
08899    AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry);
08900    AST_RWLIST_UNLOCK(&mwi_subs);
08901 }

static void mwi_unsub_event_cb ( const struct ast_event event,
void *  userdata 
) [static]

Definition at line 8834 of file app_voicemail.c.

References ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, AST_LIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, mwi_sub::entry, mwi_sub_destroy(), and mwi_sub::uniqueid.

Referenced by start_poll_thread().

08835 {
08836    uint32_t uniqueid;
08837    struct mwi_sub *mwi_sub;
08838 
08839    if (ast_event_get_type(event) != AST_EVENT_UNSUB)
08840       return;
08841 
08842    if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI)
08843       return;
08844 
08845    uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID);
08846 
08847    AST_RWLIST_WRLOCK(&mwi_subs);
08848    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) {
08849       if (mwi_sub->uniqueid == uniqueid) {
08850          AST_LIST_REMOVE_CURRENT(entry);
08851          break;
08852       }
08853    }
08854    AST_RWLIST_TRAVERSE_SAFE_END
08855    AST_RWLIST_UNLOCK(&mwi_subs);
08856 
08857    if (mwi_sub)
08858       mwi_sub_destroy(mwi_sub);
08859 }

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

Definition at line 5487 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, chan, 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(), queue_mwi_event(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, strsep(), VM_ATTACH, and VM_DELETE.

05488    {
05489       char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
05490       int newmsgs = 0, oldmsgs = 0;
05491       const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
05492       char *myserveremail = serveremail;
05493 
05494       make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
05495       make_file(fn, sizeof(fn), todir, msgnum);
05496       snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
05497 
05498       if (!ast_strlen_zero(vmu->attachfmt)) {
05499          if (strstr(fmt, vmu->attachfmt))
05500             fmt = vmu->attachfmt;
05501          else
05502             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);
05503       }
05504 
05505       /* Attach only the first format */
05506       fmt = ast_strdupa(fmt);
05507       stringp = fmt;
05508       strsep(&stringp, "|");
05509 
05510       if (!ast_strlen_zero(vmu->serveremail))
05511          myserveremail = vmu->serveremail;
05512 
05513       if (!ast_strlen_zero(vmu->email)) {
05514          int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
05515          if (!attach_user_voicemail)
05516             attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
05517 
05518          if (attach_user_voicemail)
05519             RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
05520 
05521          /* XXX possible imap issue, should category be NULL XXX */
05522          sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
05523 
05524          if (attach_user_voicemail)
05525             DISPOSE(todir, msgnum);
05526       }
05527 
05528       if (!ast_strlen_zero(vmu->pager)) {
05529          sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category);
05530       }
05531 
05532       if (ast_test_flag(vmu, VM_DELETE))
05533          DELETE(todir, msgnum, fn, vmu);
05534 
05535       /* Leave voicemail for someone */
05536       if (ast_app_has_voicemail(ext_context, NULL)) 
05537          ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
05538 
05539       queue_mwi_event(ext_context, newmsgs, oldmsgs);
05540 
05541       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);
05542       run_externnotify(vmu->context, vmu->mailbox);
05543 
05544       return 0;
05545    }

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

Definition at line 3203 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

03204 {
03205    if (bio->linelength >= BASELINELEN) {
03206       if (fputs(eol, so) == EOF)
03207          return -1;
03208 
03209       bio->linelength= 0;
03210    }
03211 
03212    if (putc(((unsigned char)c), so) == EOF)
03213       return -1;
03214 
03215    bio->linelength++;
03216 
03217    return 1;
03218 }

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

Definition at line 6163 of file app_voicemail.c.

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

Referenced by vm_execmain().

06164 {
06165    int res = 0;
06166    int count_msg, last_msg;
06167 
06168    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
06169    
06170    /* Rename the member vmbox HERE so that we don't try to return before
06171     * we know what's going on.
06172     */
06173    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
06174    
06175    /* Faster to make the directory than to check if it exists. */
06176    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
06177 
06178    count_msg = count_messages(vmu, vms->curdir);
06179    if (count_msg < 0)
06180       return count_msg;
06181    else
06182       vms->lastmsg = count_msg - 1;
06183 
06184    /*
06185    The following test is needed in case sequencing gets messed up.
06186    There appears to be more than one way to mess up sequence, so
06187    we will not try to find all of the root causes--just fix it when
06188    detected.
06189    */
06190 
06191    if (vm_lock_path(vms->curdir)) {
06192       ast_log(LOG_ERROR, "Could not open mailbox %s:  mailbox is locked\n", vms->curdir);
06193       return -1;
06194    }
06195 
06196    last_msg = last_message_index(vmu, vms->curdir);
06197    ast_unlock_path(vms->curdir);
06198 
06199    if (last_msg < 0) 
06200       return last_msg;
06201    else if (vms->lastmsg != last_msg) {
06202       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
06203       res = resequence_mailbox(vmu, vms->curdir);
06204       if (res)
06205          return res;
06206    }
06207 
06208    return 0;
06209 }

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

Definition at line 3865 of file app_voicemail.c.

References ast_debug, ast_fileexists(), ast_streamfile(), ast_waitstream(), chan, ast_vm_user::context, DISPOSE, ast_channel::language, ast_vm_user::mailbox, and RETRIEVE.

Referenced by invent_message().

03866 {
03867    int res = -2;
03868    
03869 #ifdef ODBC_STORAGE
03870    int success = 
03871 #endif
03872    RETRIEVE(filename, -1, vmu->mailbox, vmu->context);
03873    if (ast_fileexists(filename, NULL, NULL) > 0) {
03874       res = ast_streamfile(chan, filename, chan->language);
03875       if (res > -1) 
03876          res = ast_waitstream(chan, ecodes);
03877 #ifdef ODBC_STORAGE
03878       if (success == -1) {
03879          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03880          ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03881          store_file(filename, vmu->mailbox, vmu->context, -1);
03882       }
03883 #endif
03884    }
03885    DISPOSE(filename, -1);
03886 
03887    return res;
03888 }

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

Definition at line 5999 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(), chan, CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::fn2, vm_state::heard, ast_channel::language, vm_state::lastmsg, ast_vm_user::mailbox, 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(), vm_browse_messages_tw(), and vm_execmain().

06000    {
06001       int res = 0;
06002       char filename[256], *cid;
06003       const char *origtime, *context, *category, *duration;
06004       struct ast_config *msg_cfg;
06005       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
06006 
06007       vms->starting = 0; 
06008       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
06009       adsi_message(chan, vms);
06010       if (!vms->curmsg)
06011          res = wait_file2(chan, vms, "vm-first");  /* "First" */
06012       else if (vms->curmsg == vms->lastmsg)
06013          res = wait_file2(chan, vms, "vm-last");      /* "last" */
06014       if (!res) {
06015          /* POLISH syntax */
06016          if (!strcasecmp(chan->language, "pl")) { 
06017             if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
06018                int ten, one;
06019                char nextmsg[256];
06020                ten = (vms->curmsg + 1) / 10;
06021                one = (vms->curmsg + 1) % 10;
06022                
06023                if (vms->curmsg < 20) {
06024                   snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
06025                   res = wait_file2(chan, vms, nextmsg);
06026                } else {
06027                   snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
06028                   res = wait_file2(chan, vms, nextmsg);
06029                   if (one > 0) {
06030                      if (!res) {
06031                         snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
06032                         res = wait_file2(chan, vms, nextmsg);
06033                      }
06034                   }
06035                }
06036             }
06037             if (!res)
06038                res = wait_file2(chan, vms, "vm-message");
06039          } else {
06040             if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */
06041                res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
06042             else /* DEFAULT syntax */ {
06043                res = wait_file2(chan, vms, "vm-message");
06044             }
06045             if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
06046                if (!res) {
06047                   res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
06048                }
06049             }
06050          }
06051       }
06052 
06053       /* Retrieve info from VM attribute file */
06054       make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
06055       snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
06056       RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
06057       msg_cfg = ast_config_load(filename, config_flags);
06058       if (!msg_cfg) {
06059          ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
06060          return 0;
06061       }
06062 
06063       if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
06064          ast_log(LOG_WARNING, "No origtime?!\n");
06065          DISPOSE(vms->curdir, vms->curmsg);
06066          ast_config_destroy(msg_cfg);
06067          return 0;
06068       }
06069 
06070       cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
06071       duration = ast_variable_retrieve(msg_cfg, "message", "duration");
06072       category = ast_variable_retrieve(msg_cfg, "message", "category");
06073 
06074       context = ast_variable_retrieve(msg_cfg, "message", "context");
06075       if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
06076          context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
06077       if (!res) {
06078          res = play_message_category(chan, category);
06079       }
06080       if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
06081          res = play_message_datetime(chan, vmu, origtime, filename);
06082       if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
06083          res = play_message_callerid(chan, vms, cid, context, 0);
06084       if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
06085          res = play_message_duration(chan, vms, duration, vmu->saydurationm);
06086       /* Allow pressing '1' to skip envelope / callerid */
06087       if (res == '1')
06088          res = 0;
06089       ast_config_destroy(msg_cfg);
06090 
06091       if (!res) {
06092          make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
06093          vms->heard[vms->curmsg] = 1;
06094          if ((res = wait_file(chan, vms, vms->fn)) < 0) {
06095             ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
06096             res = 0;
06097          }
06098       }
06099       DISPOSE(vms->curdir, vms->curmsg);
06100       return res;
06101    }

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

Definition at line 5885 of file app_voicemail.c.

References ast_callerid_parse(), ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verb, chan, cidinternalcontexts, ast_channel::language, MAX_NUM_CID_CONTEXTS, name, and wait_file2().

Referenced by advanced_options(), and play_message().

05886    {
05887       int res = 0;
05888       int i;
05889       char *callerid, *name;
05890       char prefile[PATH_MAX] = "";
05891       
05892 
05893       /* If voicemail cid is not enabled, or we didn't get cid or context from
05894       * the attribute file, leave now.
05895       *
05896       * TODO Still need to change this so that if this function is called by the
05897       * message envelope (and someone is explicitly requesting to hear the CID),
05898       * it does not check to see if CID is enabled in the config file.
05899       */
05900       if ((cid == NULL)||(context == NULL))
05901          return res;
05902 
05903       /* Strip off caller ID number from name */
05904       ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05905       ast_callerid_parse(cid, &name, &callerid);
05906       if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05907          /* Check for internal contexts and only */
05908          /* say extension when the call didn't come from an internal context in the list */
05909          for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++) {
05910             ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05911             if ((strcmp(cidinternalcontexts[i], context) == 0))
05912                break;
05913          }
05914          if (i != MAX_NUM_CID_CONTEXTS) { /* internal context? */
05915             if (!res) {
05916                snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05917                if (!ast_strlen_zero(prefile)) {
05918                /* See if we can find a recorded name for this person instead of their extension number */
05919                   if (ast_fileexists(prefile, NULL, NULL) > 0) {
05920                      ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05921                      if (!callback)
05922                         res = wait_file2(chan, vms, "vm-from");
05923                      res = ast_stream_and_wait(chan, prefile, "");
05924                   } else {
05925                      ast_verb(3, "Playing envelope info: message from '%s'\n", callerid);
05926                      /* Say "from extension" as one saying to sound smoother */
05927                      if (!callback)
05928                         res = wait_file2(chan, vms, "vm-from-extension");
05929                      res = ast_say_digit_str(chan, callerid, "", chan->language);
05930                   }
05931                }
05932             }
05933          } else if (!res) {
05934             ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid);
05935             /* Since this is all nicely figured out, why not say "from phone number" in this case? */
05936             if (!callback)
05937                res = wait_file2(chan, vms, "vm-from-phonenumber");
05938             res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05939          }
05940       } else {
05941          /* Number unknown */
05942          ast_debug(1, "VM-CID: From an unknown number\n");
05943          /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05944          res = wait_file2(chan, vms, "vm-unknown-caller");
05945       }
05946       return res;
05947    }

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

Definition at line 5797 of file app_voicemail.c.

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

Referenced by play_message().

05798    {
05799       int res = 0;
05800 
05801       if (!ast_strlen_zero(category))
05802          res = ast_play_and_wait(chan, category);
05803 
05804       if (res) {
05805          ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05806          res = 0;
05807       }
05808 
05809       return res;
05810    }

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

Definition at line 5812 of file app_voicemail.c.

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

Referenced by advanced_options(), and play_message().

05813    {
05814       int res = 0;
05815       struct vm_zone *the_zone = NULL;
05816       time_t t;
05817 
05818       if (ast_get_time_t(origtime, &t, 0, NULL)) {
05819          ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05820          return 0;
05821       }
05822 
05823       /* Does this user have a timezone specified? */
05824       if (!ast_strlen_zero(vmu->zonetag)) {
05825          /* Find the zone in the list */
05826          struct vm_zone *z;
05827          AST_LIST_LOCK(&zones);
05828          AST_LIST_TRAVERSE(&zones, z, list) {
05829             if (!strcmp(z->name, vmu->zonetag)) {
05830                the_zone = z;
05831                break;
05832             }
05833          }
05834          AST_LIST_UNLOCK(&zones);
05835       }
05836 
05837    /* No internal variable parsing for now, so we'll comment it out for the time being */
05838 #if 0
05839       /* Set the DIFF_* variables */
05840       ast_localtime(&t, &time_now, NULL);
05841       tv_now = ast_tvnow();
05842       ast_localtime(&tv_now, &time_then, NULL);
05843 
05844       /* Day difference */
05845       if (time_now.tm_year == time_then.tm_year)
05846          snprintf(temp, sizeof(temp), "%d", time_now.tm_yday);
05847       else
05848          snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05849       pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05850 
05851       /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05852 #endif
05853       if (the_zone) {
05854          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05855       }
05856       else if (!strcasecmp(chan->language,"pl"))       /* POLISH syntax */
05857          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05858       else if (!strcasecmp(chan->language, "se"))       /* SWEDISH syntax */
05859          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05860       else if (!strcasecmp(chan->language, "no"))       /* NORWEGIAN syntax */
05861          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05862       else if (!strcasecmp(chan->language, "de"))       /* GERMAN syntax */
05863          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05864       else if (!strcasecmp(chan->language, "nl"))      /* DUTCH syntax */
05865          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05866       else if (!strcasecmp(chan->language, "it"))      /* ITALIAN syntax */
05867          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);
05868       else if (!strcasecmp(chan->language, "gr"))
05869          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05870       else if (!strcasecmp(chan->language, "pt_BR"))
05871          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);
05872       else if (!strcasecmp(chan->language, "tw"))      /* CHINESE (Taiwan) syntax */
05873          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL);     
05874       else {
05875          res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05876       }
05877 #if 0
05878       pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05879 #endif
05880       return res;
05881    }

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

Definition at line 5949 of file app_voicemail.c.

References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), chan, ast_channel::language, num, say_and_wait(), and wait_file2().

Referenced by play_message().

05950    {
05951       int res = 0;
05952       int durationm;
05953       int durations;
05954       /* Verify that we have a duration for the message */
05955       if (duration == NULL)
05956          return res;
05957 
05958       /* Convert from seconds to minutes */
05959       durations = atoi(duration);
05960       durationm = durations / 60;
05961 
05962       ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05963 
05964       if ((!res) && (durationm >= minduration)) {
05965          res = wait_file2(chan, vms, "vm-duration");
05966 
05967          /* POLISH syntax */
05968          if (!strcasecmp(chan->language, "pl")) {
05969             div_t num = div(durationm, 10);
05970 
05971             if (durationm == 1) {
05972                res = ast_play_and_wait(chan, "digits/1z");
05973                res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05974             } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05975                if (num.rem == 2) {
05976                   if (!num.quot) {
05977                      res = ast_play_and_wait(chan, "digits/2-ie");
05978                   } else {
05979                      res = say_and_wait(chan, durationm - 2 , chan->language);
05980                      res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05981                   }
05982                } else {
05983                   res = say_and_wait(chan, durationm, chan->language);
05984                }
05985                res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05986             } else {
05987                res = say_and_wait(chan, durationm, chan->language);
05988                res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05989             }
05990          /* DEFAULT syntax */
05991          } else {
05992             res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05993             res = wait_file2(chan, vms, "vm-minutes");
05994          }
05995       }
05996       return res;
05997    }

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

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

10019 {
10020    /* Record message & let caller review or re-record it, or set options if applicable */
10021    int res = 0;
10022    int cmd = 0;
10023    int max_attempts = 3;
10024    int attempts = 0;
10025    int recorded = 0;
10026    int message_exists = 0;
10027    signed char zero_gain = 0;
10028    char tempfile[PATH_MAX];
10029    char *acceptdtmf = "#";
10030    char *canceldtmf = "";
10031 
10032    /* Note that urgent and private are for flagging messages as such in the future */
10033 
10034    /* barf if no pointer passed to store duration in */
10035    if (duration == NULL) {
10036       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
10037       return -1;
10038    }
10039 
10040    if (!outsidecaller)
10041       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
10042    else
10043       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
10044 
10045    cmd = '3';  /* Want to start by recording */
10046 
10047    while ((cmd >= 0) && (cmd != 't')) {
10048       switch (cmd) {
10049       case '1':
10050          if (!message_exists) {
10051             /* In this case, 1 is to record a message */
10052             cmd = '3';
10053             break;
10054          } else {
10055             /* Otherwise 1 is to save the existing message */
10056             ast_verb(3, "Saving message as is\n");
10057             if (!outsidecaller) 
10058                ast_filerename(tempfile, recordfile, NULL);
10059             ast_stream_and_wait(chan, "vm-msgsaved", "");
10060             if (!outsidecaller) {
10061                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
10062                DISPOSE(recordfile, -1);
10063             }
10064             cmd = 't';
10065             return res;
10066          }
10067       case '2':
10068          /* Review */
10069          ast_verb(3, "Reviewing the message\n");
10070          cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY);
10071          break;
10072       case '3':
10073          message_exists = 0;
10074          /* Record */
10075          if (recorded == 1) 
10076             ast_verb(3, "Re-recording the message\n");
10077          else  
10078             ast_verb(3, "Recording the message\n");
10079          
10080          if (recorded && outsidecaller) {
10081             cmd = ast_play_and_wait(chan, INTRO);
10082             cmd = ast_play_and_wait(chan, "beep");
10083          }
10084          recorded = 1;
10085          /* 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 */
10086          if (record_gain)
10087             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
10088          if (ast_test_flag(vmu, VM_OPERATOR))
10089             canceldtmf = "0";
10090          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
10091          if (record_gain)
10092             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
10093          if (cmd == -1) {
10094             /* User has hung up, no options to give */
10095             if (!outsidecaller) {
10096                /* user was recording a greeting and they hung up, so let's delete the recording. */
10097                ast_filedelete(tempfile, NULL);
10098             }     
10099             return cmd;
10100          }
10101          if (cmd == '0') {
10102             break;
10103          } else if (cmd == '*') {
10104             break;
10105 #if 0
10106          } else if (vmu->review && (*duration < 5)) {
10107             /* Message is too short */
10108             ast_verb(3, "Message too short\n");
10109             cmd = ast_play_and_wait(chan, "vm-tooshort");
10110             cmd = ast_filedelete(tempfile, NULL);
10111             break;
10112          } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
10113             /* Message is all silence */
10114             ast_verb(3, "Nothing recorded\n");
10115             cmd = ast_filedelete(tempfile, NULL);
10116             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
10117             if (!cmd)
10118                cmd = ast_play_and_wait(chan, "vm-speakup");
10119             break;
10120 #endif
10121          } else {
10122             /* If all is well, a message exists */
10123             message_exists = 1;
10124             cmd = 0;
10125          }
10126          break;
10127       case '4':
10128       case '5':
10129       case '6':
10130       case '7':
10131       case '8':
10132       case '9':
10133       case '*':
10134       case '#':
10135          cmd = ast_play_and_wait(chan, "vm-sorry");
10136          break;
10137 #if 0 
10138 /*  XXX Commented out for the moment because of the dangers of deleting
10139     a message while recording (can put the message numbers out of sync) */
10140       case '*':
10141          /* Cancel recording, delete message, offer to take another message*/
10142          cmd = ast_play_and_wait(chan, "vm-deleted");
10143          cmd = ast_filedelete(tempfile, NULL);
10144          if (outsidecaller) {
10145             res = vm_exec(chan, NULL);
10146             return res;
10147          }
10148          else
10149             return 1;
10150 #endif
10151       case '0':
10152          if (!ast_test_flag(vmu, VM_OPERATOR)) {
10153             cmd = ast_play_and_wait(chan, "vm-sorry");
10154             break;
10155          }
10156          if (message_exists || recorded) {
10157             cmd = ast_play_and_wait(chan, "vm-saveoper");
10158             if (!cmd)
10159                cmd = ast_waitfordigit(chan, 3000);
10160             if (cmd == '1') {
10161                ast_play_and_wait(chan, "vm-msgsaved");
10162                cmd = '0';
10163             } else {
10164                ast_play_and_wait(chan, "vm-deleted");
10165                DELETE(recordfile, -1, recordfile, vmu);
10166                cmd = '0';
10167             }
10168          }
10169          return cmd;
10170       default:
10171          /* If the caller is an ouside caller, and the review option is enabled,
10172             allow them to review the message, but let the owner of the box review
10173             their OGM's */
10174          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
10175             return cmd;
10176          if (message_exists) {
10177             cmd = ast_play_and_wait(chan, "vm-review");
10178          } else {
10179             cmd = ast_play_and_wait(chan, "vm-torerecord");
10180             if (!cmd)
10181                cmd = ast_waitfordigit(chan, 600);
10182          }
10183          
10184          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
10185             cmd = ast_play_and_wait(chan, "vm-reachoper");
10186             if (!cmd)
10187                cmd = ast_waitfordigit(chan, 600);
10188          }
10189 #if 0
10190          if (!cmd)
10191             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
10192 #endif
10193          if (!cmd)
10194             cmd = ast_waitfordigit(chan, 6000);
10195          if (!cmd) {
10196             attempts++;
10197          }
10198          if (attempts > max_attempts) {
10199             cmd = 't';
10200          }
10201       }
10202    }
10203    if (outsidecaller)
10204       ast_play_and_wait(chan, "vm-goodbye");
10205    if (cmd == 't')
10206       cmd = 0;
10207    return cmd;
10208 }

static void poll_subscribed_mailboxes ( void   )  [static]

Definition at line 8784 of file app_voicemail.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, inboxcount(), mwi_sub::mailbox, mwi_sub::old_new, mwi_sub::old_old, and queue_mwi_event().

Referenced by mb_poll_thread().

08785 {
08786    struct mwi_sub *mwi_sub;
08787 
08788    AST_RWLIST_RDLOCK(&mwi_subs);
08789    AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {
08790       int new = 0, old = 0;
08791 
08792       if (ast_strlen_zero(mwi_sub->mailbox))
08793          continue;
08794 
08795       inboxcount(mwi_sub->mailbox, &new, &old);
08796 
08797       if (new != mwi_sub->old_new || old != mwi_sub->old_old) {
08798          mwi_sub->old_new = new;
08799          mwi_sub->old_old = old;
08800          queue_mwi_event(mwi_sub->mailbox, new, old);
08801       }
08802    }
08803    AST_RWLIST_UNLOCK(&mwi_subs);
08804 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 697 of file app_voicemail.c.

References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::exit, exitcontext, globalflags, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::saydurationm, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.

00698 {
00699    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00700    if (saydurationminfo)
00701       vmu->saydurationm = saydurationminfo;
00702    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00703    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00704    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00705    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00706    if (vmmaxsecs)
00707       vmu->maxsecs = vmmaxsecs;
00708    if (maxmsg)
00709       vmu->maxmsg = maxmsg;
00710    if (maxdeletedmsg)
00711       vmu->maxdeletedmsg = maxdeletedmsg;
00712    vmu->volgain = volgain;
00713 }

static void prep_email_sub_vars ( struct ast_channel ast,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
const char *  fromfolder,
char *  cidnum,
char *  cidname,
char *  dur,
char *  date,
char *  passdata,
size_t  passdatasize,
const char *  category 
) [static]

Definition at line 3279 of file app_voicemail.c.

References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, and pbx_builtin_setvar_helper().

03280 {
03281    char callerid[256];
03282    char fromdir[256], fromfile[256];
03283    struct ast_config *msg_cfg;
03284    const char *origcallerid, *origtime;
03285    char origcidname[80], origcidnum[80], origdate[80];
03286    int inttime;
03287    struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
03288 
03289    /* Prepare variables for substitution in email body and subject */
03290    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
03291    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
03292    snprintf(passdata, passdatasize, "%d", msgnum);
03293    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
03294    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
03295    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
03296    pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
03297       ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
03298    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
03299    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
03300    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
03301    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
03302 
03303    /* Retrieve info from VM attribute file */
03304    make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03305    make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
03306    if (strlen(fromfile) < sizeof(fromfile) - 5) {
03307       strcat(fromfile, ".txt");
03308    }
03309    if (!(msg_cfg = ast_config_load(fromfile, config_flags))) {
03310       if (option_debug > 0) {
03311          ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
03312       }
03313       return;
03314    }
03315 
03316    if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03317       pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
03318       ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
03319       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
03320       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
03321    }
03322 
03323    if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%d", &inttime) == 1) {
03324       struct timeval tv = { inttime, };
03325       struct ast_tm tm;
03326       ast_localtime(&tv, &tm, NULL);
03327       ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03328       pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
03329    }
03330    ast_config_destroy(msg_cfg);
03331 }

static void queue_mwi_event ( const char *  mbox,
int  new,
int  old 
) [static]

Definition at line 5461 of file app_voicemail.c.

References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, ast_strlen_zero(), and strsep().

Referenced by append_mailbox(), notify_new_message(), poll_subscribed_mailboxes(), and vm_execmain().

05462    {
05463       struct ast_event *event;
05464       char *mailbox, *context;
05465 
05466       /* Strip off @default */
05467       context = mailbox = ast_strdupa(mbox);
05468       strsep(&context, "@");
05469       if (ast_strlen_zero(context))
05470          context = "default";
05471 
05472       if (!(event = ast_event_new(AST_EVENT_MWI,
05473             AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
05474             AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
05475             AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, new,
05476             AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old,
05477             AST_EVENT_IE_END))) {
05478          return;
05479       }
05480 
05481       ast_event_queue_and_cache(event,
05482          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
05483          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR,
05484          AST_EVENT_IE_END);
05485    }

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

Definition at line 3333 of file app_voicemail.c.

03334 {
03335    char *ptr = to;
03336    *ptr++ = '"';
03337    for (; ptr < to + len - 1; from++) {
03338       if (*from == '"')
03339          *ptr++ = '\\';
03340       else if (*from == '\0')
03341          break;
03342       *ptr++ = *from;
03343    }
03344    if (ptr < to + len - 1)
03345       *ptr++ = '"';
03346    *ptr = '\0';
03347    return to;
03348 }

static int reload ( void   )  [static]

Definition at line 9714 of file app_voicemail.c.

References load_config().

09715 {
09716    return load_config(1);
09717 }

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

Definition at line 3003 of file app_voicemail.c.

References ast_check_realtime(), ast_filerename(), and ast_update_realtime().

03004 {
03005    char stxt[PATH_MAX];
03006    char dtxt[PATH_MAX];
03007    ast_filerename(sfn, dfn, NULL);
03008    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
03009    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
03010    if (ast_check_realtime("voicemail_data")) {
03011       ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, NULL);
03012    }
03013    rename(stxt, dtxt);
03014 }

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

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

04712    {
04713       /* we know max messages, so stop process when number is hit */
04714 
04715       int x, dest;
04716       char sfn[PATH_MAX];
04717       char dfn[PATH_MAX];
04718 
04719       if (vm_lock_path(dir))
04720          return ERROR_LOCK_PATH;
04721 
04722       for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
04723          make_file(sfn, sizeof(sfn), dir, x);
04724          if (EXISTS(dir, x, sfn, NULL)) {
04725             
04726             if (x != dest) {
04727                make_file(dfn, sizeof(dfn), dir, dest);
04728                RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04729             }
04730             
04731             dest++;
04732          }
04733       }
04734       ast_unlock_path(dir);
04735 
04736       return 0;
04737    }

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

Definition at line 946 of file app_voicemail.c.

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

Referenced by vm_change_password(), and vm_change_password_shell().

00947 {
00948    /* This function could be made to generate one from a database, too */
00949    struct ast_vm_user *cur;
00950    int res = -1;
00951    AST_LIST_LOCK(&users);
00952    AST_LIST_TRAVERSE(&users, cur, list) {
00953       if ((!context || !strcasecmp(context, cur->context)) &&
00954          (!strcasecmp(mailbox, cur->mailbox)))
00955             break;
00956    }
00957    if (cur) {
00958       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00959       res = 0;
00960    }
00961    AST_LIST_UNLOCK(&users);
00962    return res;
00963 }

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

Definition at line 4224 of file app_voicemail.c.

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

04225    {
04226       char arguments[255];
04227       char ext_context[256] = "";
04228       int newvoicemails = 0, oldvoicemails = 0;
04229       struct ast_smdi_mwi_message *mwi_msg;
04230 
04231       if (!ast_strlen_zero(context))
04232          snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
04233       else
04234          ast_copy_string(ext_context, extension, sizeof(ext_context));
04235 
04236       if (smdi_iface) {
04237          if (ast_app_has_voicemail(ext_context, NULL)) 
04238             ast_smdi_mwi_set(smdi_iface, extension);
04239          else
04240             ast_smdi_mwi_unset(smdi_iface, extension);
04241 
04242          if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
04243             ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
04244             if (!strncmp(mwi_msg->cause, "INV", 3))
04245                ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
04246             else if (!strncmp(mwi_msg->cause, "BLK", 3))
04247                ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
04248             ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
04249             ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
04250          } else {
04251             ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension);
04252          }
04253       }
04254 
04255       if (!ast_strlen_zero(externnotify)) {
04256          if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
04257             ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
04258          } else {
04259             snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
04260             ast_debug(1, "Executing %s\n", arguments);
04261             ast_safe_system(arguments);
04262          }
04263       }
04264    }

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

Definition at line 4747 of file app_voicemail.c.

References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_unlock_path(), ast_vm_user::context, COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, ERROR_MAILBOX_FULL, EXISTS, last_message_index(), LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().

Referenced by close_mailbox(), and vm_execmain().

04748    {
04749 #ifdef IMAP_STORAGE
04750       /* we must use mbox(x) folder names, and copy the message there */
04751       /* simple. huh? */
04752       char sequence[10];
04753       char mailbox[256];
04754       int res;
04755 
04756       /* get the real IMAP message number for this message */
04757       snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04758       
04759       ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(box));
04760       ast_mutex_lock(&vms->lock);
04761 
04762       if (box == OLD_FOLDER) {
04763          mail_setflag(vms->mailstream, sequence, "\\Seen");
04764          mail_clearflag(vms->mailstream, sequence, "\\Unseen");
04765       } else if (box == NEW_FOLDER) {
04766          mail_clearflag(vms->mailstream, sequence, "\\Seen");
04767          mail_setflag(vms->mailstream, sequence, "\\Unseen");
04768       }
04769       if (!strcasecmp(mbox(NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) {
04770          ast_mutex_unlock(&vms->lock);
04771          return 0;
04772       }
04773       /* Create the folder if it don't exist */
04774       imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */
04775       ast_debug(5, "Checking if folder exists: %s\n",mailbox);
04776       if (mail_create(vms->mailstream, mailbox) == NIL) 
04777          ast_debug(5, "Folder exists.\n");
04778       else
04779          ast_log(LOG_NOTICE, "Folder %s created!\n",mbox(box));
04780       res = !mail_copy(vms->mailstream, sequence, (char *)mbox(box));
04781       ast_mutex_unlock(&vms->lock);
04782       return res;
04783 #else
04784       char *dir = vms->curdir;
04785       char *username = vms->username;
04786       char *context = vmu->context;
04787       char sfn[PATH_MAX];
04788       char dfn[PATH_MAX];
04789       char ddir[PATH_MAX];
04790       const char *dbox = mbox(box);
04791       int x, i;
04792       create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04793 
04794       if (vm_lock_path(ddir))
04795          return ERROR_LOCK_PATH;
04796 
04797       x = last_message_index(vmu, ddir) + 1;
04798 
04799       if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/
04800          x--;
04801          for (i = 1; i <= x; i++) {
04802             /* Push files down a "slot".  The oldest file (msg0000) will be deleted. */
04803             make_file(sfn, sizeof(sfn), ddir, i);
04804             make_file(dfn, sizeof(dfn), ddir, i - 1);
04805             if (EXISTS(ddir, i, sfn, NULL)) {
04806                RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn);
04807             } else
04808                break;
04809          }
04810       } else {
04811          if (x >= vmu->maxmsg) {
04812             ast_unlock_path(ddir);
04813             return ERROR_MAILBOX_FULL;
04814          }
04815       }
04816       make_file(sfn, sizeof(sfn), dir, msg);
04817       make_file(dfn, sizeof(dfn), ddir, x);
04818       if (strcmp(sfn, dfn)) {
04819          COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04820       }
04821       ast_unlock_path(ddir);
04822 #endif
04823       return 0;
04824    }

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

Definition at line 4740 of file app_voicemail.c.

References AST_DIGIT_ANY, ast_say_number(), and chan.

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_se(), and vm_intro_tw().

04741    {
04742       int d;
04743       d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL);
04744       return d;
04745    }

static int sendmail ( char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
const char *  fromfolder,
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 3746 of file app_voicemail.c.

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

03747 {
03748    FILE *p = NULL;
03749    char tmp[80] = "/tmp/astmail-XXXXXX";
03750    char tmp2[256];
03751 
03752    if (vmu && ast_strlen_zero(vmu->email)) {
03753       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03754       return(0);
03755    }
03756    if (!strcmp(format, "wav49"))
03757       format = "WAV";
03758    ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
03759    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03760    command hangs */
03761    if ((p = vm_mkftemp(tmp)) == NULL) {
03762       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03763       return -1;
03764    } else {
03765       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03766       fclose(p);
03767       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03768       ast_safe_system(tmp2);
03769       ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03770    }
03771    return 0;
03772 }

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

Definition at line 3774 of file app_voicemail.c.

References ast_channel_alloc, ast_channel_free(), ast_copy_string(), ast_debug, ast_log(), ast_safe_system(), AST_STATE_DOWN, ast_strftime(), fromstring, MAXHOSTNAMELEN, pagerbody, pagerfromstring, pagersubject, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().

Referenced by notify_new_message().

03775 {
03776    char date[256];
03777    char host[MAXHOSTNAMELEN] = "";
03778    char who[256];
03779    char dur[PATH_MAX];
03780    char tmp[80] = "/tmp/astmail-XXXXXX";
03781    char tmp2[PATH_MAX];
03782    struct ast_tm tm;
03783    FILE *p;
03784 
03785    if ((p = vm_mkftemp(tmp)) == NULL) {
03786       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03787       return -1;
03788    }
03789    gethostname(host, sizeof(host) - 1);
03790    if (strchr(srcemail, '@'))
03791       ast_copy_string(who, srcemail, sizeof(who));
03792    else 
03793       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03794    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03795    ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03796    fprintf(p, "Date: %s\n", date);
03797 
03798    if (*pagerfromstring) {
03799       struct ast_channel *ast;
03800       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03801          char *passdata;
03802          int vmlen = strlen(fromstring) * 3 + 200;
03803          passdata = alloca(vmlen);
03804          memset(passdata, 0, vmlen);
03805          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03806          pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
03807          fprintf(p, "From: %s <%s>\n", passdata, who);
03808          ast_channel_free(ast);
03809       } else 
03810          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03811    } else
03812       fprintf(p, "From: Asterisk PBX <%s>\n", who);
03813    fprintf(p, "To: %s\n", pager);
03814    if (pagersubject) {
03815       struct ast_channel *ast;
03816       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03817          char *passdata;
03818          int vmlen = strlen(pagersubject) * 3 + 200;
03819          passdata = alloca(vmlen);
03820          memset(passdata, 0, vmlen);
03821          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03822          pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
03823          fprintf(p, "Subject: %s\n\n", passdata);
03824          ast_channel_free(ast);
03825       } else
03826          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03827    } else
03828       fprintf(p, "Subject: New VM\n\n");
03829 
03830    ast_strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
03831    if (pagerbody) {
03832       struct ast_channel *ast;
03833       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03834          char *passdata;
03835          int vmlen = strlen(pagerbody) * 3 + 200;
03836          passdata = alloca(vmlen);
03837          memset(passdata, 0, vmlen);
03838          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03839          pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
03840          fprintf(p, "%s\n", passdata);
03841          ast_channel_free(ast);
03842       } else
03843          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03844    } else {
03845       fprintf(p, "New %s long msg in box %s\n"
03846             "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
03847    }
03848    fclose(p);
03849    snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03850    ast_safe_system(tmp2);
03851    ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd);
03852    return 0;
03853 }

static char* show_users_realtime ( int  fd,
const char *  context 
) [static]

Definition at line 8582 of file app_voicemail.c.

References ast_category_browse(), ast_cli(), ast_config_destroy(), ast_load_realtime_multientry(), ast_variable_browse(), CLI_FAILURE, CLI_SUCCESS, and var.

Referenced by handle_voicemail_show_users().

08583 {
08584    struct ast_config *cfg;
08585    const char *cat = NULL;
08586 
08587    if (!(cfg = ast_load_realtime_multientry("voicemail", 
08588       "context", context, NULL))) {
08589       return CLI_FAILURE;
08590    }
08591 
08592    ast_cli(fd,
08593       "\n"
08594       "=============================================================\n"
08595       "=== Configured Voicemail Users ==============================\n"
08596       "=============================================================\n"
08597       "===\n");
08598 
08599    while ((cat = ast_category_browse(cfg, cat))) {
08600       struct ast_variable *var = NULL;
08601       ast_cli(fd,
08602          "=== Mailbox ...\n"
08603          "===\n");
08604       for (var = ast_variable_browse(cfg, cat); var; var = var->next)
08605          ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value);
08606       ast_cli(fd,
08607          "===\n"
08608          "=== ---------------------------------------------------------\n"
08609          "===\n");
08610    }
08611 
08612    ast_cli(fd,
08613       "=============================================================\n"
08614       "\n");
08615 
08616    ast_config_destroy(cfg);
08617 
08618    return CLI_SUCCESS;
08619 }

static void start_poll_thread ( void   )  [static]

Definition at line 8903 of file app_voicemail.c.

References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_pthread_create, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), and mwi_unsub_sub.

Referenced by load_config().

08904 {
08905    pthread_attr_t attr;
08906 
08907    mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, NULL,
08908       AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI,
08909       AST_EVENT_IE_END);
08910 
08911    mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, NULL,
08912       AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI,
08913       AST_EVENT_IE_END);
08914 
08915    if (mwi_sub_sub)
08916       ast_event_report_subs(mwi_sub_sub);
08917 
08918    poll_thread_run = 1;
08919 
08920    pthread_attr_init(&attr);
08921    ast_pthread_create(&poll_thread, &attr, mb_poll_thread, NULL);
08922    pthread_attr_destroy(&attr);
08923 }

static void stop_poll_thread ( void   )  [static]

Definition at line 8925 of file app_voicemail.c.

References ast_cond_signal(), ast_event_unsubscribe(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, mwi_sub_sub, mwi_unsub_sub, and poll_lock.

Referenced by load_config(), and unload_module().

08926 {
08927    poll_thread_run = 0;
08928 
08929    if (mwi_sub_sub) {
08930       ast_event_unsubscribe(mwi_sub_sub);
08931       mwi_sub_sub = NULL;
08932    }
08933 
08934    if (mwi_unsub_sub) {
08935       ast_event_unsubscribe(mwi_unsub_sub);
08936       mwi_unsub_sub = NULL;
08937    }
08938 
08939    ast_mutex_lock(&poll_lock);
08940    ast_cond_signal(&poll_cond);
08941    ast_mutex_unlock(&poll_lock);
08942 
08943    pthread_join(poll_thread, NULL);
08944 
08945    poll_thread = AST_PTHREADT_NULL;
08946 }

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

Definition at line 680 of file app_voicemail.c.

Referenced by make_email_file().

00681 {
00682    char *bufptr = buf;
00683    for (; *input; input++) {
00684       if (*input < 32) {
00685          continue;
00686       }
00687       *bufptr++ = *input;
00688       if (bufptr == buf + buflen - 1) {
00689          break;
00690       }
00691    }
00692    *bufptr = '\0';
00693    return buf;
00694 }

static char* substitute_escapes ( const char *  value  )  [static]

Definition at line 9072 of file app_voicemail.c.

References ast_log(), ast_str_append(), ast_str_create(), LOG_NOTICE, and str.

Referenced by load_config().

09073 {
09074    char *current, *result;
09075 
09076    /* Add 16 for fudge factor */
09077    struct ast_str *str = ast_str_create(strlen(value) + 16);
09078 
09079    /* Substitute strings \r, \n, and \t into the appropriate characters */
09080    for (current = (char *) value; *current; current++) {
09081       if (*current == '\\') {
09082          current++;
09083          if (!*current) {
09084             ast_log(LOG_NOTICE, "Incomplete escape at end of value.\n");
09085             break;
09086          }
09087          switch (*current) {
09088          case 'r':
09089             ast_str_append(&str, 0, "\r");
09090             break;
09091          case 'n':
09092 #ifdef IMAP_STORAGE
09093             if (!str->used || str->str[str->used - 1] != '\r') {
09094                ast_str_append(&str, 0, "\r");
09095             }
09096 #endif
09097             ast_str_append(&str, 0, "\n");
09098             break;
09099          case 't':
09100             ast_str_append(&str, 0, "\t");
09101             break;
09102          default:
09103             ast_log(LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current);
09104             break;
09105          }
09106       } else {
09107          ast_str_append(&str, 0, "%c", *current);
09108       }
09109    }
09110 
09111    result = ast_strdup(str->str);
09112    ast_free(str);
09113 
09114    return result;
09115 }

static int unload_module ( void   )  [static]

Definition at line 9719 of file app_voicemail.c.

References ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_manager_unregister(), AST_PTHREADT_NULL, ast_uninstall_vm_functions(), ast_unregister_application(), cli_voicemail, free_vm_users(), free_vm_zones(), mailbox_exists_acf, and stop_poll_thread().

09720 {
09721    int res;
09722 
09723    res = ast_unregister_application(app);
09724    res |= ast_unregister_application(app2);
09725    res |= ast_unregister_application(app3);
09726    res |= ast_unregister_application(app4);
09727    res |= ast_custom_function_unregister(&mailbox_exists_acf);
09728    res |= ast_manager_unregister("VoicemailUsersList");
09729    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
09730    ast_uninstall_vm_functions();
09731 
09732    if (poll_thread != AST_PTHREADT_NULL)
09733       stop_poll_thread();
09734 
09735 
09736    free_vm_users();
09737    free_vm_zones();
09738    return res;
09739 }

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

References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitstream(), chan, find_user(), ast_vm_user::password, and vm_password.

Referenced by vm_execmain(), and vmauthenticate().

07687 {
07688    int useadsi = 0, valid = 0, logretries = 0;
07689    char password[AST_MAX_EXTENSION] = "", *passptr;
07690    struct ast_vm_user vmus, *vmu = NULL;
07691 
07692    /* If ADSI is supported, setup login screen */
07693    adsi_begin(chan, &useadsi);
07694    if (!skipuser && useadsi)
07695       adsi_login(chan);
07696    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
07697       ast_log(LOG_WARNING, "Couldn't stream login file\n");
07698       return -1;
07699    }
07700    
07701    /* Authenticate them and get their mailbox/password */
07702    
07703    while (!valid && (logretries < maxlogins)) {
07704       /* Prompt for, and read in the username */
07705       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
07706          ast_log(LOG_WARNING, "Couldn't read username\n");
07707          return -1;
07708       }
07709       if (ast_strlen_zero(mailbox)) {
07710          if (chan->cid.cid_num) {
07711             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
07712          } else {
07713             ast_verb(3, "Username not entered\n"); 
07714             return -1;
07715          }
07716       }
07717       if (useadsi)
07718          adsi_password(chan);
07719 
07720       if (!ast_strlen_zero(prefix)) {
07721          char fullusername[80] = "";
07722          ast_copy_string(fullusername, prefix, sizeof(fullusername));
07723          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
07724          ast_copy_string(mailbox, fullusername, mailbox_size);
07725       }
07726 
07727       ast_debug(1, "Before find user for mailbox %s\n", mailbox);
07728       vmu = find_user(&vmus, context, mailbox);
07729       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
07730          /* saved password is blank, so don't bother asking */
07731          password[0] = '\0';
07732       } else {
07733          if (ast_streamfile(chan, vm_password, chan->language)) {
07734             ast_log(LOG_WARNING, "Unable to stream password file\n");
07735             return -1;
07736          }
07737          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
07738             ast_log(LOG_WARNING, "Unable to read password\n");
07739             return -1;
07740          }
07741       }
07742 
07743       if (vmu) {
07744          passptr = vmu->password;
07745          if (passptr[0] == '-') passptr++;
07746       }
07747       if (vmu && !strcmp(passptr, password))
07748          valid++;
07749       else {
07750          ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
07751          if (!ast_strlen_zero(prefix))
07752             mailbox[0] = '\0';
07753       }
07754       logretries++;
07755       if (!valid) {
07756          if (skipuser || logretries >= maxlogins) {
07757             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
07758                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
07759                return -1;
07760             }
07761          } else {
07762             if (useadsi)
07763                adsi_login(chan);
07764             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
07765                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
07766                return -1;
07767             }
07768          }
07769          if (ast_waitstream(chan, "")) /* Channel is hung up */
07770             return -1;
07771       }
07772    }
07773    if (!valid && (logretries >= maxlogins)) {
07774       ast_stopstream(chan);
07775       ast_play_and_wait(chan, "vm-goodbye");
07776       return -1;
07777    }
07778    if (vmu && !skipuser) {
07779       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
07780    }
07781    return 0;
07782 }

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

Definition at line 8477 of file app_voicemail.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan, find_user(), LOG_ERROR, and pbx_builtin_setvar_helper().

Referenced by load_module().

08478 {
08479    struct ast_vm_user svm;
08480    char *context, *box;
08481    AST_DECLARE_APP_ARGS(args,
08482       AST_APP_ARG(mbox);
08483       AST_APP_ARG(options);
08484    );
08485    static int dep_warning = 0;
08486 
08487    if (ast_strlen_zero(data)) {
08488       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
08489       return -1;
08490    }
08491 
08492    if (!dep_warning) {
08493       dep_warning = 1;
08494       ast_log(LOG_WARNING, "MailboxExists is deprecated.  Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *)data);
08495    }
08496 
08497    box = ast_strdupa(data);
08498 
08499    AST_STANDARD_APP_ARGS(args, box);
08500 
08501    if (args.options) {
08502    }
08503 
08504    if ((context = strchr(args.mbox, '@'))) {
08505       *context = '\0';
08506       context++;
08507    }
08508 
08509    if (find_user(&svm, context, args.mbox)) {
08510       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
08511    } else
08512       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
08513 
08514    return 0;
08515 }

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

Definition at line 7667 of file app_voicemail.c.

References chan, ast_channel::language, vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_it(), vm_browse_messages_pt(), and vm_browse_messages_tw().

Referenced by vm_execmain().

07668 {
07669    if (!strcasecmp(chan->language, "es")) {  /* SPANISH */
07670       return vm_browse_messages_es(chan, vms, vmu);
07671    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */
07672       return vm_browse_messages_it(chan, vms, vmu);
07673    } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) {   /* PORTUGUESE */
07674       return vm_browse_messages_pt(chan, vms, vmu);
07675    } else if (!strcasecmp(chan->language, "gr")) {
07676       return vm_browse_messages_gr(chan, vms, vmu);   /* GREEK */
07677    } else if (!strcasecmp(chan->language, "tw")) {
07678       return vm_browse_messages_tw(chan, vms, vmu);   /* CHINESE (Taiwan) */
07679    } else { /* Default to English syntax */
07680       return vm_browse_messages_en(chan, vms, vmu);
07681    }
07682 }

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

Definition at line 7569 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07570 {
07571    int cmd = 0;
07572 
07573    if (vms->lastmsg > -1) {
07574       cmd = play_message(chan, vmu, vms);
07575    } else {
07576       cmd = ast_play_and_wait(chan, "vm-youhave");
07577       if (!cmd) 
07578          cmd = ast_play_and_wait(chan, "vm-no");
07579       if (!cmd) {
07580          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07581          cmd = ast_play_and_wait(chan, vms->fn);
07582       }
07583       if (!cmd)
07584          cmd = ast_play_and_wait(chan, "vm-messages");
07585    }
07586    return cmd;
07587 }

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

Definition at line 7609 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07610 {
07611    int cmd = 0;
07612 
07613    if (vms->lastmsg > -1) {
07614       cmd = play_message(chan, vmu, vms);
07615    } else {
07616       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07617       if (!cmd)
07618          cmd = ast_play_and_wait(chan, "vm-messages");
07619       if (!cmd) {
07620          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07621          cmd = ast_play_and_wait(chan, vms->fn);
07622       }
07623    }
07624    return cmd;
07625 }

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

Definition at line 7541 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07542 {
07543    int cmd = 0;
07544 
07545    if (vms->lastmsg > -1) {
07546       cmd = play_message(chan, vmu, vms);
07547    } else {
07548       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07549       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")) {
07550          if (!cmd) {
07551             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07552             cmd = ast_play_and_wait(chan, vms->fn);
07553          }
07554          if (!cmd)
07555             cmd = ast_play_and_wait(chan, "vm-messages");
07556       } else {
07557          if (!cmd)
07558             cmd = ast_play_and_wait(chan, "vm-messages");
07559          if (!cmd) {
07560             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07561             cmd = ast_play_and_wait(chan, vms->fn);
07562          }
07563       }
07564    } 
07565    return cmd;
07566 }

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

Definition at line 7590 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07591 {
07592    int cmd = 0;
07593 
07594    if (vms->lastmsg > -1) {
07595       cmd = play_message(chan, vmu, vms);
07596    } else {
07597       cmd = ast_play_and_wait(chan, "vm-no");
07598       if (!cmd)
07599          cmd = ast_play_and_wait(chan, "vm-message");
07600       if (!cmd) {
07601          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07602          cmd = ast_play_and_wait(chan, vms->fn);
07603       }
07604    }
07605    return cmd;
07606 }

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

Definition at line 7628 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07629 {
07630    int cmd = 0;
07631 
07632    if (vms->lastmsg > -1) {
07633       cmd = play_message(chan, vmu, vms);
07634    } else {
07635       cmd = ast_play_and_wait(chan, "vm-no");
07636       if (!cmd) {
07637          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07638          cmd = ast_play_and_wait(chan, vms->fn);
07639       }
07640       if (!cmd)
07641          cmd = ast_play_and_wait(chan, "vm-messages");
07642    }
07643    return cmd;
07644 }

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

Definition at line 7647 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07648 {
07649    int cmd = 0;
07650 
07651    if (vms->lastmsg > -1) {
07652       cmd = play_message(chan, vmu, vms);
07653    } else {
07654       cmd = ast_play_and_wait(chan, "vm-you");
07655       if (!cmd) 
07656          cmd = ast_play_and_wait(chan, "vm-haveno");
07657       if (!cmd)
07658          cmd = ast_play_and_wait(chan, "vm-messages");
07659       if (!cmd) {
07660          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07661          cmd = ast_play_and_wait(chan, vms->fn);
07662       }
07663    }
07664    return cmd;
07665 }

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

Definition at line 965 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00966 {
00967    struct ast_config *cfg = NULL;
00968    struct ast_variable *var = NULL;
00969    struct ast_category *cat = NULL;
00970    char *category = NULL, *value = NULL, *new = NULL;
00971    const char *tmp = NULL;
00972    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
00973    if (!change_password_realtime(vmu, newpassword))
00974       return;
00975 
00976    /* check voicemail.conf */
00977    if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags))) {
00978       while ((category = ast_category_browse(cfg, category))) {
00979          if (!strcasecmp(category, vmu->context)) {
00980             if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
00981                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00982                break;
00983             }
00984             value = strstr(tmp, ",");
00985             if (!value) {
00986                ast_log(LOG_WARNING, "variable has bad format.\n");
00987                break;
00988             }
00989             new = alloca(strlen(value) + strlen(newpassword) + 1);
00990             sprintf(new, "%s%s", newpassword, value);
00991             if (!(cat = ast_category_get(cfg, category))) {
00992                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00993                break;
00994             }
00995             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00996          }
00997       }
00998       /* save the results */
00999       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
01000       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
01001       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
01002    }
01003    category = NULL;
01004    var = NULL;
01005    /* check users.conf and update the password stored for the mailbox*/
01006    /* if no vmsecret entry exists create one. */
01007    if ((cfg = ast_config_load("users.conf", config_flags))) {
01008       ast_debug(4, "we are looking for %s\n", vmu->mailbox);
01009       while ((category = ast_category_browse(cfg, category))) {
01010          ast_debug(4, "users.conf: %s\n", category);
01011          if (!strcasecmp(category, vmu->mailbox)) {
01012             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
01013                ast_debug(3, "looks like we need to make vmsecret!\n");
01014                var = ast_variable_new("vmsecret", newpassword, "");
01015             } 
01016             new = alloca(strlen(newpassword) + 1);
01017             sprintf(new, "%s", newpassword);
01018             if (!(cat = ast_category_get(cfg, category))) {
01019                ast_debug(4, "failed to get category!\n");
01020                break;
01021             }
01022             if (!var)      
01023                ast_variable_update(cat, "vmsecret", new, NULL, 0);
01024             else
01025                ast_variable_append(cat, var);
01026          }
01027       }
01028       /* save the results and clean things up */
01029       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
01030       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
01031       config_text_file_save("users.conf", cfg, "AppVoicemail");
01032    }
01033 }

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

Definition at line 1035 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

01036 {
01037    char buf[255];
01038    snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword);
01039    if (!ast_safe_system(buf)) {
01040       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
01041       /* Reset the password in memory, too */
01042       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
01043    }
01044 }

static int vm_delete ( char *  file  )  [static]

Removes the voicemail sound and information file.

Parameters:
file The path to the sound file. This will be the the folder and message index, without the extension.
This is used by the DELETE macro when voicemails are stored on the file system.

Returns:
zero on success, -1 on error.

Definition at line 3154 of file app_voicemail.c.

References ast_check_realtime(), ast_destroy_realtime(), and ast_filedelete().

03155 {
03156    char *txt;
03157    int txtsize = 0;
03158 
03159    txtsize = (strlen(file) + 5) * sizeof(char);
03160    txt = alloca(txtsize);
03161    /* Sprintf here would safe because we alloca'd exactly the right length,
03162    * but trying to eliminate all sprintf's anyhow
03163    */
03164    if (ast_check_realtime("voicemail_data")) {
03165       ast_destroy_realtime("voicemail_data", "filename", file, NULL);
03166    }
03167    snprintf(txt, txtsize, "%s.txt", file);
03168    unlink(txt);
03169    return ast_filedelete(file, NULL);
03170 }

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

Definition at line 8345 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_log(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, chan, ERROR_LOCK_PATH, ast_flags::flags, leave_voicemail(), LOG_ERROR, OPT_ARG_ARRAY_SIZE, OPT_ARG_DTMFEXIT, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and vm_app_options.

Referenced by load_module(), and play_record_review().

08346 {
08347    int res = 0;
08348    char *tmp;
08349    struct leave_vm_options leave_options;
08350    struct ast_flags flags = { 0 };
08351    char *opts[OPT_ARG_ARRAY_SIZE];
08352    AST_DECLARE_APP_ARGS(args,
08353       AST_APP_ARG(argv0);
08354       AST_APP_ARG(argv1);
08355    );
08356    
08357    memset(&leave_options, 0, sizeof(leave_options));
08358 
08359    if (chan->_state != AST_STATE_UP)
08360       ast_answer(chan);
08361 
08362    if (!ast_strlen_zero(data)) {
08363       tmp = ast_strdupa(data);
08364       AST_STANDARD_APP_ARGS(args, tmp);
08365       if (args.argc == 2) {
08366          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
08367             return -1;
08368          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_DTMFEXIT);
08369          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
08370             int gain;
08371 
08372             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
08373                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
08374                return -1;
08375             } else {
08376                leave_options.record_gain = (signed char) gain;
08377             }
08378          }
08379          if (ast_test_flag(&flags, OPT_DTMFEXIT)) {
08380             if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT]))
08381                leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT];
08382          }
08383       }
08384    } else {
08385       char tmp[256];
08386       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
08387       if (res < 0)
08388          return res;
08389       if (ast_strlen_zero(tmp))
08390          return 0;
08391       args.argv0 = ast_strdupa(tmp);
08392    }
08393 
08394    res = leave_voicemail(chan, args.argv0, &leave_options);
08395 
08396    if (res == ERROR_LOCK_PATH) {
08397       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
08398       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
08399       res = 0;
08400    }
08401 
08402    return res;
08403 }

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

Definition at line 7784 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_inboxcount(), ast_app_parse_options(), ast_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_vm_user::callback, chan, close_mailbox(), ast_vm_user::context, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free_user(), get_folder2(), globalflags, has_voicemail(), language, ast_vm_user::language, LOG_ERROR, ast_vm_user::mailbox, make_file(), manager_event, ast_vm_user::maxmsg, NEW_FOLDER, OLD_FOLDER, open_mailbox(), OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, parse(), ast_vm_user::password, play_message(), queue_mwi_event(), run_externnotify(), save_to_folder(), say_and_wait(), vm_app_options, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, and VM_SVMAIL.

Referenced by load_module().

07785 {
07786    /* XXX This is, admittedly, some pretty horrendous code.  For some
07787       reason it just seemed a lot easier to do with GOTO's.  I feel
07788       like I'm back in my GWBASIC days. XXX */
07789    int res = -1;
07790    int cmd = 0;
07791    int valid = 0;
07792    char prefixstr[80] = "";
07793    char ext_context[256] = "";
07794    int box;
07795    int useadsi = 0;
07796    int skipuser = 0;
07797    struct vm_state vms;
07798    struct ast_vm_user *vmu = NULL, vmus;
07799    char *context = NULL;
07800    int silentexit = 0;
07801    struct ast_flags flags = { 0 };
07802    signed char record_gain = 0;
07803    int play_auto = 0;
07804    int play_folder = 0;
07805 #ifdef IMAP_STORAGE
07806    int deleted = 0;
07807 #endif
07808 
07809    /* Add the vm_state to the active list and keep it active */
07810    memset(&vms, 0, sizeof(vms));
07811    vms.lastmsg = -1;
07812 
07813    memset(&vmus, 0, sizeof(vmus));
07814 
07815    if (chan->_state != AST_STATE_UP) {
07816       ast_debug(1, "Before ast_answer\n");
07817       ast_answer(chan);
07818    }
07819 
07820    if (!ast_strlen_zero(data)) {
07821       char *opts[OPT_ARG_ARRAY_SIZE];
07822       char *parse;
07823       AST_DECLARE_APP_ARGS(args,
07824          AST_APP_ARG(argv0);
07825          AST_APP_ARG(argv1);
07826       );
07827 
07828       parse = ast_strdupa(data);
07829 
07830       AST_STANDARD_APP_ARGS(args, parse);
07831 
07832       if (args.argc == 2) {
07833          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
07834             return -1;
07835          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07836             int gain;
07837             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
07838                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) {
07839                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07840                   return -1;
07841                } else {
07842                   record_gain = (signed char) gain;
07843                }
07844             } else {
07845                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
07846             }
07847          }
07848          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
07849             play_auto = 1;
07850             if (opts[OPT_ARG_PLAYFOLDER]) {
07851                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) {
07852                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
07853                }
07854             } else {
07855                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
07856             }  
07857             if (play_folder > 9 || play_folder < 0) {
07858                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
07859                play_folder = 0;
07860             }
07861          }
07862       } else {
07863          /* old style options parsing */
07864          while (*(args.argv0)) {
07865             if (*(args.argv0) == 's')
07866                ast_set_flag(&flags, OPT_SILENT);
07867             else if (*(args.argv0) == 'p')
07868                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
07869             else 
07870                break;
07871             (args.argv0)++;
07872          }
07873 
07874       }
07875 
07876       valid = ast_test_flag(&flags, OPT_SILENT);
07877 
07878       if ((context = strchr(args.argv0, '@')))
07879          *context++ = '\0';
07880 
07881       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
07882          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
07883       else
07884          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
07885 
07886       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context, vms.username)))
07887          skipuser++;
07888       else
07889          valid = 0;
07890    }
07891 
07892    if (!valid)
07893       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
07894 
07895    ast_debug(1, "After vm_authenticate\n");
07896    if (!res) {
07897       valid = 1;
07898       if (!skipuser)
07899          vmu = &vmus;
07900    } else {
07901       res = 0;
07902    }
07903 
07904    /* If ADSI is supported, setup login screen */
07905    adsi_begin(chan, &useadsi);
07906 
07907    if (!valid) {
07908       goto out;
07909    }
07910 
07911 #ifdef IMAP_STORAGE
07912    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
07913    pthread_setspecific(ts_vmstate.key, &vms);
07914 
07915    vms.interactive = 1;
07916    vms.updated = 1;
07917    vmstate_insert(&vms);
07918    init_vm_state(&vms);
07919 #endif
07920    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07921       ast_log(LOG_ERROR, "Could not allocate memory for deleted message storage!\n");
07922       cmd = ast_play_and_wait(chan, "an-error-has-occured");
07923       return -1;
07924    }
07925    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07926       ast_log(LOG_ERROR, "Could not allocate memory for heard message storage!\n");
07927       cmd = ast_play_and_wait(chan, "an-error-has-occured");
07928       return -1;
07929    }
07930    
07931    /* Set language from config to override channel language */
07932    if (!ast_strlen_zero(vmu->language))
07933       ast_string_field_set(chan, language, vmu->language);
07934    /* Retrieve old and new message counts */
07935    ast_debug(1, "Before open_mailbox\n");
07936    res = open_mailbox(&vms, vmu, OLD_FOLDER);
07937    if (res == ERROR_LOCK_PATH)
07938       goto out;
07939    vms.oldmessages = vms.lastmsg + 1;
07940    ast_debug(1, "Number of old messages: %d\n", vms.oldmessages);
07941    /* Start in INBOX */
07942    res = open_mailbox(&vms, vmu, NEW_FOLDER);
07943    if (res == ERROR_LOCK_PATH)
07944       goto out;
07945    vms.newmessages = vms.lastmsg + 1;
07946    ast_debug(1, "Number of new messages: %d\n", vms.newmessages);
07947       
07948    /* Select proper mailbox FIRST!! */
07949    if (play_auto) {
07950       res = open_mailbox(&vms, vmu, play_folder);
07951       if (res == ERROR_LOCK_PATH)
07952          goto out;
07953 
07954       /* If there are no new messages, inform the user and hangup */
07955       if (vms.lastmsg == -1) {
07956          cmd = vm_browse_messages(chan, &vms, vmu);
07957          res = 0;
07958          goto out;
07959       }
07960    } else {
07961       if (!vms.newmessages && vms.oldmessages) {
07962          /* If we only have old messages start here */
07963          res = open_mailbox(&vms, vmu, OLD_FOLDER);
07964          play_folder = 1;
07965          if (res == ERROR_LOCK_PATH)
07966             goto out;
07967       }
07968    }
07969 
07970    if (useadsi)
07971       adsi_status(chan, &vms);
07972    res = 0;
07973 
07974    /* Check to see if this is a new user */
07975    if (!strcasecmp(vmu->mailbox, vmu->password) && 
07976       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
07977       if (ast_play_and_wait(chan, "vm-newuser") == -1)
07978          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
07979       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
07980       if ((cmd == 't') || (cmd == '#')) {
07981          /* Timeout */
07982          res = 0;
07983          goto out;
07984       } else if (cmd < 0) {
07985          /* Hangup */
07986          res = -1;
07987          goto out;
07988       }
07989    }
07990 #ifdef IMAP_STORAGE
07991       ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit);
07992       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
07993          ast_debug(1, "*** QUOTA EXCEEDED!!\n");
07994          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07995       }
07996       ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg);
07997       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
07998          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg);
07999          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
08000       }
08001 #endif
08002    if (play_auto) {
08003       cmd = '1';
08004    } else {
08005       cmd = vm_intro(chan, vmu, &vms);
08006    }
08007 
08008    vms.repeats = 0;
08009    vms.starting = 1;
08010    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
08011       /* Run main menu */
08012       switch (cmd) {
08013       case '1':
08014          vms.curmsg = 0;
08015          /* Fall through */
08016       case '5':
08017          cmd = vm_browse_messages(chan, &vms, vmu);
08018          break;
08019       case '2': /* Change folders */
08020          if (useadsi)
08021             adsi_folders(chan, 0, "Change to folder...");
08022          cmd = get_folder2(chan, "vm-changeto", 0);
08023          if (cmd == '#') {
08024             cmd = 0;
08025          } else if (cmd > 0) {
08026             cmd = cmd - '0';
08027             res = close_mailbox(&vms, vmu);
08028             if (res == ERROR_LOCK_PATH)
08029                goto out;
08030             res = open_mailbox(&vms, vmu, cmd);
08031             if (res == ERROR_LOCK_PATH)
08032                goto out;
08033             play_folder = cmd;
08034             cmd = 0;
08035          }
08036          if (useadsi)
08037             adsi_status2(chan, &vms);
08038             
08039          if (!cmd)
08040             cmd = vm_play_folder_name(chan, vms.vmbox);
08041 
08042          vms.starting = 1;
08043          break;
08044       case '3': /* Advanced options */
08045          cmd = 0;
08046          vms.repeats = 0;
08047          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
08048             switch (cmd) {
08049             case '1': /* Reply */
08050                if (vms.lastmsg > -1 && !vms.starting) {
08051                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
08052                   if (cmd == ERROR_LOCK_PATH) {
08053                      res = cmd;
08054                      goto out;
08055                   }
08056                } else
08057                   cmd = ast_play_and_wait(chan, "vm-sorry");
08058                cmd = 't';
08059                break;
08060             case '2': /* Callback */
08061                if (!vms.starting)
08062                   ast_verb(3, "Callback Requested\n");
08063                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
08064                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
08065                   if (cmd == 9) {
08066                      silentexit = 1;
08067                      goto out;
08068                   } else if (cmd == ERROR_LOCK_PATH) {
08069                      res = cmd;
08070                      goto out;
08071                   }
08072                } else 
08073                   cmd = ast_play_and_wait(chan, "vm-sorry");
08074                cmd = 't';
08075                break;
08076             case '3': /* Envelope */
08077                if (vms.lastmsg > -1 && !vms.starting) {
08078                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
08079                   if (cmd == ERROR_LOCK_PATH) {
08080                      res = cmd;
08081                      goto out;
08082                   }
08083                } else
08084                   cmd = ast_play_and_wait(chan, "vm-sorry");
08085                cmd = 't';
08086                break;
08087             case '4': /* Dialout */
08088                if (!ast_strlen_zero(vmu->dialout)) {
08089                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
08090                   if (cmd == 9) {
08091                      silentexit = 1;
08092                      goto out;
08093                   }
08094                } else 
08095                   cmd = ast_play_and_wait(chan, "vm-sorry");
08096                cmd = 't';
08097                break;
08098 
08099             case '5': /* Leave VoiceMail */
08100                if (ast_test_flag(vmu, VM_SVMAIL)) {
08101                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
08102                   if (cmd == ERROR_LOCK_PATH) {
08103                      res = cmd;
08104                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
08105                      goto out;
08106                   }
08107                } else
08108                   cmd = ast_play_and_wait(chan, "vm-sorry");
08109                cmd = 't';
08110                break;
08111                
08112             case '*': /* Return to main menu */
08113                cmd = 't';
08114                break;
08115 
08116             default:
08117                cmd = 0;
08118                if (!vms.starting) {
08119                   cmd = ast_play_and_wait(chan, "vm-toreply");
08120                }
08121                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
08122                   cmd = ast_play_and_wait(chan, "vm-tocallback");
08123                }
08124                if (!cmd && !vms.starting) {
08125                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
08126                }
08127                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
08128                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
08129                }
08130                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
08131                   cmd = ast_play_and_wait(chan, "vm-leavemsg");
08132                if (!cmd)
08133                   cmd = ast_play_and_wait(chan, "vm-starmain");
08134                if (!cmd)
08135                   cmd = ast_waitfordigit(chan, 6000);
08136                if (!cmd)
08137                   vms.repeats++;
08138                if (vms.repeats > 3)
08139                   cmd = 't';
08140             }
08141          }
08142          if (cmd == 't') {
08143             cmd = 0;
08144             vms.repeats = 0;
08145          }
08146          break;
08147       case '4':
08148          if (vms.curmsg > 0) {
08149             vms.curmsg--;
08150             cmd = play_message(chan, vmu, &vms);
08151          } else {
08152             cmd = ast_play_and_wait(chan, "vm-nomore");
08153          }
08154          break;
08155       case '6':
08156          if (vms.curmsg < vms.lastmsg) {
08157             vms.curmsg++;
08158             cmd = play_message(chan, vmu, &vms);
08159          } else {
08160             cmd = ast_play_and_wait(chan, "vm-nomore");
08161          }
08162          break;
08163       case '7':
08164          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
08165             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
08166             if (useadsi)
08167                adsi_delete(chan, &vms);
08168             if (vms.deleted[vms.curmsg]) {
08169                if (play_folder == 0)
08170                   vms.newmessages--;
08171                else if (play_folder == 1)
08172                   vms.oldmessages--;
08173                cmd = ast_play_and_wait(chan, "vm-deleted");
08174             } else {
08175                if (play_folder == 0)
08176                   vms.newmessages++;
08177                else if (play_folder == 1)
08178                   vms.oldmessages++;
08179                cmd = ast_play_and_wait(chan, "vm-undeleted");
08180             }
08181             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
08182                if (vms.curmsg < vms.lastmsg) {
08183                   vms.curmsg++;
08184                   cmd = play_message(chan, vmu, &vms);
08185                } else {
08186                   cmd = ast_play_and_wait(chan, "vm-nomore");
08187                }
08188             }
08189          } else /* Delete not valid if we haven't selected a message */
08190             cmd = 0;
08191 #ifdef IMAP_STORAGE
08192          deleted = 1;
08193 #endif
08194          break;
08195    
08196       case '8':
08197          if (vms.lastmsg > -1) {
08198             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
08199             if (cmd == ERROR_LOCK_PATH) {
08200                res = cmd;
08201                goto out;
08202             }
08203          } else
08204             cmd = ast_play_and_wait(chan, "vm-nomore");
08205          break;
08206       case '9':
08207          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
08208             /* No message selected */
08209             cmd = 0;
08210             break;
08211          }
08212          if (useadsi)
08213             adsi_folders(chan, 1, "Save to folder...");
08214          cmd = get_folder2(chan, "vm-savefolder", 1);
08215          box = 0; /* Shut up compiler */
08216          if (cmd == '#') {
08217             cmd = 0;
08218             break;
08219          } else if (cmd > 0) {
08220             box = cmd = cmd - '0';
08221             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
08222             if (cmd == ERROR_LOCK_PATH) {
08223                res = cmd;
08224                goto out;
08225 #ifndef IMAP_STORAGE
08226             } else if (!cmd) {
08227                vms.deleted[vms.curmsg] = 1;
08228 #endif
08229             } else {
08230                vms.deleted[vms.curmsg] = 0;
08231                vms.heard[vms.curmsg] = 0;
08232             }
08233          }
08234          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
08235          if (useadsi)
08236             adsi_message(chan, &vms);
08237          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
08238          if (!cmd) {
08239             cmd = ast_play_and_wait(chan, "vm-message");
08240             if (!cmd) 
08241                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
08242             if (!cmd)
08243                cmd = ast_play_and_wait(chan, "vm-savedto");
08244             if (!cmd)
08245                cmd = vm_play_folder_name(chan, vms.fn);
08246          } else {
08247             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
08248          }
08249          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
08250             if (vms.curmsg < vms.lastmsg) {
08251                vms.curmsg++;
08252                cmd = play_message(chan, vmu, &vms);
08253             } else {
08254                cmd = ast_play_and_wait(chan, "vm-nomore");
08255             }
08256          }
08257          break;
08258       case '*':
08259          if (!vms.starting) {
08260             cmd = ast_play_and_wait(chan, "vm-onefor");
08261             if (!cmd)
08262                cmd = vm_play_folder_name(chan, vms.vmbox);
08263             if (!cmd)
08264                cmd = ast_play_and_wait(chan, "vm-opts");
08265             if (!cmd)
08266                cmd = vm_instructions(chan, &vms, 1);
08267          } else
08268             cmd = 0;
08269          break;
08270       case '0':
08271          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
08272          if (useadsi)
08273             adsi_status(chan, &vms);
08274          break;
08275       default: /* Nothing */
08276          cmd = vm_instructions(chan, &vms, 0);
08277          break;
08278       }
08279    }
08280    if ((cmd == 't') || (cmd == '#')) {
08281       /* Timeout */
08282       res = 0;
08283    } else {
08284       /* Hangup */
08285       res = -1;
08286    }
08287 
08288 out:
08289    if (res > -1) {
08290       ast_stopstream(chan);
08291       adsi_goodbye(chan);
08292       if (valid) {
08293          if (silentexit)
08294             res = ast_play_and_wait(chan, "vm-dialout");
08295          else 
08296             res = ast_play_and_wait(chan, "vm-goodbye");
08297          if (res > 0)
08298             res = 0;
08299       }
08300       if (useadsi)
08301          ast_adsi_unload_session(chan);
08302    }
08303    if (vmu)
08304       close_mailbox(&vms, vmu);
08305    if (valid) {
08306       int new = 0, old = 0;
08307       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
08308       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
08309       run_externnotify(vmu->context, vmu->mailbox);
08310       ast_app_inboxcount(ext_context, &new, &old);
08311       queue_mwi_event(ext_context, new, old);
08312    }
08313 #ifdef IMAP_STORAGE
08314    /* expunge message - use UID Expunge if supported on IMAP server*/
08315    ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup);
08316    if (vmu && deleted == 1 && expungeonhangup == 1) {
08317       ast_mutex_lock(&vms.lock);
08318 #ifdef HAVE_IMAP_TK2006
08319       if (LEVELUIDPLUS (vms.mailstream)) {
08320          mail_expunge_full(vms.mailstream, NIL, EX_UID);
08321       } else 
08322 #endif
08323          mail_expunge(vms.mailstream);
08324       ast_mutex_unlock(&vms.lock);
08325    }
08326    /*  before we delete the state, we should copy pertinent info
08327     *  back to the persistent model */
08328    if (vmu) {
08329       vmstate_delete(&vms);
08330    }
08331 #endif
08332    if (vmu)
08333       free_user(vmu);
08334    if (vms.deleted)
08335       ast_free(vms.deleted);
08336    if (vms.heard)
08337       ast_free(vms.heard);
08338 
08339 #ifdef IMAP_STORAGE
08340    pthread_setspecific(ts_vmstate.key, NULL);
08341 #endif
08342    return res;
08343 }

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 5360 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(), chan, CONFIG_FLAG_NOCACHE, config_text_file_save(), ast_vm_user::mailbox, make_file(), and STORE.

Referenced by forward_message().

05362    {
05363       int cmd = 0;
05364       int retries = 0, prepend_duration = 0, already_recorded = 0;
05365       signed char zero_gain = 0;
05366       struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
05367       struct ast_config *msg_cfg;
05368       const char *duration_str;
05369       char msgfile[PATH_MAX], backup[PATH_MAX];
05370       char textfile[PATH_MAX];
05371 
05372       /* Must always populate duration correctly */
05373       make_file(msgfile, sizeof(msgfile), curdir, curmsg);
05374       strcpy(textfile, msgfile);
05375       strcpy(backup, msgfile);
05376       strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
05377       strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
05378 
05379       if ((msg_cfg = ast_config_load(textfile, config_flags)) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) {
05380          *duration = atoi(duration_str);
05381       } else {
05382          *duration = 0;
05383       }
05384 
05385       while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
05386          if (cmd)
05387             retries = 0;
05388          switch (cmd) {
05389          case '1': 
05390             /* prepend a message to the current message, update the metadata and return */
05391             prepend_duration = 0;
05392 
05393             /* if we can't read the message metadata, stop now */
05394             if (!msg_cfg) {
05395                cmd = 0;
05396                break;
05397             }
05398 
05399             /* Back up the original file, so we can retry the prepend */
05400             if (already_recorded)
05401                ast_filecopy(backup, msgfile, NULL);
05402             else
05403                ast_filecopy(msgfile, backup, NULL);
05404             already_recorded = 1;
05405 
05406             if (record_gain)
05407                ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
05408 
05409             cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
05410             if (record_gain)
05411                ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
05412 
05413             if (prepend_duration) {
05414                struct ast_category *msg_cat;
05415                /* need enough space for a maximum-length message duration */
05416                char duration_str[12];
05417 
05418                prepend_duration += *duration;
05419                msg_cat = ast_category_get(msg_cfg, "message");
05420                snprintf(duration_str, sizeof(duration_str), "%d", prepend_duration);
05421                if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
05422                   config_text_file_save(textfile, msg_cfg, "app_voicemail");
05423                   STORE(curdir, vmu->mailbox, context, curmsg, chan, vmu, vmfmts, prepend_duration, vms);
05424                }
05425             }
05426 
05427             break;
05428          case '2': 
05429             cmd = 't';
05430             break;
05431          case '*':
05432             cmd = '*';
05433             break;
05434          default: 
05435             cmd = ast_play_and_wait(chan, "vm-forwardoptions");
05436                /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
05437             if (!cmd)
05438                cmd = ast_play_and_wait(chan, "vm-starmain");
05439                /* "press star to return to the main menu" */
05440             if (!cmd)
05441                cmd = ast_waitfordigit(chan, 6000);
05442             if (!cmd)
05443                retries++;
05444             if (retries > 3)
05445                cmd = 't';
05446          }
05447       }
05448 
05449       if (msg_cfg)
05450          ast_config_destroy(msg_cfg);
05451       if (already_recorded)
05452          ast_filedelete(backup, NULL);
05453       if (prepend_duration)
05454          *duration = prepend_duration;
05455 
05456       if (cmd == 't' || cmd == 'S')
05457          cmd = 0;
05458       return cmd;
05459    }

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

Definition at line 7276 of file app_voicemail.c.

References chan, ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_tw().

Referenced by vm_execmain().

07277 {
07278    if (vms->starting && !strcasecmp(chan->language, "tw")) { /* CHINESE (Taiwan) syntax */
07279       return vm_instructions_tw(chan, vms, skipadvanced);
07280    } else {             /* Default to ENGLISH */
07281       return vm_instructions_en(chan, vms, skipadvanced);
07282    }
07283 }

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

Definition at line 7205 of file app_voicemail.c.

References ast_play_and_wait(), ast_waitfordigit(), chan, 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_instructions(), and vm_instructions_tw().

07206 {
07207    int res = 0;
07208    /* Play instructions and wait for new command */
07209    while (!res) {
07210       if (vms->starting) {
07211          if (vms->lastmsg > -1) {
07212             res = ast_play_and_wait(chan, "vm-onefor");
07213             if (!res)
07214                res = vm_play_folder_name(chan, vms->vmbox);
07215          }
07216          if (!res)
07217             res = ast_play_and_wait(chan, "vm-opts");
07218       } else {
07219          if (vms->curmsg)
07220             res = ast_play_and_wait(chan, "vm-prev");
07221          if (!res && !skipadvanced)
07222             res = ast_play_and_wait(chan, "vm-advopts");
07223          if (!res)
07224             res = ast_play_and_wait(chan, "vm-repeat");
07225          if (!res && (vms->curmsg != vms->lastmsg))
07226             res = ast_play_and_wait(chan, "vm-next");
07227          if (!res) {
07228             if (!vms->deleted[vms->curmsg])
07229                res = ast_play_and_wait(chan, "vm-delete");
07230             else
07231                res = ast_play_and_wait(chan, "vm-undelete");
07232             if (!res)
07233                res = ast_play_and_wait(chan, "vm-toforward");
07234             if (!res)
07235                res = ast_play_and_wait(chan, "vm-savemessage");
07236          }
07237       }
07238       if (!res)
07239          res = ast_play_and_wait(chan, "vm-helpexit");
07240       if (!res)
07241          res = ast_waitfordigit(chan, 6000);
07242       if (!res) {
07243          vms->repeats++;
07244          if (vms->repeats > 2) {
07245             res = 't';
07246          }
07247       }
07248    }
07249    return res;
07250 }

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

Definition at line 7252 of file app_voicemail.c.

References ast_play_and_wait(), chan, vm_state::lastmsg, vm_state::starting, vm_instructions_en(), vm_play_folder_name(), and vm_state::vmbox.

Referenced by vm_instructions().

07253 {
07254    int res = 0;
07255    /* Play instructions and wait for new command */
07256    while (!res) {
07257       if (vms->lastmsg > -1) {
07258          res = ast_play_and_wait(chan, "vm-listen");
07259          if (!res)
07260             res = vm_play_folder_name(chan, vms->vmbox);
07261          if (!res)
07262             res = ast_play_and_wait(chan, "press");
07263          if (!res)
07264             res = ast_play_and_wait(chan, "digits/1");
07265       }
07266       if (!res)
07267          res = ast_play_and_wait(chan, "vm-opts");
07268       if (!res) {
07269          vms->starting = 0;
07270          return vm_instructions_en(chan, vms, skipadvanced);
07271       }
07272    }
07273    return res;
07274 }

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

Definition at line 7155 of file app_voicemail.c.

References ast_fileexists(), ast_play_and_wait(), ast_test_flag, chan, ast_vm_user::context, DISPOSE, ast_channel::language, ast_vm_user::mailbox, RETRIEVE, 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_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_tw(), and VM_TEMPGREETWARN.

Referenced by vm_execmain().

07156 {
07157    char prefile[256];
07158    
07159    /* Notify the user that the temp greeting is set and give them the option to remove it */
07160    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07161    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
07162       RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
07163       if (ast_fileexists(prefile, NULL, NULL) > 0) {
07164          ast_play_and_wait(chan, "vm-tempgreetactive");
07165       }
07166       DISPOSE(prefile, -1);
07167    }
07168 
07169    /* Play voicemail intro - syntax is different for different languages */
07170    if (!strcasecmp(chan->language, "de")) {  /* GERMAN syntax */
07171       return vm_intro_de(chan, vms);
07172    } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */
07173       return vm_intro_es(chan, vms);
07174    } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */
07175       return vm_intro_it(chan, vms);
07176    } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */
07177       return vm_intro_fr(chan, vms);
07178    } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */
07179       return vm_intro_nl(chan, vms);
07180    } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */
07181       return vm_intro_pt(chan, vms);
07182    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
07183       return vm_intro_pt_BR(chan, vms);
07184    } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */
07185       return vm_intro_cz(chan, vms);
07186    } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */
07187       return vm_intro_gr(chan, vms);
07188    } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */
07189       return vm_intro_pl(chan, vms);
07190    } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */
07191       return vm_intro_se(chan, vms);
07192    } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */
07193       return vm_intro_no(chan, vms);
07194    } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */
07195       return vm_intro_multilang(chan, vms, "n");
07196    } else if (!strcasecmp(chan->language, "tw")) { /* CHINESE (Taiwan) syntax */
07197       return vm_intro_tw(chan, vms);
07198    } else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */
07199       return vm_intro_multilang(chan, vms, "n");
07200    } else {             /* Default to ENGLISH */
07201       return vm_intro_en(chan, vms);
07202    }
07203 }

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

Definition at line 7056 of file app_voicemail.c.

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

Referenced by vm_intro().

07057 {
07058    int res;
07059    res = ast_play_and_wait(chan, "vm-youhave");
07060    if (!res) {
07061       if (vms->newmessages) {
07062          if (vms->newmessages == 1) {
07063             res = ast_play_and_wait(chan, "digits/jednu");
07064          } else {
07065             res = say_and_wait(chan, vms->newmessages, chan->language);
07066          }
07067          if (!res) {
07068             if ((vms->newmessages == 1))
07069                res = ast_play_and_wait(chan, "vm-novou");
07070             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
07071                res = ast_play_and_wait(chan, "vm-nove");
07072             if (vms->newmessages > 4)
07073                res = ast_play_and_wait(chan, "vm-novych");
07074          }
07075          if (vms->oldmessages && !res)
07076             res = ast_play_and_wait(chan, "vm-and");
07077          else if (!res) {
07078             if ((vms->newmessages == 1))
07079                res = ast_play_and_wait(chan, "vm-zpravu");
07080             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
07081                res = ast_play_and_wait(chan, "vm-zpravy");
07082             if (vms->newmessages > 4)
07083                res = ast_play_and_wait(chan, "vm-zprav");
07084          }
07085       }
07086       if (!res && vms->oldmessages) {
07087          res = say_and_wait(chan, vms->oldmessages, chan->language);
07088          if (!res) {
07089             if ((vms->oldmessages == 1))
07090                res = ast_play_and_wait(chan, "vm-starou");
07091             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
07092                res = ast_play_and_wait(chan, "vm-stare");
07093             if (vms->oldmessages > 4)
07094                res = ast_play_and_wait(chan, "vm-starych");
07095          }
07096          if (!res) {
07097             if ((vms->oldmessages == 1))
07098                res = ast_play_and_wait(chan, "vm-zpravu");
07099             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
07100                res = ast_play_and_wait(chan, "vm-zpravy");
07101             if (vms->oldmessages > 4)
07102                res = ast_play_and_wait(chan, "vm-zprav");
07103          }
07104       }
07105       if (!res) {
07106          if (!vms->oldmessages && !vms->newmessages) {
07107             res = ast_play_and_wait(chan, "vm-no");
07108             if (!res)
07109                res = ast_play_and_wait(chan, "vm-zpravy");
07110          }
07111       }
07112    }
07113    return res;
07114 }

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

Definition at line 6752 of file app_voicemail.c.

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

Referenced by vm_intro().

06753 {
06754    /* Introduce messages they have */
06755    int res;
06756    res = ast_play_and_wait(chan, "vm-youhave");
06757    if (!res) {
06758       if (vms->newmessages) {
06759          if ((vms->newmessages == 1))
06760             res = ast_play_and_wait(chan, "digits/1F");
06761          else
06762             res = say_and_wait(chan, vms->newmessages, chan->language);
06763          if (!res)
06764             res = ast_play_and_wait(chan, "vm-INBOX");
06765          if (vms->oldmessages && !res)
06766             res = ast_play_and_wait(chan, "vm-and");
06767          else if (!res) {
06768             if ((vms->newmessages == 1))
06769                res = ast_play_and_wait(chan, "vm-message");
06770             else
06771                res = ast_play_and_wait(chan, "vm-messages");
06772          }
06773             
06774       }
06775       if (!res && vms->oldmessages) {
06776          if (vms->oldmessages == 1)
06777             res = ast_play_and_wait(chan, "digits/1F");
06778          else
06779             res = say_and_wait(chan, vms->oldmessages, chan->language);
06780          if (!res)
06781             res = ast_play_and_wait(chan, "vm-Old");
06782          if (!res) {
06783             if (vms->oldmessages == 1)
06784                res = ast_play_and_wait(chan, "vm-message");
06785             else
06786                res = ast_play_and_wait(chan, "vm-messages");
06787          }
06788       }
06789       if (!res) {
06790          if (!vms->oldmessages && !vms->newmessages) {
06791             res = ast_play_and_wait(chan, "vm-no");
06792             if (!res)
06793                res = ast_play_and_wait(chan, "vm-messages");
06794          }
06795       }
06796    }
06797    return res;
06798 }

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

Definition at line 6514 of file app_voicemail.c.

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

Referenced by vm_intro().

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

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

Definition at line 6801 of file app_voicemail.c.

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

Referenced by vm_intro().

06802 {
06803    /* Introduce messages they have */
06804    int res;
06805    if (!vms->oldmessages && !vms->newmessages) {
06806       res = ast_play_and_wait(chan, "vm-youhaveno");
06807       if (!res)
06808          res = ast_play_and_wait(chan, "vm-messages");
06809    } else {
06810       res = ast_play_and_wait(chan, "vm-youhave");
06811    }
06812    if (!res) {
06813       if (vms->newmessages) {
06814          if (!res) {
06815             if ((vms->newmessages == 1)) {
06816                res = ast_play_and_wait(chan, "digits/1M");
06817                if (!res)
06818                   res = ast_play_and_wait(chan, "vm-message");
06819                if (!res)
06820                   res = ast_play_and_wait(chan, "vm-INBOXs");
06821             } else {
06822                res = say_and_wait(chan, vms->newmessages, chan->language);
06823                if (!res)
06824                   res = ast_play_and_wait(chan, "vm-messages");
06825                if (!res)
06826                   res = ast_play_and_wait(chan, "vm-INBOX");
06827             }
06828          }
06829          if (vms->oldmessages && !res)
06830             res = ast_play_and_wait(chan, "vm-and");
06831       }
06832       if (vms->oldmessages) {
06833          if (!res) {
06834             if (vms->oldmessages == 1) {
06835                res = ast_play_and_wait(chan, "digits/1M");
06836                if (!res)
06837                   res = ast_play_and_wait(chan, "vm-message");
06838                if (!res)
06839                   res = ast_play_and_wait(chan, "vm-Olds");
06840             } else {
06841                res = say_and_wait(chan, vms->oldmessages, chan->language);
06842                if (!res)
06843                   res = ast_play_and_wait(chan, "vm-messages");
06844                if (!res)
06845                   res = ast_play_and_wait(chan, "vm-Old");
06846             }
06847          }
06848       }
06849    }
06850 return res;
06851 }

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

Definition at line 6899 of file app_voicemail.c.

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

Referenced by vm_intro().

06900 {
06901    /* Introduce messages they have */
06902    int res;
06903    res = ast_play_and_wait(chan, "vm-youhave");
06904    if (!res) {
06905       if (vms->newmessages) {
06906          res = say_and_wait(chan, vms->newmessages, chan->language);
06907          if (!res)
06908             res = ast_play_and_wait(chan, "vm-INBOX");
06909          if (vms->oldmessages && !res)
06910             res = ast_play_and_wait(chan, "vm-and");
06911          else if (!res) {
06912             if ((vms->newmessages == 1))
06913                res = ast_play_and_wait(chan, "vm-message");
06914             else
06915                res = ast_play_and_wait(chan, "vm-messages");
06916          }
06917             
06918       }
06919       if (!res && vms->oldmessages) {
06920          res = say_and_wait(chan, vms->oldmessages, chan->language);
06921          if (!res)
06922             res = ast_play_and_wait(chan, "vm-Old");
06923          if (!res) {
06924             if (vms->oldmessages == 1)
06925                res = ast_play_and_wait(chan, "vm-message");
06926             else
06927                res = ast_play_and_wait(chan, "vm-messages");
06928          }
06929       }
06930       if (!res) {
06931          if (!vms->oldmessages && !vms->newmessages) {
06932             res = ast_play_and_wait(chan, "vm-no");
06933             if (!res)
06934                res = ast_play_and_wait(chan, "vm-messages");
06935          }
06936       }
06937    }
06938    return res;
06939 }

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

Definition at line 6380 of file app_voicemail.c.

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

Referenced by vm_intro().

06381 {
06382    int res = 0;
06383 
06384    if (vms->newmessages) {
06385       res = ast_play_and_wait(chan, "vm-youhave");
06386       if (!res) 
06387          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
06388       if (!res) {
06389          if ((vms->newmessages == 1)) {
06390             res = ast_play_and_wait(chan, "vm-INBOX");
06391             if (!res)
06392                res = ast_play_and_wait(chan, "vm-message");
06393          } else {
06394             res = ast_play_and_wait(chan, "vm-INBOXs");
06395             if (!res)
06396                res = ast_play_and_wait(chan, "vm-messages");
06397          }
06398       }
06399    } else if (vms->oldmessages) {
06400       res = ast_play_and_wait(chan, "vm-youhave");
06401       if (!res)
06402          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
06403       if ((vms->oldmessages == 1)) {
06404          res = ast_play_and_wait(chan, "vm-Old");
06405          if (!res)
06406             res = ast_play_and_wait(chan, "vm-message");
06407       } else {
06408          res = ast_play_and_wait(chan, "vm-Olds");
06409          if (!res)
06410             res = ast_play_and_wait(chan, "vm-messages");
06411       }
06412    } else if (!vms->oldmessages && !vms->newmessages) 
06413       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
06414    return res;
06415 }

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

Definition at line 6558 of file app_voicemail.c.

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

Referenced by vm_intro().

06559 {
06560    /* Introduce messages they have */
06561    int res;
06562    if (!vms->oldmessages && !vms->newmessages)
06563       res = ast_play_and_wait(chan, "vm-no") ||
06564          ast_play_and_wait(chan, "vm-message");
06565    else
06566       res = ast_play_and_wait(chan, "vm-youhave");
06567    if (!res && vms->newmessages) {
06568       res = (vms->newmessages == 1) ?
06569          ast_play_and_wait(chan, "digits/un") ||
06570          ast_play_and_wait(chan, "vm-nuovo") ||
06571          ast_play_and_wait(chan, "vm-message") :
06572          /* 2 or more new messages */
06573          say_and_wait(chan, vms->newmessages, chan->language) ||
06574          ast_play_and_wait(chan, "vm-nuovi") ||
06575          ast_play_and_wait(chan, "vm-messages");
06576       if (!res && vms->oldmessages)
06577          res = ast_play_and_wait(chan, "vm-and");
06578    }
06579    if (!res && vms->oldmessages) {
06580       res = (vms->oldmessages == 1) ?
06581          ast_play_and_wait(chan, "digits/un") ||
06582          ast_play_and_wait(chan, "vm-vecchio") ||
06583          ast_play_and_wait(chan, "vm-message") :
06584          /* 2 or more old messages */
06585          say_and_wait(chan, vms->oldmessages, chan->language) ||
06586          ast_play_and_wait(chan, "vm-vecchi") ||
06587          ast_play_and_wait(chan, "vm-messages");
06588    }
06589    return res;
06590 }

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

Definition at line 6474 of file app_voicemail.c.

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

Referenced by vm_intro().

06475 {
06476    int res;
06477    int lastnum = 0;
06478 
06479    res = ast_play_and_wait(chan, "vm-youhave");
06480 
06481    if (!res && vms->newmessages) {
06482       lastnum = vms->newmessages;
06483 
06484       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06485          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
06486       }
06487 
06488       if (!res && vms->oldmessages) {
06489          res = ast_play_and_wait(chan, "vm-and");
06490       }
06491    }
06492 
06493    if (!res && vms->oldmessages) {
06494       lastnum = vms->oldmessages;
06495 
06496       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06497          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
06498       }
06499    }
06500 
06501    if (!res) {
06502       if (lastnum == 0) {
06503          res = ast_play_and_wait(chan, "vm-no");
06504       }
06505       if (!res) {
06506          res = ast_say_counted_noun(chan, lastnum, "vm-message");
06507       }
06508    }
06509 
06510    return res;
06511 }

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

Definition at line 6942 of file app_voicemail.c.

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

Referenced by vm_intro().

06943 {
06944    /* Introduce messages they have */
06945    int res;
06946    res = ast_play_and_wait(chan, "vm-youhave");
06947    if (!res) {
06948       if (vms->newmessages) {
06949          res = say_and_wait(chan, vms->newmessages, chan->language);
06950          if (!res) {
06951             if (vms->newmessages == 1)
06952                res = ast_play_and_wait(chan, "vm-INBOXs");
06953             else
06954                res = ast_play_and_wait(chan, "vm-INBOX");
06955          }
06956          if (vms->oldmessages && !res)
06957             res = ast_play_and_wait(chan, "vm-and");
06958          else if (!res) {
06959             if ((vms->newmessages == 1))
06960                res = ast_play_and_wait(chan, "vm-message");
06961             else
06962                res = ast_play_and_wait(chan, "vm-messages");
06963          }
06964             
06965       }
06966       if (!res && vms->oldmessages) {
06967          res = say_and_wait(chan, vms->oldmessages, chan->language);
06968          if (!res) {
06969             if (vms->oldmessages == 1)
06970                res = ast_play_and_wait(chan, "vm-Olds");
06971             else
06972                res = ast_play_and_wait(chan, "vm-Old");
06973          }
06974          if (!res) {
06975             if (vms->oldmessages == 1)
06976                res = ast_play_and_wait(chan, "vm-message");
06977             else
06978                res = ast_play_and_wait(chan, "vm-messages");
06979          }
06980       }
06981       if (!res) {
06982          if (!vms->oldmessages && !vms->newmessages) {
06983             res = ast_play_and_wait(chan, "vm-no");
06984             if (!res)
06985                res = ast_play_and_wait(chan, "vm-messages");
06986          }
06987       }
06988    }
06989    return res;
06990 }

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

Definition at line 6708 of file app_voicemail.c.

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

Referenced by vm_intro().

06709 {
06710    /* Introduce messages they have */
06711    int res;
06712 
06713    res = ast_play_and_wait(chan, "vm-youhave");
06714    if (res)
06715       return res;
06716 
06717    if (!vms->oldmessages && !vms->newmessages) {
06718       res = ast_play_and_wait(chan, "vm-no");
06719       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06720       return res;
06721    }
06722 
06723    if (vms->newmessages) {
06724       if ((vms->newmessages == 1)) {
06725          res = ast_play_and_wait(chan, "digits/1");
06726          res = res ? res : ast_play_and_wait(chan, "vm-ny");
06727          res = res ? res : ast_play_and_wait(chan, "vm-message");
06728       } else {
06729          res = say_and_wait(chan, vms->newmessages, chan->language);
06730          res = res ? res : ast_play_and_wait(chan, "vm-nye");
06731          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06732       }
06733       if (!res && vms->oldmessages)
06734          res = ast_play_and_wait(chan, "vm-and");
06735    }
06736    if (!res && vms->oldmessages) {
06737       if (vms->oldmessages == 1) {
06738          res = ast_play_and_wait(chan, "digits/1");
06739          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
06740          res = res ? res : ast_play_and_wait(chan, "vm-message");
06741       } else {
06742          res = say_and_wait(chan, vms->oldmessages, chan->language);
06743          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
06744          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06745       }
06746    }
06747 
06748    return res;
06749 }

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

Definition at line 6593 of file app_voicemail.c.

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

Referenced by vm_intro().

06594 {
06595    /* Introduce messages they have */
06596    int res;
06597    div_t num;
06598 
06599    if (!vms->oldmessages && !vms->newmessages) {
06600       res = ast_play_and_wait(chan, "vm-no");
06601       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06602       return res;
06603    } else {
06604       res = ast_play_and_wait(chan, "vm-youhave");
06605    }
06606 
06607    if (vms->newmessages) {
06608       num = div(vms->newmessages, 10);
06609       if (vms->newmessages == 1) {
06610          res = ast_play_and_wait(chan, "digits/1-a");
06611          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
06612          res = res ? res : ast_play_and_wait(chan, "vm-message");
06613       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06614          if (num.rem == 2) {
06615             if (!num.quot) {
06616                res = ast_play_and_wait(chan, "digits/2-ie");
06617             } else {
06618                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
06619                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06620             }
06621          } else {
06622             res = say_and_wait(chan, vms->newmessages, chan->language);
06623          }
06624          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
06625          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06626       } else {
06627          res = say_and_wait(chan, vms->newmessages, chan->language);
06628          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
06629          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06630       }
06631       if (!res && vms->oldmessages)
06632          res = ast_play_and_wait(chan, "vm-and");
06633    }
06634    if (!res && vms->oldmessages) {
06635       num = div(vms->oldmessages, 10);
06636       if (vms->oldmessages == 1) {
06637          res = ast_play_and_wait(chan, "digits/1-a");
06638          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
06639          res = res ? res : ast_play_and_wait(chan, "vm-message");
06640       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06641          if (num.rem == 2) {
06642             if (!num.quot) {
06643                res = ast_play_and_wait(chan, "digits/2-ie");
06644             } else {
06645                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
06646                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06647             }
06648          } else {
06649             res = say_and_wait(chan, vms->oldmessages, chan->language);
06650          }
06651          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
06652          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06653       } else {
06654          res = say_and_wait(chan, vms->oldmessages, chan->language);
06655          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
06656          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06657       }
06658    }
06659 
06660    return res;
06661 }

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

Definition at line 6993 of file app_voicemail.c.

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

Referenced by vm_intro().

06994 {
06995    /* Introduce messages they have */
06996    int res;
06997    res = ast_play_and_wait(chan, "vm-youhave");
06998    if (!res) {
06999       if (vms->newmessages) {
07000          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
07001          if (!res) {
07002             if ((vms->newmessages == 1)) {
07003                res = ast_play_and_wait(chan, "vm-message");
07004                if (!res)
07005                   res = ast_play_and_wait(chan, "vm-INBOXs");
07006             } else {
07007                res = ast_play_and_wait(chan, "vm-messages");
07008                if (!res)
07009                   res = ast_play_and_wait(chan, "vm-INBOX");
07010             }
07011          }
07012          if (vms->oldmessages && !res)
07013             res = ast_play_and_wait(chan, "vm-and");
07014       }
07015       if (!res && vms->oldmessages) {
07016          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
07017          if (!res) {
07018             if (vms->oldmessages == 1) {
07019                res = ast_play_and_wait(chan, "vm-message");
07020                if (!res)
07021                   res = ast_play_and_wait(chan, "vm-Olds");
07022             } else {
07023                res = ast_play_and_wait(chan, "vm-messages");
07024                if (!res)
07025                   res = ast_play_and_wait(chan, "vm-Old");
07026             }
07027          }
07028       }
07029       if (!res) {
07030          if (!vms->oldmessages && !vms->newmessages) {
07031             res = ast_play_and_wait(chan, "vm-no");
07032             if (!res)
07033                res = ast_play_and_wait(chan, "vm-messages");
07034          }
07035       }
07036    }
07037    return res;
07038 }

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

Definition at line 6854 of file app_voicemail.c.

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

Referenced by vm_intro().

06854                                                                           {
06855    /* Introduce messages they have */
06856    int res;
06857    if (!vms->oldmessages && !vms->newmessages) {
06858       res = ast_play_and_wait(chan, "vm-nomessages");
06859       return res;
06860    } else {
06861       res = ast_play_and_wait(chan, "vm-youhave");
06862    }
06863    if (vms->newmessages) {
06864       if (!res)
06865          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06866       if ((vms->newmessages == 1)) {
06867          if (!res)
06868             res = ast_play_and_wait(chan, "vm-message");
06869          if (!res)
06870             res = ast_play_and_wait(chan, "vm-INBOXs");
06871       } else {
06872          if (!res)
06873             res = ast_play_and_wait(chan, "vm-messages");
06874          if (!res)
06875             res = ast_play_and_wait(chan, "vm-INBOX");
06876       }
06877       if (vms->oldmessages && !res)
06878          res = ast_play_and_wait(chan, "vm-and");
06879    }
06880    if (vms->oldmessages) {
06881       if (!res)
06882          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06883       if (vms->oldmessages == 1) {
06884          if (!res)
06885             res = ast_play_and_wait(chan, "vm-message");
06886          if (!res)
06887             res = ast_play_and_wait(chan, "vm-Olds");
06888       } else {
06889          if (!res)
06890             res = ast_play_and_wait(chan, "vm-messages");
06891          if (!res)
06892             res = ast_play_and_wait(chan, "vm-Old");
06893       }
06894    }
06895    return res;
06896 }

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

Definition at line 6664 of file app_voicemail.c.

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

Referenced by vm_intro().

06665 {
06666    /* Introduce messages they have */
06667    int res;
06668 
06669    res = ast_play_and_wait(chan, "vm-youhave");
06670    if (res)
06671       return res;
06672 
06673    if (!vms->oldmessages && !vms->newmessages) {
06674       res = ast_play_and_wait(chan, "vm-no");
06675       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06676       return res;
06677    }
06678 
06679    if (vms->newmessages) {
06680       if ((vms->newmessages == 1)) {
06681          res = ast_play_and_wait(chan, "digits/ett");
06682          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
06683          res = res ? res : ast_play_and_wait(chan, "vm-message");
06684       } else {
06685          res = say_and_wait(chan, vms->newmessages, chan->language);
06686          res = res ? res : ast_play_and_wait(chan, "vm-nya");
06687          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06688       }
06689       if (!res && vms->oldmessages)
06690          res = ast_play_and_wait(chan, "vm-and");
06691    }
06692    if (!res && vms->oldmessages) {
06693       if (vms->oldmessages == 1) {
06694          res = ast_play_and_wait(chan, "digits/ett");
06695          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
06696          res = res ? res : ast_play_and_wait(chan, "vm-message");
06697       } else {
06698          res = say_and_wait(chan, vms->oldmessages, chan->language);
06699          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
06700          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06701       }
06702    }
06703 
06704    return res;
06705 }

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

Definition at line 7117 of file app_voicemail.c.

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

Referenced by vm_intro().

07118 {
07119    int res;
07120    /* Introduce messages they have */
07121    res = ast_play_and_wait(chan, "vm-you");
07122 
07123    if (!res && vms->newmessages) {
07124       res = ast_play_and_wait(chan, "vm-have");
07125       if (!res)
07126          res = say_and_wait(chan, vms->newmessages, chan->language);
07127       if (!res)
07128          res = ast_play_and_wait(chan, "vm-tong");
07129       if (!res)
07130          res = ast_play_and_wait(chan, "vm-INBOX");
07131       if (vms->oldmessages && !res)
07132          res = ast_play_and_wait(chan, "vm-and");
07133       else if (!res) 
07134          res = ast_play_and_wait(chan, "vm-messages");
07135    }
07136    if (!res && vms->oldmessages) {
07137       res = ast_play_and_wait(chan, "vm-have");
07138       if (!res)
07139          res = say_and_wait(chan, vms->oldmessages, chan->language);
07140       if (!res)
07141          res = ast_play_and_wait(chan, "vm-tong");
07142       if (!res)
07143          res = ast_play_and_wait(chan, "vm-Old");
07144       if (!res)
07145          res = ast_play_and_wait(chan, "vm-messages");
07146    }
07147    if (!res && !vms->oldmessages && !vms->newmessages) {
07148       res = ast_play_and_wait(chan, "vm-haveno");
07149       if (!res)
07150          res = ast_play_and_wait(chan, "vm-messages");
07151    }
07152    return res;
07153 }

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

Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason.

Definition at line 2417 of file app_voicemail.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

02418    {
02419       switch (ast_lock_path(path)) {
02420       case AST_LOCK_TIMEOUT:
02421          return -1;
02422       default:
02423          return 0;
02424       }
02425    }

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

Definition at line 1067 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

01068 {
01069    FILE *p = NULL;
01070    int pfd = mkstemp(template);
01071    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
01072    if (pfd > -1) {
01073       p = fdopen(pfd, "w+");
01074       if (!p) {
01075          close(pfd);
01076          pfd = -1;
01077       }
01078    }
01079    return p;
01080 }

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 7286 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_debug, ast_fileexists(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, chan, LOG_NOTICE, play_record_review(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, vm_mismatch, vm_newpassword, vm_passchanged, and vm_reenterpassword.

Referenced by vm_execmain().

07287 {
07288    int cmd = 0;
07289    int duration = 0;
07290    int tries = 0;
07291    char newpassword[80] = "";
07292    char newpassword2[80] = "";
07293    char prefile[PATH_MAX] = "";
07294    unsigned char buf[256];
07295    int bytes = 0;
07296 
07297    if (ast_adsi_available(chan)) {
07298       bytes += adsi_logo(buf + bytes);
07299       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
07300       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07301       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07302       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07303       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07304    }
07305 
07306    /* First, have the user change their password 
07307       so they won't get here again */
07308    for (;;) {
07309       newpassword[1] = '\0';
07310       newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword);
07311       if (cmd == '#')
07312          newpassword[0] = '\0';
07313       if (cmd < 0 || cmd == 't' || cmd == '#')
07314          return cmd;
07315       cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#");
07316       if (cmd < 0 || cmd == 't' || cmd == '#')
07317          return cmd;
07318       newpassword2[1] = '\0';
07319       newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword);
07320       if (cmd == '#')
07321          newpassword2[0] = '\0';
07322       if (cmd < 0 || cmd == 't' || cmd == '#')
07323          return cmd;
07324       cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#");
07325       if (cmd < 0 || cmd == 't' || cmd == '#')
07326          return cmd;
07327       if (!strcmp(newpassword, newpassword2))
07328          break;
07329       ast_log(LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
07330       cmd = ast_play_and_wait(chan, vm_mismatch);
07331       if (++tries == 3)
07332          return -1;
07333    }
07334    if (pwdchange & PWDCHANGE_INTERNAL)
07335       vm_change_password(vmu, newpassword);
07336    if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd))
07337       vm_change_password_shell(vmu, newpassword);
07338 
07339    ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int)strlen(newpassword));
07340    cmd = ast_play_and_wait(chan, vm_passchanged);
07341 
07342    /* If forcename is set, have the user record their name */  
07343    if (ast_test_flag(vmu, VM_FORCENAME)) {
07344       snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
07345       if (ast_fileexists(prefile, NULL, NULL) < 1) {
07346          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07347          if (cmd < 0 || cmd == 't' || cmd == '#')
07348             return cmd;
07349       }
07350    }
07351 
07352    /* If forcegreetings is set, have the user record their greetings */
07353    if (ast_test_flag(vmu, VM_FORCEGREET)) {
07354       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
07355       if (ast_fileexists(prefile, NULL, NULL) < 1) {
07356          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07357          if (cmd < 0 || cmd == 't' || cmd == '#')
07358             return cmd;
07359       }
07360 
07361       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
07362       if (ast_fileexists(prefile, NULL, NULL) < 1) {
07363          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07364          if (cmd < 0 || cmd == 't' || cmd == '#')
07365             return cmd;
07366       }
07367    }
07368 
07369    return cmd;
07370 }

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 7372 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_debug, ast_fileexists(), ast_log(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_waitfordigit(), chan, ast_vm_user::context, DISPOSE, LOG_NOTICE, ast_vm_user::password, play_record_review(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), vm_mismatch, vm_newpassword, vm_passchanged, vm_reenterpassword, and vm_tempgreeting().

Referenced by vm_execmain().

07373 {
07374    int cmd = 0;
07375    int retries = 0;
07376    int duration = 0;
07377    char newpassword[80] = "";
07378    char newpassword2[80] = "";
07379    char prefile[PATH_MAX] = "";
07380    unsigned char buf[256];
07381    int bytes = 0;
07382 
07383    if (ast_adsi_available(chan)) {
07384       bytes += adsi_logo(buf + bytes);
07385       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
07386       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07387       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07388       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07389       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07390    }
07391    while ((cmd >= 0) && (cmd != 't')) {
07392       if (cmd)
07393          retries = 0;
07394       switch (cmd) {
07395       case '1':
07396          snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
07397          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07398          break;
07399       case '2': 
07400          snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
07401          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07402          break;
07403       case '3': 
07404          snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
07405          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07406          break;
07407       case '4': 
07408          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
07409          break;
07410       case '5':
07411          if (vmu->password[0] == '-') {
07412             cmd = ast_play_and_wait(chan, "vm-no");
07413             break;
07414          }
07415          newpassword[1] = '\0';
07416          newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword);
07417          if (cmd == '#')
07418             newpassword[0] = '\0';
07419          else {
07420             if (cmd < 0)
07421                break;
07422             if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) {
07423                break;
07424             }
07425          }
07426          newpassword2[1] = '\0';
07427          newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword);
07428          if (cmd == '#')
07429             newpassword2[0] = '\0';
07430          else {
07431             if (cmd < 0)
07432                break;
07433 
07434             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) {
07435                break;
07436             }
07437          }
07438          if (strcmp(newpassword, newpassword2)) {
07439             ast_log(LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
07440             cmd = ast_play_and_wait(chan, vm_mismatch);
07441             break;
07442          }
07443          if (pwdchange & PWDCHANGE_INTERNAL)
07444             vm_change_password(vmu, newpassword);
07445          if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd))
07446             vm_change_password_shell(vmu, newpassword);
07447 
07448          ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int)strlen(newpassword));
07449          cmd = ast_play_and_wait(chan, vm_passchanged);
07450          break;
07451       case '*': 
07452          cmd = 't';
07453          break;
07454       default: 
07455          cmd = 0;
07456          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07457          RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
07458          if (ast_fileexists(prefile, NULL, NULL)) {
07459             cmd = ast_play_and_wait(chan, "vm-tmpexists");
07460          }
07461          DISPOSE(prefile, -1);
07462          if (!cmd) {
07463             cmd = ast_play_and_wait(chan, "vm-options");
07464          }
07465          if (!cmd) {
07466             cmd = ast_waitfordigit(chan, 6000);
07467          }
07468          if (!cmd) {
07469             retries++;
07470          }
07471          if (retries > 3) {
07472             cmd = 't';
07473          }
07474       }
07475    }
07476    if (cmd == 't')
07477       cmd = 0;
07478    return cmd;
07479 }

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

Definition at line 6349 of file app_voicemail.c.

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

Referenced by get_folder(), vm_execmain(), vm_instructions_en(), and vm_instructions_tw().

06350 {
06351    int cmd;
06352 
06353    if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */
06354       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
06355       return cmd ? cmd : ast_play_and_wait(chan, mbox);
06356    } else if (!strcasecmp(chan->language, "gr")) {
06357       return vm_play_folder_name_gr(chan, mbox);
06358    } else if (!strcasecmp(chan->language, "pl")) {
06359       return vm_play_folder_name_pl(chan, mbox);
06360    } else if (!strcasecmp(chan->language, "ua")) {  /* Ukrainian syntax */
06361       return vm_play_folder_name_ua(chan, mbox);
06362    } else {  /* Default English */
06363       cmd = ast_play_and_wait(chan, mbox);
06364       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
06365    }
06366 }

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

Definition at line 6302 of file app_voicemail.c.

References ast_play_and_wait(), and chan.

Referenced by vm_play_folder_name().

06303 {
06304    int cmd;
06305    char *buf;
06306 
06307    buf = alloca(strlen(mbox) + 2); 
06308    strcpy(buf, mbox);
06309    strcat(buf, "s");
06310 
06311    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
06312       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
06313       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
06314    } else {
06315       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
06316       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
06317    }
06318 }

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

Definition at line 6320 of file app_voicemail.c.

References ast_play_and_wait(), and chan.

Referenced by vm_play_folder_name().

06321 {
06322    int cmd;
06323 
06324    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
06325       if (!strcasecmp(mbox, "vm-INBOX"))
06326          cmd = ast_play_and_wait(chan, "vm-new-e");
06327       else
06328          cmd = ast_play_and_wait(chan, "vm-old-e");
06329       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
06330    } else {
06331       cmd = ast_play_and_wait(chan, "vm-messages");
06332       return cmd ? cmd : ast_play_and_wait(chan, mbox);
06333    }
06334 }

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

Definition at line 6336 of file app_voicemail.c.

References ast_play_and_wait(), and chan.

Referenced by vm_play_folder_name().

06337 {
06338    int cmd;
06339 
06340    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")) {
06341       cmd = ast_play_and_wait(chan, "vm-messages");
06342       return cmd ? cmd : ast_play_and_wait(chan, mbox);
06343    } else {
06344       cmd = ast_play_and_wait(chan, mbox);
06345       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
06346    }
06347 }

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 7481 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_play_and_wait(), ast_waitfordigit(), chan, ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.

Referenced by vm_options().

07482 {
07483    int cmd = 0;
07484    int retries = 0;
07485    int duration = 0;
07486    char prefile[PATH_MAX] = "";
07487    unsigned char buf[256];
07488    int bytes = 0;
07489 
07490    if (ast_adsi_available(chan)) {
07491       bytes += adsi_logo(buf + bytes);
07492       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
07493       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07494       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07495       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07496       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07497    }
07498 
07499    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07500    while ((cmd >= 0) && (cmd != 't')) {
07501       if (cmd)
07502          retries = 0;
07503       RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
07504       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
07505          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07506          cmd = 't';  
07507       } else {
07508          switch (cmd) {
07509          case '1':
07510             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07511             break;
07512          case '2':
07513             DELETE(prefile, -1, prefile, vmu);
07514             ast_play_and_wait(chan, "vm-tempremoved");
07515             cmd = 't';  
07516             break;
07517          case '*': 
07518             cmd = 't';
07519             break;
07520          default:
07521             cmd = ast_play_and_wait(chan,
07522                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
07523                   "vm-tempgreeting2" : "vm-tempgreeting");
07524             if (!cmd)
07525                cmd = ast_waitfordigit(chan, 6000);
07526             if (!cmd)
07527                retries++;
07528             if (retries > 3)
07529                cmd = 't';
07530          }
07531       }
07532       DISPOSE(prefile, -1);
07533    }
07534    if (cmd == 't')
07535       cmd = 0;
07536    return cmd;
07537 }

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

Definition at line 8546 of file app_voicemail.c.

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

Referenced by load_module().

08547 {
08548    char *s = data, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = "";
08549    struct ast_vm_user vmus;
08550    char *options = NULL;
08551    int silent = 0, skipuser = 0;
08552    int res = -1;
08553    
08554    if (s) {
08555       s = ast_strdupa(s);
08556       user = strsep(&s, ",");
08557       options = strsep(&s, ",");
08558       if (user) {
08559          s = user;
08560          user = strsep(&s, "@");
08561          context = strsep(&s, "");
08562          if (!ast_strlen_zero(user))
08563             skipuser++;
08564          ast_copy_string(mailbox, user, sizeof(mailbox));
08565       }
08566    }
08567 
08568    if (options) {
08569       silent = (strchr(options, 's')) != NULL;
08570    }
08571 
08572    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
08573       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
08574       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
08575       ast_play_and_wait(chan, "auth-thankyou");
08576       res = 0;
08577    }
08578 
08579    return res;
08580 }

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

fill in *tm for current time according to the proper timezone, if any. Return tm so it can be used as a function argument.

Definition at line 3354 of file app_voicemail.c.

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

Referenced by make_email_file(), and sendpage().

03355 {
03356    const struct vm_zone *z = NULL;
03357    struct timeval t = ast_tvnow();
03358 
03359    /* Does this user have a timezone specified? */
03360    if (!ast_strlen_zero(vmu->zonetag)) {
03361       /* Find the zone in the list */
03362       AST_LIST_LOCK(&zones);
03363       AST_LIST_TRAVERSE(&zones, z, list) {
03364          if (!strcmp(z->name, vmu->zonetag))
03365             break;
03366       }
03367       AST_LIST_UNLOCK(&zones);
03368    }
03369    ast_localtime(&t, tm, z ? z->timezone : NULL);
03370    return tm;
03371 }

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

Definition at line 5792 of file app_voicemail.c.

References ast_control_streamfile(), chan, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, and listen_control_stop_key.

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

Definition at line 5784 of file app_voicemail.c.

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

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

05785    {
05786       int res;
05787       if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 
05788          ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05789       return res;
05790    }


Variable Documentation

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

Definition at line 10218 of file app_voicemail.c.

char* addesc = "Comedian Mail" [static]

Definition at line 489 of file app_voicemail.c.

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

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

Referenced by adsi_load_vmail(), and load_config().

int adsiver = 1 [static]

Definition at line 659 of file app_voicemail.c.

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

char* app = "VoiceMail" [static]

Definition at line 561 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 564 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 566 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 567 of file app_voicemail.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 10218 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 643 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

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

Definition at line 655 of file app_voicemail.c.

Referenced by encode_mime_str(), load_config(), make_email_file(), and tds_load_module().

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 646 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

struct ast_cli_entry cli_voicemail[] [static]

Initial value:

 {
   { .handler =  handle_voicemail_show_users , .summary =  "List defined voicemail boxes" ,__VA_ARGS__ },
   { .handler =  handle_voicemail_show_zones , .summary =  "List zone message formats" ,__VA_ARGS__ },
   { .handler =  handle_voicemail_reload , .summary =  "Reload voicemail configuration" ,__VA_ARGS__ },
}

Definition at line 8778 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 493 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 538 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 520 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 550 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 642 of file app_voicemail.c.

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

char* emailbody = NULL [static]

Definition at line 649 of file app_voicemail.c.

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

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

Definition at line 660 of file app_voicemail.c.

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

char* emailsubject = NULL [static]

Definition at line 650 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

char exitcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 644 of file app_voicemail.c.

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

char ext_pass_cmd[128] [static]

Definition at line 469 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 578 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 653 of file app_voicemail.c.

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

struct ast_flags globalflags = {0} [static]

Definition at line 638 of file app_voicemail.c.

char listen_control_forward_key[12] [static]

Definition at line 625 of file app_voicemail.c.

Referenced by load_config(), and wait_file().

char listen_control_pause_key[12] [static]

Definition at line 627 of file app_voicemail.c.

Referenced by load_config(), and wait_file().

char listen_control_restart_key[12] [static]

Definition at line 628 of file app_voicemail.c.

Referenced by load_config(), and wait_file().

char listen_control_reverse_key[12] [static]

Definition at line 626 of file app_voicemail.c.

Referenced by load_config(), and wait_file().

char listen_control_stop_key[12] [static]

Definition at line 629 of file app_voicemail.c.

Referenced by load_config(), and wait_file().

struct ast_custom_function mailbox_exists_acf [static]

Definition at line 8536 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char mailcmd[160] [static]

Definition at line 577 of file app_voicemail.c.

int maxdeletedmsg [static]

Definition at line 574 of file app_voicemail.c.

int maxgreet [static]

Definition at line 584 of file app_voicemail.c.

int maxlogins [static]

Definition at line 586 of file app_voicemail.c.

int maxmsg [static]

Definition at line 573 of file app_voicemail.c.

int maxsilence [static]

Definition at line 572 of file app_voicemail.c.

Referenced by ast_record_review().

struct ast_event_sub* mwi_sub_sub [static]

Subscription to ... MWI event subscriptions

Definition at line 603 of file app_voicemail.c.

Referenced by start_poll_thread(), and stop_poll_thread().

struct ast_event_sub* mwi_unsub_sub [static]

Subscription to ... MWI event un-subscriptions

Definition at line 605 of file app_voicemail.c.

Referenced by start_poll_thread(), and stop_poll_thread().

int my_umask [static]

Definition at line 471 of file app_voicemail.c.

char* pagerbody = NULL [static]

Definition at line 651 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char pagerfromstring[100] [static]

Definition at line 654 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

char* pagersubject = NULL [static]

Definition at line 652 of file app_voicemail.c.

Referenced by load_config(), and sendpage().

ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static]

Definition at line 598 of file app_voicemail.c.

unsigned int poll_freq [static]

Polling frequency

Definition at line 593 of file app_voicemail.c.

ast_mutex_t poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 597 of file app_voicemail.c.

Referenced by mb_poll_thread(), and stop_poll_thread().

unsigned int poll_mailboxes [static]

Poll mailboxes for changes since there is something external to app_voicemail that may change them.

Definition at line 590 of file app_voicemail.c.

pthread_t poll_thread = AST_PTHREADT_NULL [static]

Definition at line 599 of file app_voicemail.c.

unsigned char poll_thread_run [static]

Definition at line 600 of file app_voicemail.c.

int pwdchange = PWDCHANGE_INTERNAL [static]

Definition at line 475 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 640 of file app_voicemail.c.

Referenced by load_config(), and populate_defaults().

char serveremail[80] [static]

Definition at line 576 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 575 of file app_voicemail.c.

int skipms [static]

Definition at line 585 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 579 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char* synopsis_vm = "Leave a Voicemail message" [static]

Definition at line 491 of file app_voicemail.c.

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 535 of file app_voicemail.c.

char* synopsis_vmain = "Check Voicemail messages" [static]

Definition at line 518 of file app_voicemail.c.

char* synopsis_vmauthenticate = "Authenticate with Voicemail passwords" [static]

Definition at line 548 of file app_voicemail.c.

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

Definition at line 487 of file app_voicemail.c.

Referenced by pbx_load_users().

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

Definition at line 272 of file app_voicemail.c.

Referenced by vm_exec(), and vm_execmain().

enum { ... } vm_box

char vm_mismatch[80] = "vm-mismatch" [static]

Definition at line 636 of file app_voicemail.c.

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

char vm_newpassword[80] = "vm-newpassword" [static]

Definition at line 633 of file app_voicemail.c.

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

enum { ... } vm_option_args

enum { ... } vm_option_flags

char vm_passchanged[80] = "vm-passchanged" [static]

Definition at line 634 of file app_voicemail.c.

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

char vm_password[80] = "vm-password" [static]

Definition at line 632 of file app_voicemail.c.

Referenced by load_config(), and vm_authenticate().

char vm_reenterpassword[80] = "vm-reenterpassword" [static]

Definition at line 635 of file app_voicemail.c.

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

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 467 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 580 of file app_voicemail.c.

int vmmaxsecs [static]

Definition at line 583 of file app_voicemail.c.

int vmminsecs [static]

Definition at line 582 of file app_voicemail.c.

double volgain [static]

Definition at line 581 of file app_voicemail.c.

char zonetag[80] [static]

Definition at line 571 of file app_voicemail.c.

Referenced by build_peer().


Generated on Thu Jul 9 13:40:51 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7