Sat Aug 6 00:39:37 2011

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

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

Go to the source code of this file.

Data Structures

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

Defines

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

Enumerations

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

Functions

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

Variables

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


Detailed Description

Comedian Mail - Voicemail System.

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

Definition in file app_voicemail.c.


Define Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 170 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 186 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 187 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 187 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 167 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 163 of file app_voicemail.c.

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

Definition at line 498 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 499 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 494 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"

Definition at line 191 of file app_voicemail.c.

Referenced by base_encode(), make_email_file(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 213 of file app_voicemail.c.

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

#define ERROR_MAILBOX_FULL   -200

Definition at line 214 of file app_voicemail.c.

Referenced by save_to_folder().

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

Definition at line 496 of file app_voicemail.c.

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

#define INTRO   "vm-intro"

Definition at line 176 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 194 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 195 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 178 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 180 of file app_voicemail.c.

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

#define OPERATOR_EXIT   300

Definition at line 215 of file app_voicemail.c.

Referenced by leave_voicemail(), vm_exec(), and vm_execmain().

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

Definition at line 497 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
b,
 ) 

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

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 161 of file app_voicemail.c.

Referenced by run_externnotify().

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

Definition at line 495 of file app_voicemail.c.

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

#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 514 of file app_voicemail.c.

#define VM_ALLOCED   (1 << 13)

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

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

#define VM_DELETE   (1 << 12)

Definition at line 209 of file app_voicemail.c.

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 207 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

Definition at line 201 of file app_voicemail.c.

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

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

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

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

#define VM_OPERATOR   (1 << 1)

Definition at line 198 of file app_voicemail.c.

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

#define VM_PBXSKIP   (1 << 9)

Definition at line 206 of file app_voicemail.c.

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 197 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 199 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 202 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

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

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

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

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 169 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 165 of file app_voicemail.c.

Referenced by create_dirpath(), and leave_voicemail().

#define VOICEMAIL_FILE_MODE   0666

Definition at line 166 of file app_voicemail.c.

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


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_PRIORITY_JUMP 
OPT_AUTOPLAY 

Definition at line 218 of file app_voicemail.c.

00218      {
00219    OPT_SILENT =           (1 << 0),
00220    OPT_BUSY_GREETING =    (1 << 1),
00221    OPT_UNAVAIL_GREETING = (1 << 2),
00222    OPT_RECORDGAIN =       (1 << 3),
00223    OPT_PREPEND_MAILBOX =  (1 << 4),
00224    OPT_PRIORITY_JUMP =    (1 << 5),
00225    OPT_AUTOPLAY =         (1 << 6),
00226 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 228 of file app_voicemail.c.

00228      {
00229    OPT_ARG_RECORDGAIN = 0,
00230    OPT_ARG_PLAYFOLDER = 1,
00231    /* This *must* be the last value in this enum! */
00232    OPT_ARG_ARRAY_SIZE = 2,
00233 } vm_option_args;


Function Documentation

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

Definition at line 4128 of file app_voicemail.c.

References ast_strlen_zero().

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

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

static void __reg_module ( void   )  [static]

Definition at line 9744 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 9744 of file app_voicemail.c.

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

Definition at line 4878 of file app_voicemail.c.

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

Referenced by vm_authenticate(), and vm_execmain().

04879 {
04880    int x;
04881    if (!ast_adsi_available(chan))
04882       return;
04883    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04884    if (x < 0)
04885       return;
04886    if (!x) {
04887       if (adsi_load_vmail(chan, useadsi)) {
04888          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04889          return;
04890       }
04891    } else
04892       *useadsi = 1;
04893 }

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

Definition at line 5067 of file app_voicemail.c.

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

Referenced by vm_execmain().

05068 {
05069    int bytes=0;
05070    unsigned char buf[256];
05071    unsigned char keys[8];
05072 
05073    int x;
05074 
05075    if (!ast_adsi_available(chan))
05076       return;
05077 
05078    /* New meaning for keys */
05079    for (x=0;x<5;x++)
05080       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
05081 
05082    keys[6] = 0x0;
05083    keys[7] = 0x0;
05084 
05085    if (!vms->curmsg) {
05086       /* No prev key, provide "Folder" instead */
05087       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05088    }
05089    if (vms->curmsg >= vms->lastmsg) {
05090       /* If last message ... */
05091       if (vms->curmsg) {
05092          /* but not only message, provide "Folder" instead */
05093          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05094       } else {
05095          /* Otherwise if only message, leave blank */
05096          keys[3] = 1;
05097       }
05098    }
05099 
05100    /* If deleted, show "undeleted" */
05101    if (vms->deleted[vms->curmsg]) 
05102       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
05103 
05104    /* Except "Exit" */
05105    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
05106    bytes += ast_adsi_set_keys(buf + bytes, keys);
05107    bytes += ast_adsi_voice_mode(buf + bytes, 0);
05108 
05109    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05110 }

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

Definition at line 4943 of file app_voicemail.c.

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

Referenced by vm_execmain().

04944 {
04945    unsigned char buf[256];
04946    int bytes=0;
04947    unsigned char keys[8];
04948    int x,y;
04949 
04950    if (!ast_adsi_available(chan))
04951       return;
04952 
04953    for (x=0;x<5;x++) {
04954       y = ADSI_KEY_APPS + 12 + start + x;
04955       if (y > ADSI_KEY_APPS + 12 + 4)
04956          y = 0;
04957       keys[x] = ADSI_KEY_SKT | y;
04958    }
04959    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
04960    keys[6] = 0;
04961    keys[7] = 0;
04962 
04963    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
04964    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
04965    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04966    bytes += ast_adsi_set_keys(buf + bytes, keys);
04967    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04968 
04969    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04970 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

Definition at line 5215 of file app_voicemail.c.

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

Referenced by vm_execmain().

05216 {
05217    unsigned char buf[256];
05218    int bytes=0;
05219 
05220    if (!ast_adsi_available(chan))
05221       return;
05222    bytes += adsi_logo(buf + bytes);
05223    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
05224    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
05225    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05226    bytes += ast_adsi_voice_mode(buf + bytes, 0);
05227 
05228    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05229 }

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

Definition at line 4747 of file app_voicemail.c.

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

Referenced by adsi_begin().

04748 {
04749    unsigned char buf[256];
04750    int bytes=0;
04751    int x;
04752    char num[5];
04753 
04754    *useadsi = 0;
04755    bytes += ast_adsi_data_mode(buf + bytes);
04756    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04757 
04758    bytes = 0;
04759    bytes += adsi_logo(buf);
04760    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04761 #ifdef DISPLAY
04762    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04763 #endif
04764    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04765    bytes += ast_adsi_data_mode(buf + bytes);
04766    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04767 
04768    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04769       bytes = 0;
04770       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04771       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04772       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04773       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04774       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04775       return 0;
04776    }
04777 
04778 #ifdef DISPLAY
04779    /* Add a dot */
04780    bytes = 0;
04781    bytes += ast_adsi_logo(buf);
04782    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04783    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04784    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04785    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04786 #endif
04787    bytes = 0;
04788    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04789    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04790    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04791    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04792    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04793    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04794    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04795 
04796 #ifdef DISPLAY
04797    /* Add another dot */
04798    bytes = 0;
04799    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04800    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04801 
04802    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04803    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04804 #endif
04805 
04806    bytes = 0;
04807    /* These buttons we load but don't use yet */
04808    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04809    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04810    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04811    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04812    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04813    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04814    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04815 
04816 #ifdef DISPLAY
04817    /* Add another dot */
04818    bytes = 0;
04819    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04820    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04821    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04822 #endif
04823 
04824    bytes = 0;
04825    for (x=0;x<5;x++) {
04826       snprintf(num, sizeof(num), "%d", x);
04827       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04828    }
04829    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04830    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04831 
04832 #ifdef DISPLAY
04833    /* Add another dot */
04834    bytes = 0;
04835    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04836    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04837    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04838 #endif
04839 
04840    if (ast_adsi_end_download(chan)) {
04841       bytes = 0;
04842       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04843       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04844       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04845       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04846       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04847       return 0;
04848    }
04849    bytes = 0;
04850    bytes += ast_adsi_download_disconnect(buf + bytes);
04851    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04852    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04853 
04854    if (option_debug)
04855       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
04856 
04857 #ifdef DISPLAY
04858    /* Add last dot */
04859    bytes = 0;
04860    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04861    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04862 #endif
04863    if (option_debug)
04864       ast_log(LOG_DEBUG, "Restarting session...\n");
04865 
04866    bytes = 0;
04867    /* Load the session now */
04868    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04869       *useadsi = 1;
04870       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04871    } else
04872       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04873 
04874    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04875    return 0;
04876 }

static void adsi_login ( struct ast_channel chan  )  [static]

Definition at line 4895 of file app_voicemail.c.

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

Referenced by vm_authenticate().

04896 {
04897    unsigned char buf[256];
04898    int bytes=0;
04899    unsigned char keys[8];
04900    int x;
04901    if (!ast_adsi_available(chan))
04902       return;
04903 
04904    for (x=0;x<8;x++)
04905       keys[x] = 0;
04906    /* Set one key for next */
04907    keys[3] = ADSI_KEY_APPS + 3;
04908 
04909    bytes += adsi_logo(buf + bytes);
04910    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04911    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04912    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04913    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04914    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
04915    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
04916    bytes += ast_adsi_set_keys(buf + bytes, keys);
04917    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04918    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04919 }

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

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

04740 {
04741    int bytes = 0;
04742    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04743    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04744    return bytes;
04745 }

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

Definition at line 4972 of file app_voicemail.c.

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

Referenced by play_message(), and vm_execmain().

04973 {
04974    int bytes=0;
04975    unsigned char buf[256]; 
04976    char buf1[256], buf2[256];
04977    char fn2[PATH_MAX];
04978 
04979    char cid[256]="";
04980    char *val;
04981    char *name, *num;
04982    char datetime[21]="";
04983    FILE *f;
04984 
04985    unsigned char keys[8];
04986 
04987    int x;
04988 
04989    if (!ast_adsi_available(chan))
04990       return;
04991 
04992    /* Retrieve important info */
04993    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
04994    f = fopen(fn2, "r");
04995    if (f) {
04996       while (!feof(f)) {   
04997          if (!fgets((char *)buf, sizeof(buf), f)) {
04998             continue;
04999          }
05000          if (!feof(f)) {
05001             char *stringp=NULL;
05002             stringp = (char *)buf;
05003             strsep(&stringp, "=");
05004             val = strsep(&stringp, "=");
05005             if (!ast_strlen_zero(val)) {
05006                if (!strcmp((char *)buf, "callerid"))
05007                   ast_copy_string(cid, val, sizeof(cid));
05008                if (!strcmp((char *)buf, "origdate"))
05009                   ast_copy_string(datetime, val, sizeof(datetime));
05010             }
05011          }
05012       }
05013       fclose(f);
05014    }
05015    /* New meaning for keys */
05016    for (x=0;x<5;x++)
05017       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
05018    keys[6] = 0x0;
05019    keys[7] = 0x0;
05020 
05021    if (!vms->curmsg) {
05022       /* No prev key, provide "Folder" instead */
05023       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05024    }
05025    if (vms->curmsg >= vms->lastmsg) {
05026       /* If last message ... */
05027       if (vms->curmsg) {
05028          /* but not only message, provide "Folder" instead */
05029          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
05030          bytes += ast_adsi_voice_mode(buf + bytes, 0);
05031 
05032       } else {
05033          /* Otherwise if only message, leave blank */
05034          keys[3] = 1;
05035       }
05036    }
05037 
05038    if (!ast_strlen_zero(cid)) {
05039       ast_callerid_parse(cid, &name, &num);
05040       if (!name)
05041          name = num;
05042    } else
05043       name = "Unknown Caller";
05044 
05045    /* If deleted, show "undeleted" */
05046 
05047    if (vms->deleted[vms->curmsg])
05048       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
05049 
05050    /* Except "Exit" */
05051    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
05052    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
05053       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
05054    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
05055 
05056    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
05057    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
05058    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
05059    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
05060    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05061    bytes += ast_adsi_set_keys(buf + bytes, keys);
05062    bytes += ast_adsi_voice_mode(buf + bytes, 0);
05063 
05064    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05065 }

static void adsi_password ( struct ast_channel chan  )  [static]

Definition at line 4921 of file app_voicemail.c.

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

Referenced by vm_authenticate().

04922 {
04923    unsigned char buf[256];
04924    int bytes=0;
04925    unsigned char keys[8];
04926    int x;
04927    if (!ast_adsi_available(chan))
04928       return;
04929 
04930    for (x=0;x<8;x++)
04931       keys[x] = 0;
04932    /* Set one key for next */
04933    keys[3] = ADSI_KEY_APPS + 3;
04934 
04935    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04936    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
04937    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
04938    bytes += ast_adsi_set_keys(buf + bytes, keys);
04939    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04940    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04941 }

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

Definition at line 5112 of file app_voicemail.c.

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

Referenced by vm_execmain().

05113 {
05114    unsigned char buf[256] = "";
05115    char buf1[256] = "", buf2[256] = "";
05116    int bytes=0;
05117    unsigned char keys[8];
05118    int x;
05119 
05120    char *newm = (vms->newmessages == 1) ? "message" : "messages";
05121    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
05122    if (!ast_adsi_available(chan))
05123       return;
05124    if (vms->newmessages) {
05125       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
05126       if (vms->oldmessages) {
05127          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
05128          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
05129       } else {
05130          snprintf(buf2, sizeof(buf2), "%s.", newm);
05131       }
05132    } else if (vms->oldmessages) {
05133       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
05134       snprintf(buf2, sizeof(buf2), "%s.", oldm);
05135    } else {
05136       strcpy(buf1, "You have no messages.");
05137       buf2[0] = ' ';
05138       buf2[1] = '\0';
05139    }
05140    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
05141    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
05142    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05143 
05144    for (x=0;x<6;x++)
05145       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
05146    keys[6] = 0;
05147    keys[7] = 0;
05148 
05149    /* Don't let them listen if there are none */
05150    if (vms->lastmsg < 0)
05151       keys[0] = 1;
05152    bytes += ast_adsi_set_keys(buf + bytes, keys);
05153 
05154    bytes += ast_adsi_voice_mode(buf + bytes, 0);
05155 
05156    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05157 }

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

Definition at line 5159 of file app_voicemail.c.

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

Referenced by vm_execmain().

05160 {
05161    unsigned char buf[256] = "";
05162    char buf1[256] = "", buf2[256] = "";
05163    int bytes=0;
05164    unsigned char keys[8];
05165    int x;
05166 
05167    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
05168 
05169    if (!ast_adsi_available(chan))
05170       return;
05171 
05172    /* Original command keys */
05173    for (x=0;x<6;x++)
05174       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
05175 
05176    keys[6] = 0;
05177    keys[7] = 0;
05178 
05179    if ((vms->lastmsg + 1) < 1)
05180       keys[0] = 0;
05181 
05182    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
05183       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
05184 
05185    if (vms->lastmsg + 1)
05186       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
05187    else
05188       strcpy(buf2, "no messages.");
05189    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
05190    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
05191    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
05192    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
05193    bytes += ast_adsi_set_keys(buf + bytes, keys);
05194 
05195    bytes += ast_adsi_voice_mode(buf + bytes, 0);
05196 
05197    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
05198    
05199 }

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

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

Referenced by vm_execmain().

09333 {
09334    int res = 0;
09335    char filename[PATH_MAX];
09336    struct ast_config *msg_cfg = NULL;
09337    const char *origtime, *context;
09338    char *cid, *name, *num;
09339    int retries = 0;
09340 
09341    vms->starting = 0; 
09342    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09343 
09344    /* Retrieve info from VM attribute file */
09345    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
09346    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
09347    RETRIEVE(vms->curdir, vms->curmsg, vmu);
09348    msg_cfg = ast_config_load(filename);
09349    DISPOSE(vms->curdir, vms->curmsg);
09350    if (!msg_cfg) {
09351       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
09352       return 0;
09353    }
09354 
09355    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
09356       ast_config_destroy(msg_cfg);
09357       return 0;
09358    }
09359 
09360    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
09361 
09362    context = ast_variable_retrieve(msg_cfg, "message", "context");
09363    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
09364       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
09365    switch (option) {
09366    case 3:
09367       if (!res)
09368          res = play_message_datetime(chan, vmu, origtime, filename);
09369       if (!res)
09370          res = play_message_callerid(chan, vms, cid, context, 0);
09371 
09372       res = 't';
09373       break;
09374 
09375    case 2:  /* Call back */
09376 
09377       if (ast_strlen_zero(cid))
09378          break;
09379 
09380       ast_callerid_parse(cid, &name, &num);
09381       while ((res > -1) && (res != 't')) {
09382          switch (res) {
09383          case '1':
09384             if (num) {
09385                /* Dial the CID number */
09386                res = dialout(chan, vmu, num, vmu->callback);
09387                if (res) {
09388                   ast_config_destroy(msg_cfg);
09389                   return 9;
09390                }
09391             } else {
09392                res = '2';
09393             }
09394             break;
09395 
09396          case '2':
09397             /* Want to enter a different number, can only do this if there's a dialout context for this user */
09398             if (!ast_strlen_zero(vmu->dialout)) {
09399                res = dialout(chan, vmu, NULL, vmu->dialout);
09400                if (res) {
09401                   ast_config_destroy(msg_cfg);
09402                   return 9;
09403                }
09404             } else {
09405                if (option_verbose > 2)
09406                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
09407                res = ast_play_and_wait(chan, "vm-sorry");
09408             }
09409             ast_config_destroy(msg_cfg);
09410             return res;
09411          case '*':
09412             res = 't';
09413             break;
09414          case '3':
09415          case '4':
09416          case '5':
09417          case '6':
09418          case '7':
09419          case '8':
09420          case '9':
09421          case '0':
09422 
09423             res = ast_play_and_wait(chan, "vm-sorry");
09424             retries++;
09425             break;
09426          default:
09427             if (num) {
09428                if (option_verbose > 2)
09429                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
09430                res = ast_play_and_wait(chan, "vm-num-i-have");
09431                if (!res)
09432                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
09433                if (!res)
09434                   res = ast_play_and_wait(chan, "vm-tocallnum");
09435                /* Only prompt for a caller-specified number if there is a dialout context specified */
09436                if (!ast_strlen_zero(vmu->dialout)) {
09437                   if (!res)
09438                      res = ast_play_and_wait(chan, "vm-calldiffnum");
09439                }
09440             } else {
09441                res = ast_play_and_wait(chan, "vm-nonumber");
09442                if (!ast_strlen_zero(vmu->dialout)) {
09443                   if (!res)
09444                      res = ast_play_and_wait(chan, "vm-toenternumber");
09445                }
09446             }
09447             if (!res)
09448                res = ast_play_and_wait(chan, "vm-star-cancel");
09449             if (!res)
09450                res = ast_waitfordigit(chan, 6000);
09451             if (!res) {
09452                retries++;
09453                if (retries > 3)
09454                   res = 't';
09455             }
09456             break; 
09457             
09458          }
09459          if (res == 't')
09460             res = 0;
09461          else if (res == '*')
09462             res = -1;
09463       }
09464       break;
09465       
09466    case 1:  /* Reply */
09467       /* Send reply directly to sender */
09468       if (ast_strlen_zero(cid))
09469          break;
09470 
09471       ast_callerid_parse(cid, &name, &num);
09472       if (!num) {
09473          if (option_verbose > 2)
09474             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
09475          if (!res)
09476             res = ast_play_and_wait(chan, "vm-nonumber");
09477          ast_config_destroy(msg_cfg);
09478          return res;
09479       } else {
09480          struct ast_vm_user vmu2;
09481          if (find_user(&vmu2, vmu->context, num)) {
09482             struct leave_vm_options leave_options;
09483             char mailbox[AST_MAX_EXTENSION * 2 + 2];
09484             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
09485 
09486             if (option_verbose > 2)
09487                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
09488             
09489             memset(&leave_options, 0, sizeof(leave_options));
09490             leave_options.record_gain = record_gain;
09491             res = leave_voicemail(chan, mailbox, &leave_options);
09492             if (!res)
09493                res = 't';
09494             ast_config_destroy(msg_cfg);
09495             return res;
09496          } else {
09497             /* Sender has no mailbox, can't reply */
09498             if (option_verbose > 2)
09499                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
09500             ast_play_and_wait(chan, "vm-nobox");
09501             res = 't';
09502             ast_config_destroy(msg_cfg);
09503             return res;
09504          }
09505       } 
09506       res = 0;
09507 
09508       break;
09509    }
09510 
09511 #ifndef IMAP_STORAGE
09512    ast_config_destroy(msg_cfg);
09513 
09514    if (!res) {
09515       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09516       vms->heard[msg] = 1;
09517       res = wait_file(chan, vms, vms->fn);
09518    }
09519 #endif
09520    return res;
09521 }

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

Definition at line 8363 of file app_voicemail.c.

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

Referenced by load_config().

08364 {
08365    /* Assumes lock is already held */
08366    char *tmp;
08367    char *stringp;
08368    char *s;
08369    struct ast_vm_user *vmu;
08370 
08371    tmp = ast_strdupa(data);
08372 
08373    if ((vmu = find_or_create(context, mbox))) {
08374       populate_defaults(vmu);
08375 
08376       stringp = tmp;
08377       if ((s = strsep(&stringp, ","))) 
08378          ast_copy_string(vmu->password, s, sizeof(vmu->password));
08379       if (stringp && (s = strsep(&stringp, ","))) 
08380          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
08381       if (stringp && (s = strsep(&stringp, ","))) 
08382          ast_copy_string(vmu->email, s, sizeof(vmu->email));
08383       if (stringp && (s = strsep(&stringp, ","))) 
08384          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
08385       if (stringp && (s = strsep(&stringp, ","))) 
08386          apply_options(vmu, s);
08387    }
08388    return 0;
08389 }

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

Definition at line 685 of file app_voicemail.c.

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

Referenced by apply_options(), and apply_options_full().

00686 {
00687    int x;
00688    if (!strcasecmp(var, "attach")) {
00689       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00690    } else if (!strcasecmp(var, "attachfmt")) {
00691       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00692    } else if (!strcasecmp(var, "preprocesscmd")) {
00693       ast_copy_string(vmu->preprocesscmd, value, sizeof(vmu->preprocesscmd));
00694    } else if (!strcasecmp(var, "preprocessfmt")) {
00695       ast_copy_string(vmu->preprocessfmt, value, sizeof(vmu->preprocessfmt));
00696    } else if (!strcasecmp(var, "serveremail")) {
00697       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00698    } else if (!strcasecmp(var, "language")) {
00699       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00700    } else if (!strcasecmp(var, "tz")) {
00701       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00702 #ifdef IMAP_STORAGE
00703    } else if (!strcasecmp(var, "imapuser")) {
00704       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00705       vmu->imapversion = imapversion;
00706    } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
00707       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00708       vmu->imapversion = imapversion;
00709    } else if (!strcasecmp(var, "imapvmshareid")) {
00710       ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
00711       vmu->imapversion = imapversion;
00712 #endif
00713    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00714       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00715    } else if (!strcasecmp(var, "saycid")){
00716       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00717    } else if (!strcasecmp(var,"sendvoicemail")){
00718       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00719    } else if (!strcasecmp(var, "review")){
00720       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00721    } else if (!strcasecmp(var, "tempgreetwarn")){
00722       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00723    } else if (!strcasecmp(var, "operator")){
00724       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00725    } else if (!strcasecmp(var, "envelope")){
00726       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00727    } else if (!strcasecmp(var, "sayduration")){
00728       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00729    } else if (!strcasecmp(var, "saydurationm")){
00730       if (sscanf(value, "%30d", &x) == 1) {
00731          vmu->saydurationm = x;
00732       } else {
00733          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00734       }
00735    } else if (!strcasecmp(var, "forcename")){
00736       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00737    } else if (!strcasecmp(var, "forcegreetings")){
00738       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00739    } else if (!strcasecmp(var, "callback")) {
00740       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00741    } else if (!strcasecmp(var, "dialout")) {
00742       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00743    } else if (!strcasecmp(var, "exitcontext")) {
00744       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00745    } else if (!strcasecmp(var, "maxmsg")) {
00746       vmu->maxmsg = atoi(value);
00747       if (vmu->maxmsg <= 0) {
00748          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00749          vmu->maxmsg = MAXMSG;
00750       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00751          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00752          vmu->maxmsg = MAXMSGLIMIT;
00753       }
00754    } else if (!strcasecmp(var, "volgain")) {
00755       sscanf(value, "%30lf", &vmu->volgain);
00756    } else if (!strcasecmp(var, "options")) {
00757       apply_options(vmu, value);
00758    }
00759 }

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

Definition at line 776 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00777 {  /* Destructively Parse options and apply */
00778    char *stringp;
00779    char *s;
00780    char *var, *value;
00781    stringp = ast_strdupa(options);
00782    while ((s = strsep(&stringp, "|"))) {
00783       value = s;
00784       if ((var = strsep(&value, "=")) && value) {
00785          apply_option(vmu, var, value);
00786       }
00787    }  
00788 }

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

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

00791 {
00792    struct ast_variable *tmp;
00793    tmp = var;
00794    while (tmp) {
00795       if (!strcasecmp(tmp->name, "vmsecret")) {
00796          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00797       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00798          if (ast_strlen_zero(retval->password))
00799             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00800       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00801          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00802       } else if (!strcasecmp(tmp->name, "pager")) {
00803          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00804       } else if (!strcasecmp(tmp->name, "email")) {
00805          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00806       } else if (!strcasecmp(tmp->name, "fullname")) {
00807          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00808       } else if (!strcasecmp(tmp->name, "context")) {
00809          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00810 #ifdef IMAP_STORAGE
00811       } else if (!strcasecmp(tmp->name, "imapuser")) {
00812          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00813          retval->imapversion = imapversion;
00814       } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) {
00815          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00816          retval->imapversion = imapversion;
00817       } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
00818          ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
00819          retval->imapversion = imapversion;
00820 #endif
00821       } else
00822          apply_option(retval, tmp->name, tmp->value);
00823       tmp = tmp->next;
00824    } 
00825 }

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

Definition at line 3176 of file app_voicemail.c.

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

Referenced by make_email_file().

03177 {
03178    unsigned char dtable[BASEMAXINLINE];
03179    int i,hiteof= 0;
03180    FILE *fi;
03181    struct baseio bio;
03182 
03183    memset(&bio, 0, sizeof(bio));
03184    bio.iocp = BASEMAXINLINE;
03185 
03186    if (!(fi = fopen(filename, "rb"))) {
03187       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
03188       return -1;
03189    }
03190 
03191    for (i= 0;i<9;i++) {
03192       dtable[i]= 'A'+i;
03193       dtable[i+9]= 'J'+i;
03194       dtable[26+i]= 'a'+i;
03195       dtable[26+i+9]= 'j'+i;
03196    }
03197    for (i= 0;i<8;i++) {
03198       dtable[i+18]= 'S'+i;
03199       dtable[26+i+18]= 's'+i;
03200    }
03201    for (i= 0;i<10;i++) {
03202       dtable[52+i]= '0'+i;
03203    }
03204    dtable[62]= '+';
03205    dtable[63]= '/';
03206 
03207    while (!hiteof){
03208       unsigned char igroup[3],ogroup[4];
03209       int c,n;
03210 
03211       igroup[0]= igroup[1]= igroup[2]= 0;
03212 
03213       for (n= 0;n<3;n++) {
03214          if ((c = inchar(&bio, fi)) == EOF) {
03215             hiteof= 1;
03216             break;
03217          }
03218 
03219          igroup[n]= (unsigned char)c;
03220       }
03221 
03222       if (n> 0) {
03223          ogroup[0]= dtable[igroup[0]>>2];
03224          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
03225          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
03226          ogroup[3]= dtable[igroup[2]&0x3F];
03227 
03228          if (n<3) {
03229             ogroup[3]= '=';
03230 
03231             if (n<2)
03232                ogroup[2]= '=';
03233          }
03234 
03235          for (i= 0;i<4;i++)
03236             ochar(&bio, ogroup[i], so);
03237       }
03238    }
03239 
03240    fclose(fi);
03241    
03242    if (fputs(ENDL, so) == EOF) {
03243       return 0;
03244    }
03245 
03246    return 1;
03247 }

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

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

00762 {
00763    int res = -1;
00764    if (!strcmp(vmu->password, password)) {
00765       /* No change (but an update would return 0 rows updated, so we opt out here) */
00766       res = 0;
00767    } else if (!ast_strlen_zero(vmu->uniqueid)) {
00768       if (ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL) > 0) {
00769          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00770          res = 0;
00771       }
00772    }
00773    return res;
00774 }

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

Referenced by make_email_file().

03346 {
03347    for (; *str; str++) {
03348       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03349          return 1;
03350       }
03351    }
03352    return 0;
03353 }

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

Definition at line 6130 of file app_voicemail.c.

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

Referenced by vm_execmain().

06131 {
06132    int x = 0;
06133 #ifndef IMAP_STORAGE
06134    int last_msg_index;
06135    int res = 0, nummsg;
06136 #endif
06137 
06138    if (vms->lastmsg <= -1)
06139       goto done;
06140 
06141    vms->curmsg = -1; 
06142 #ifndef IMAP_STORAGE
06143    /* Get the deleted messages fixed */ 
06144    if (vm_lock_path(vms->curdir))
06145       return ERROR_LOCK_PATH;
06146 
06147    last_msg_index = last_message_index(vmu, vms->curdir);
06148    if (last_msg_index !=  vms->lastmsg) {
06149       ast_log(LOG_NOTICE, "%d messages arrived while mailbox was open\n", last_msg_index - vms->lastmsg);
06150    }
06151  
06152    /* must check up to last detected message, just in case it is erroneously greater than maxmsg */
06153    for (x = 0; x < last_msg_index + 1; x++) { 
06154       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
06155          /* Save this message.  It's not in INBOX or hasn't been heard */ 
06156          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
06157          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
06158             break;
06159          vms->curmsg++; 
06160          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
06161          if (strcmp(vms->fn, vms->fn2)) { 
06162             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
06163          } 
06164       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
06165          /* Move to old folder before deleting */ 
06166          res = save_to_folder(vmu, vms, x, 1);
06167          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
06168             /* If save failed do not delete the message */
06169             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
06170             vms->deleted[x] = 0;
06171             vms->heard[x] = 0;
06172             --x;
06173          } 
06174       } 
06175    } 
06176 
06177    /* Delete ALL remaining messages */
06178    nummsg = x - 1;
06179    for (x = vms->curmsg + 1; x <= nummsg; x++) {
06180       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
06181       if (EXISTS(vms->curdir, x, vms->fn, NULL))
06182          DELETE(vms->curdir, x, vms->fn, vmu);
06183    }
06184    ast_unlock_path(vms->curdir);
06185 #else /* defined(IMAP_STORAGE) */
06186    if (vms->deleted) {
06187       /* Since we now expunge after each delete, deleting in reverse order
06188        * ensures that no reordering occurs between each step. */
06189       for (x = vms->dh_arraysize - 1; x >= 0; x--) {
06190          if (vms->deleted[x]) {
06191             if (option_debug > 2) {
06192                ast_log(LOG_DEBUG, "IMAP delete of %d\n", x);
06193             }
06194             DELETE(vms->curdir, x, vms->fn, vmu);
06195          }
06196       }
06197    }
06198 #endif
06199 
06200 done:
06201    if (vms->deleted)
06202       memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 
06203    if (vms->heard)
06204       memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 
06205 
06206    return 0;
06207 }

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

Definition at line 8552 of file app_voicemail.c.

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

08553 {
08554    int which = 0;
08555    int wordlen;
08556    struct ast_vm_user *vmu;
08557    const char *context = "";
08558 
08559    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08560    if (pos > 4)
08561       return NULL;
08562    if (pos == 3)
08563       return (state == 0) ? ast_strdup("for") : NULL;
08564    wordlen = strlen(word);
08565    AST_LIST_TRAVERSE(&users, vmu, list) {
08566       if (!strncasecmp(word, vmu->context, wordlen)) {
08567          if (context && strcmp(context, vmu->context) && ++which > state)
08568             return ast_strdup(vmu->context);
08569          /* ignore repeated contexts ? */
08570          context = vmu->context;
08571       }
08572    }
08573    return NULL;
08574 }

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

Definition at line 3047 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

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

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

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

Referenced by forward_message(), and leave_voicemail().

04069 {
04070    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
04071    const char *frombox = mbox(imbox);
04072    int recipmsgnum;
04073    int res = 0;
04074 
04075    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
04076 
04077    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
04078    
04079    if (!dir)
04080       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
04081    else
04082       ast_copy_string(fromdir, dir, sizeof(fromdir));
04083 
04084    make_file(frompath, sizeof(frompath), fromdir, msgnum);
04085 
04086    if (vm_lock_path(todir))
04087       return ERROR_LOCK_PATH;
04088 
04089    recipmsgnum = 0;
04090    do {
04091       make_file(topath, sizeof(topath), todir, recipmsgnum);
04092       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
04093          break;
04094       recipmsgnum++;
04095    } while (recipmsgnum < recip->maxmsg);
04096    if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) {
04097 #ifndef ODBC_STORAGE
04098       if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
04099          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
04100       } else {
04101 #endif
04102          /* If we are prepending a message for ODBC, then the message already
04103           * exists in the database, but we want to force copying from the
04104           * filesystem (since only the FS contains the prepend). */
04105          copy_plain_file(frompath, topath);
04106          STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL);
04107          vm_delete(topath);
04108 #ifndef ODBC_STORAGE
04109       }
04110 #endif
04111    } else {
04112       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
04113       res = -1;
04114    }
04115    ast_unlock_path(todir);
04116    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04117    
04118    return res;
04119 }

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

Definition at line 3099 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message().

03100 {
03101    char frompath2[PATH_MAX], topath2[PATH_MAX];
03102    ast_filecopy(frompath, topath, NULL);
03103    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
03104    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
03105    copy(frompath2, topath2);
03106 }

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

Definition at line 2932 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

02933 {
02934    /* Find all .txt files - even if they are not in sequence from 0000 */
02935 
02936    int vmcount = 0;
02937    DIR *vmdir = NULL;
02938    struct dirent *vment = NULL;
02939 
02940    if (vm_lock_path(dir))
02941       return ERROR_LOCK_PATH;
02942 
02943    if ((vmdir = opendir(dir))) {
02944       while ((vment = readdir(vmdir))) {
02945          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02946             vmcount++;
02947       }
02948       closedir(vmdir);
02949    }
02950    ast_unlock_path(dir);
02951    
02952    return vmcount;
02953 }

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

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

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

01030 {
01031    mode_t   mode = VOICEMAIL_DIR_MODE;
01032 
01033    if (!ast_strlen_zero(context)) {
01034       make_dir(dest, len, context, "", "");
01035       if (mkdir(dest, mode) && errno != EEXIST) {
01036          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
01037          return -1;
01038       }
01039    }
01040    if (!ast_strlen_zero(ext)) {
01041       make_dir(dest, len, context, ext, "");
01042       if (mkdir(dest, mode) && errno != EEXIST) {
01043          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
01044          return -1;
01045       }
01046    }
01047    if (!ast_strlen_zero(folder)) {
01048       make_dir(dest, len, context, ext, folder);
01049       if (mkdir(dest, mode) && errno != EEXIST) {
01050          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
01051          return -1;
01052       }
01053    }
01054    return 0;
01055 }

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

Definition at line 9271 of file app_voicemail.c.

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

Referenced by advanced_options(), and vm_execmain().

09272 {
09273    int cmd = 0;
09274    char destination[80] = "";
09275    int retries = 0;
09276 
09277    if (!num) {
09278       if (option_verbose > 2)
09279          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
09280       while (retries < 3 && cmd != 't') {
09281          destination[1] = '\0';
09282          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
09283          if (!cmd)
09284             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
09285          if (!cmd)
09286             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
09287          if (!cmd) {
09288             cmd = ast_waitfordigit(chan, 6000);
09289             if (cmd)
09290                destination[0] = cmd;
09291          }
09292          if (!cmd) {
09293             retries++;
09294          } else {
09295 
09296             if (cmd < 0)
09297                return 0;
09298             if (cmd == '*') {
09299                if (option_verbose > 2)
09300                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
09301                return 0;
09302             }
09303             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
09304                retries++;
09305             else
09306                cmd = 't';
09307          }
09308       }
09309       if (retries >= 3) {
09310          return 0;
09311       }
09312       
09313    } else {
09314       if (option_verbose > 2)
09315          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
09316       ast_copy_string(destination, num, sizeof(destination));
09317    }
09318 
09319    if (!ast_strlen_zero(destination)) {
09320       if (destination[strlen(destination) -1 ] == '*')
09321          return 0; 
09322       if (option_verbose > 2)
09323          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
09324       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
09325       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
09326       chan->priority = 0;
09327       return 9;
09328    }
09329    return 0;
09330 }

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

Referenced by make_email_file().

03372 {
03373    char tmp[80];
03374    int first_section = 1;
03375    size_t endlen = 0, tmplen = 0;
03376    *end = '\0';
03377 
03378    tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03379    for (; *start; start++) {
03380       int need_encoding = 0;
03381       if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
03382          need_encoding = 1;
03383       }
03384       if ((first_section && need_encoding && preamble + tmplen > 70) ||
03385          (first_section && !need_encoding && preamble + tmplen > 72) ||
03386          (!first_section && need_encoding && tmplen > 70) ||
03387          (!first_section && !need_encoding && tmplen > 72)) {
03388          /* Start new line */
03389          endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp);
03390          tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03391          first_section = 0;
03392       }
03393       if (need_encoding && *start == ' ') {
03394          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
03395       } else if (need_encoding) {
03396          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start);
03397       } else {
03398          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start);
03399       }
03400    }
03401    snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
03402    return end;
03403 }

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

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

08336 {
08337    struct ast_vm_user *vmu;
08338    AST_LIST_TRAVERSE(&users, vmu, list) {
08339       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
08340          if (strcasecmp(vmu->context, context)) {
08341             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
08342                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
08343                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
08344                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
08345          }
08346          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
08347          return NULL;
08348       }
08349       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
08350          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
08351          return NULL;
08352       }
08353    }
08354    
08355    if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
08356       ast_copy_string(vmu->context, context, sizeof(vmu->context));
08357       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
08358       AST_LIST_INSERT_TAIL(&users, vmu, list);
08359    }
08360    return vmu;
08361 }

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

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

00857 {
00858    /* This function could be made to generate one from a database, too */
00859    struct ast_vm_user *vmu=NULL, *cur;
00860    AST_LIST_LOCK(&users);
00861 
00862    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00863       context = "default";
00864 
00865    AST_LIST_TRAVERSE(&users, cur, list) {
00866 #ifdef IMAP_STORAGE
00867       if (cur->imapversion != imapversion) {
00868          continue;
00869       }
00870 #endif
00871       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00872          break;
00873       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00874          break;
00875    }
00876    if (cur) {
00877       /* Make a copy, so that on a reload, we have no race */
00878       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00879          memcpy(vmu, cur, sizeof(*vmu));
00880          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00881          AST_LIST_NEXT(vmu, list) = NULL;
00882       }
00883    } else
00884       vmu = find_user_realtime(ivm, context, mailbox);
00885    AST_LIST_UNLOCK(&users);
00886    return vmu;
00887 }

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

Definition at line 827 of file app_voicemail.c.

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

Referenced by find_user().

00828 {
00829    struct ast_variable *var;
00830    struct ast_vm_user *retval;
00831 
00832    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00833       if (!ivm)
00834          ast_set_flag(retval, VM_ALLOCED);   
00835       else
00836          memset(retval, 0, sizeof(*retval));
00837       if (mailbox) 
00838          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00839       populate_defaults(retval);
00840       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00841          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00842       else
00843          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00844       if (var) {
00845          apply_options_full(retval, var);
00846          ast_variables_destroy(var);
00847       } else { 
00848          if (!ivm) 
00849             free(retval);
00850          retval = NULL;
00851       }  
00852    } 
00853    return retval;
00854 }

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

Definition at line 5459 of file app_voicemail.c.

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

Referenced by vm_execmain().

05460 {
05461 #ifdef IMAP_STORAGE
05462    int todircount=0;
05463    struct vm_state *dstvms;
05464 #else
05465    char textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX];
05466 #endif
05467    char username[70]="";
05468    int res = 0, cmd = 0;
05469    struct ast_vm_user *receiver = NULL, *vmtmp;
05470    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
05471    char *stringp;
05472    const char *s;
05473    int saved_messages = 0;
05474    int valid_extensions = 0;
05475    char *dir;
05476    int curmsg;
05477    int prompt_played = 0;
05478 
05479    if (vms == NULL) return -1;
05480    dir = vms->curdir;
05481    curmsg = vms->curmsg;
05482    
05483    while (!res && !valid_extensions) {
05484       int use_directory = 0;
05485       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
05486          int done = 0;
05487          int retries = 0;
05488          cmd=0;
05489          while ((cmd >= 0) && !done ){
05490             if (cmd)
05491                retries = 0;
05492             switch (cmd) {
05493             case '1': 
05494                use_directory = 0;
05495                done = 1;
05496                break;
05497             case '2': 
05498                use_directory = 1;
05499                done=1;
05500                break;
05501             case '*': 
05502                cmd = 't';
05503                done = 1;
05504                break;
05505             default: 
05506                /* Press 1 to enter an extension press 2 to use the directory */
05507                cmd = ast_play_and_wait(chan,"vm-forward");
05508                if (!cmd)
05509                   cmd = ast_waitfordigit(chan,3000);
05510                if (!cmd)
05511                   retries++;
05512                if (retries > 3)
05513                {
05514                   cmd = 't';
05515                   done = 1;
05516                }
05517                
05518             }
05519          }
05520          if (cmd < 0 || cmd == 't')
05521             break;
05522       }
05523       
05524       if (use_directory) {
05525          /* use app_directory */
05526          
05527          char old_context[sizeof(chan->context)];
05528          char old_exten[sizeof(chan->exten)];
05529          int old_priority;
05530          struct ast_app* app;
05531 
05532          
05533          app = pbx_findapp("Directory");
05534          if (app) {
05535             char vmcontext[256];
05536             /* make backup copies */
05537             memcpy(old_context, chan->context, sizeof(chan->context));
05538             memcpy(old_exten, chan->exten, sizeof(chan->exten));
05539             old_priority = chan->priority;
05540             
05541             /* call the the Directory, changes the channel */
05542             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
05543             res = pbx_exec(chan, app, vmcontext);
05544             
05545             ast_copy_string(username, chan->exten, sizeof(username));
05546             
05547             /* restore the old context, exten, and priority */
05548             memcpy(chan->context, old_context, sizeof(chan->context));
05549             memcpy(chan->exten, old_exten, sizeof(chan->exten));
05550             chan->priority = old_priority;
05551             
05552          } else {
05553             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
05554             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
05555          }
05556       } else {
05557          /* Ask for an extension */
05558          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
05559          prompt_played++;
05560          if (res || prompt_played > 4)
05561             break;
05562          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
05563             break;
05564       }
05565       
05566       /* start all over if no username */
05567       if (ast_strlen_zero(username))
05568          continue;
05569       stringp = username;
05570       s = strsep(&stringp, "*");
05571       /* start optimistic */
05572       valid_extensions = 1;
05573       while (s) {
05574          /* Don't forward to ourselves but allow leaving a message for ourselves (is_new_message == 1).  find_user is going to malloc since we have a NULL as first argument */
05575          if ((is_new_message == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
05576             int oldmsgs;
05577             int newmsgs;
05578             int capacity;
05579             if (inboxcount(s, &newmsgs, &oldmsgs)) {
05580                ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s);
05581                /* Shouldn't happen, but allow trying another extension if it does */
05582                res = ast_play_and_wait(chan, "pbx-invalid");
05583                valid_extensions = 0;
05584                break;
05585             }
05586             capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1);
05587             if ((newmsgs + oldmsgs) >= capacity) {
05588                ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity);
05589                res = ast_play_and_wait(chan, "vm-mailboxfull");
05590                valid_extensions = 0;
05591                while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
05592                   inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
05593                   free_user(vmtmp);
05594                }
05595                inprocess_count(receiver->mailbox, receiver->context, -1);
05596                break;
05597             }
05598             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
05599          } else {
05600             ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
05601             /* "I am sorry, that's not a valid extension.  Please try again." */
05602             res = ast_play_and_wait(chan, "pbx-invalid");
05603             valid_extensions = 0;
05604             break;
05605          }
05606          s = strsep(&stringp, "*");
05607       }
05608       /* break from the loop of reading the extensions */
05609       if (valid_extensions)
05610          break;
05611    }
05612    /* check if we're clear to proceed */
05613    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
05614       return res;
05615    if (is_new_message == 1) {
05616       struct leave_vm_options leave_options;
05617       char mailbox[AST_MAX_EXTENSION * 2 + 2];
05618       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
05619       if (context)
05620          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
05621       else
05622          ast_copy_string(mailbox, username, sizeof(mailbox));
05623 
05624       /* Send VoiceMail */
05625       memset(&leave_options, 0, sizeof(leave_options));
05626       leave_options.record_gain = record_gain;
05627       cmd = leave_voicemail(chan, mailbox, &leave_options);
05628    } else {
05629       /* Forward VoiceMail */
05630       long duration = 0;
05631       struct vm_state vmstmp;
05632 #ifndef IMAP_STORAGE
05633       char msgfile[PATH_MAX];
05634 #endif
05635       int copy_msg_result = 0;
05636 
05637       memcpy(&vmstmp, vms, sizeof(vmstmp));
05638 
05639       RETRIEVE(dir, curmsg, sender);
05640 
05641       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05642       if (!cmd) {
05643          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05644 #ifdef IMAP_STORAGE
05645             char *myserveremail;
05646             int attach_user_voicemail;
05647             /* get destination mailbox */
05648             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
05649             if (!dstvms) {
05650                dstvms = create_vm_state_from_user(vmtmp);
05651             }
05652             if (dstvms) {
05653                init_mailstream(dstvms, 0);
05654                if (!dstvms->mailstream) {
05655                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
05656                } else {
05657                   copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05658                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
05659                }
05660             } else {
05661                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
05662             }
05663             myserveremail = serveremail;
05664             if (!ast_strlen_zero(vmtmp->serveremail))
05665                myserveremail = vmtmp->serveremail;
05666             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05667             /* NULL category for IMAP storage */
05668             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);
05669 #else
05670             copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir);
05671 #endif
05672             saved_messages++;
05673             inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
05674             AST_LIST_REMOVE_CURRENT(&extensions, list);
05675             free_user(vmtmp);
05676             if (res)
05677                break;
05678          }
05679          AST_LIST_TRAVERSE_SAFE_END;
05680          if (saved_messages > 0 && !copy_msg_result) {
05681             /* give confirmation that the message was saved */
05682             /* commented out since we can't forward batches yet
05683             if (saved_messages == 1)
05684                res = ast_play_and_wait(chan, "vm-message");
05685             else
05686                res = ast_play_and_wait(chan, "vm-messages");
05687             if (!res)
05688                res = ast_play_and_wait(chan, "vm-saved"); */
05689             res = ast_play_and_wait(chan, "vm-msgsaved");
05690          }
05691 #ifndef IMAP_STORAGE
05692          else {
05693             /* with IMAP, mailbox full warning played by imap_check_limits */
05694             res = ast_play_and_wait(chan, "vm-mailboxfull");
05695          }
05696          /* Restore original message without prepended message if backup exists */
05697          make_file(msgfile, sizeof(msgfile), dir, curmsg);
05698          strcpy(textfile, msgfile);
05699          strcpy(backup, msgfile);
05700          strcpy(backup_textfile, msgfile);
05701          strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
05702          strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
05703          strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
05704          if (ast_fileexists(backup, NULL, NULL) > 0) {
05705             ast_filerename(backup, msgfile, NULL);
05706             rename(backup_textfile, textfile);
05707          }
05708 #endif
05709       }
05710       DISPOSE(dir, curmsg);
05711 #ifndef IMAP_STORAGE
05712       if (cmd) { /* assuming hangup, cleanup backup file */
05713          make_file(msgfile, sizeof(msgfile), dir, curmsg);
05714          strcpy(textfile, msgfile);
05715          strcpy(backup_textfile, msgfile);
05716          strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
05717          strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
05718          rename(backup_textfile, textfile);
05719       }
05720 #endif
05721    }
05722 
05723    /* If anything failed above, we still have this list to free */
05724    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
05725       inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
05726       free_user(vmtmp);
05727    }
05728    return res ? res : cmd;
05729 }

static void free_user ( struct ast_vm_user vmu  )  [static]

Definition at line 1074 of file app_voicemail.c.

References ast_test_flag, free, and VM_ALLOCED.

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

01075 {
01076    if (ast_test_flag(vmu, VM_ALLOCED))
01077       free(vmu);
01078 }

static void free_vm_users ( void   )  [static]

Definition at line 8596 of file app_voicemail.c.

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

Referenced by load_config().

08597 {
08598    struct ast_vm_user *cur;
08599    struct vm_zone *zcur;
08600 
08601    AST_LIST_LOCK(&users);
08602    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
08603       ast_set_flag(cur, VM_ALLOCED);
08604       free_user(cur);
08605    }
08606    AST_LIST_UNLOCK(&users);
08607 
08608    AST_LIST_LOCK(&zones);
08609    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
08610       free_zone(zcur);
08611    }
08612    AST_LIST_UNLOCK(&zones);
08613 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3911 of file app_voicemail.c.

References free.

03912 {
03913    free(z);
03914 }

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

Definition at line 3844 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03845 {
03846    struct tm tm;
03847    time_t t;
03848 
03849    time(&t);
03850 
03851    ast_localtime(&t, &tm, NULL);
03852 
03853    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03854 }

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

Definition at line 5235 of file app_voicemail.c.

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

Referenced by get_folder2().

05236 {
05237    int x;
05238    int d;
05239    char fn[PATH_MAX];
05240    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
05241    if (d)
05242       return d;
05243    for (x = start; x< 5; x++) {  /* For all folders */
05244       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
05245          return d;
05246       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
05247       if (d)
05248          return d;
05249       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
05250       d = vm_play_folder_name(chan, fn);
05251       if (d)
05252          return d;
05253       d = ast_waitfordigit(chan, 500);
05254       if (d)
05255          return d;
05256    }
05257    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
05258    if (d)
05259       return d;
05260    d = ast_waitfordigit(chan, 4000);
05261    return d;
05262 }

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

Definition at line 5264 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

05265 {
05266    int res = 0;
05267    int loops = 0;
05268    res = ast_play_and_wait(chan, fn);  /* Folder name */
05269    while (((res < '0') || (res > '9')) &&
05270          (res != '#') && (res >= 0) &&
05271          loops < 4) {
05272       res = get_folder(chan, 0);
05273       loops++;
05274    }
05275    if (loops == 4) { /* give up */
05276       return '#';
05277    }
05278    return res;
05279 }

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

Definition at line 8482 of file app_voicemail.c.

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

08483 {
08484    struct ast_vm_user *vmu;
08485    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
08486 
08487    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
08488    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
08489 
08490    AST_LIST_LOCK(&users);
08491    if (!AST_LIST_EMPTY(&users)) {
08492       if (argc == 3)
08493          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08494       else {
08495          int count = 0;
08496          AST_LIST_TRAVERSE(&users, vmu, list) {
08497             if (!strcmp(argv[4],vmu->context))
08498                count++;
08499          }
08500          if (count) {
08501             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08502          } else {
08503             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
08504             AST_LIST_UNLOCK(&users);
08505             return RESULT_FAILURE;
08506          }
08507       }
08508       AST_LIST_TRAVERSE(&users, vmu, list) {
08509          int newmsgs = 0, oldmsgs = 0;
08510          char count[12], tmp[256] = "";
08511 
08512          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
08513             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08514             inboxcount(tmp, &newmsgs, &oldmsgs);
08515             snprintf(count,sizeof(count),"%d",newmsgs);
08516             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08517          }
08518       }
08519    } else {
08520       ast_cli(fd, "There are no voicemail users currently defined\n");
08521       AST_LIST_UNLOCK(&users);
08522       return RESULT_FAILURE;
08523    }
08524    AST_LIST_UNLOCK(&users);
08525    return RESULT_SUCCESS;
08526 }

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

Definition at line 8528 of file app_voicemail.c.

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

08529 {
08530    struct vm_zone *zone;
08531    char *output_format = "%-15s %-20s %-45s\n";
08532    int res = RESULT_SUCCESS;
08533 
08534    if (argc != 3)
08535       return RESULT_SHOWUSAGE;
08536 
08537    AST_LIST_LOCK(&zones);
08538    if (!AST_LIST_EMPTY(&zones)) {
08539       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
08540       AST_LIST_TRAVERSE(&zones, zone, list) {
08541          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
08542       }
08543    } else {
08544       ast_cli(fd, "There are no voicemail zones currently defined\n");
08545       res = RESULT_FAILURE;
08546    }
08547    AST_LIST_UNLOCK(&zones);
08548 
08549    return res;
08550 }

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

Definition at line 4159 of file app_voicemail.c.

References __has_voicemail(), and ast_copy_string().

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

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

Definition at line 4175 of file app_voicemail.c.

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

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

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

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

Definition at line 3126 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

03127 {
03128    int l;
03129 
03130    if (bio->ateof)
03131       return 0;
03132 
03133    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
03134       if (ferror(fi))
03135          return -1;
03136 
03137       bio->ateof = 1;
03138       return 0;
03139    }
03140 
03141    bio->iolen= l;
03142    bio->iocp= 0;
03143 
03144    return 1;
03145 }

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

Definition at line 3147 of file app_voicemail.c.

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

Referenced by base_encode().

03148 {
03149    if (bio->iocp>=bio->iolen) {
03150       if (!inbuf(bio, fi))
03151          return EOF;
03152    }
03153 
03154    return bio->iobuf[bio->iocp++];
03155 }

static int inprocess_cmp_fn ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 434 of file app_voicemail.c.

References inprocess::context, and inprocess::mailbox.

Referenced by load_module().

00435 {
00436    struct inprocess *i = obj, *j = arg;
00437    if (strcmp(i->mailbox, j->mailbox)) {
00438       return 0;
00439    }
00440    return !strcmp(i->context, j->context) ? CMP_MATCH : 0;
00441 }

static int inprocess_count ( const char *  context,
const char *  mailbox,
int  delta 
) [static]

Definition at line 443 of file app_voicemail.c.

References ao2_alloc(), ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_atomic_fetchadd_int(), ast_log(), inprocess::count, inprocess_container, and LOG_WARNING.

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

00444 {
00445    struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2);
00446    arg->context = arg->mailbox + strlen(mailbox) + 1;
00447    strcpy(arg->mailbox, mailbox); /* SAFE */
00448    strcpy(arg->context, context); /* SAFE */
00449    ao2_lock(inprocess_container);
00450    if ((i = ao2_find(inprocess_container, arg, 0))) {
00451       int ret = ast_atomic_fetchadd_int(&i->count, delta);
00452       ao2_unlock(inprocess_container);
00453       ao2_ref(i, -1);
00454       return ret;
00455    }
00456    if (delta < 0) {
00457       ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n");
00458    }
00459    if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) {
00460       ao2_unlock(inprocess_container);
00461       return 0;
00462    }
00463    i->context = i->mailbox + strlen(mailbox) + 1;
00464    strcpy(i->mailbox, mailbox); /* SAFE */
00465    strcpy(i->context, context); /* SAFE */
00466    i->count = delta;
00467    ao2_link(inprocess_container, i);
00468    ao2_unlock(inprocess_container);
00469    ao2_ref(i, -1);
00470    return 0;
00471 }

static int inprocess_hash_fn ( const void *  obj,
const int  flags 
) [static]

Definition at line 428 of file app_voicemail.c.

References inprocess::mailbox.

Referenced by load_module().

00429 {
00430    const struct inprocess *i = obj;
00431    return atoi(i->mailbox);
00432 }

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

Definition at line 3882 of file app_voicemail.c.

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

Referenced by leave_voicemail().

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

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

Determines the highest message number in use for a given user and mailbox folder.

Parameters:
vmu 
dir the folder the mailbox folder to look for messages. Used to construct the SQL where clause.
This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). Typical use to set the msgnum would be to take the value returned from this method and add one to it.

Note:
Should always be called with a lock already set on dir.
Returns:
the value of zero or greater to indicate the last message index in use, -1 to indicate none.

Definition at line 2978 of file app_voicemail.c.

References ast_log(), LOG_DEBUG, map, ast_vm_user::maxmsg, MAXMSGLIMIT, and option_debug.

Referenced by close_mailbox(), leave_voicemail(), and open_mailbox().

02979 {
02980    int x;
02981    unsigned char map[MAXMSGLIMIT] = "";
02982    DIR *msgdir;
02983    struct dirent *msgdirent;
02984    int msgdirint;
02985    char extension[4];
02986    int stopcount = 0;
02987 
02988    /* Reading the entire directory into a file map scales better than
02989     * doing a stat repeatedly on a predicted sequence.  I suspect this
02990     * is partially due to stat(2) internally doing a readdir(2) itself to
02991     * find each file. */
02992    if (!(msgdir = opendir(dir))) {
02993       return -1;
02994    }
02995 
02996    while ((msgdirent = readdir(msgdir))) {
02997       if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) {
02998          map[msgdirint] = 1;
02999          stopcount++;
03000          if (option_debug > 3) {
03001             ast_log(LOG_DEBUG, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount);
03002          }
03003       }
03004    }
03005    closedir(msgdir);
03006 
03007    for (x = 0; x < vmu->maxmsg; x++) {
03008       if (map[x] == 1) {
03009          stopcount--;
03010       } else if (map[x] == 0 && !stopcount) {
03011          break;
03012       }
03013    }
03014 
03015    return x - 1;
03016 }

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

Definition at line 4270 of file app_voicemail.c.

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

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

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

static int load_config ( void   )  [static]

Definition at line 8615 of file app_voicemail.c.

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

08616 {
08617    struct ast_vm_user *cur;
08618    struct ast_config *cfg, *ucfg;
08619    char *cat;
08620    struct ast_variable *var;
08621    const char *notifystr = NULL;
08622    const char *smdistr = NULL;
08623    const char *astattach;
08624    const char *astsearch;
08625    const char *astsaycid;
08626    const char *send_voicemail;
08627 #ifdef IMAP_STORAGE
08628    const char *imap_server;
08629    const char *imap_port;
08630    const char *imap_flags;
08631    const char *imap_folder;
08632    const char *auth_user;
08633    const char *auth_password;
08634    const char *expunge_on_hangup;
08635    const char *imap_timeout;
08636 #endif
08637    const char *astcallop;
08638    const char *astreview;
08639    const char *asttempgreetwarn;
08640    const char *astskipcmd;
08641    const char *asthearenv;
08642    const char *astsaydurationinfo;
08643    const char *astsaydurationminfo;
08644    const char *silencestr;
08645    const char *maxmsgstr;
08646    const char *astdirfwd;
08647    const char *thresholdstr;
08648    const char *fmt;
08649    const char *astemail;
08650    const char *ucontext;
08651    const char *astmailcmd = SENDMAIL;
08652    const char *astpreprocesscmd;
08653    const char *astpreprocessfmt;
08654    const char *astforcename;
08655    const char *astforcegreet;
08656    const char *s;
08657    char *q,*stringp, *tmp;
08658    const char *dialoutcxt = NULL;
08659    const char *callbackcxt = NULL;  
08660    const char *exitcxt = NULL;   
08661    const char *extpc;
08662    const char *emaildateformatstr;
08663    const char *volgainstr;
08664    int x;
08665    int tmpadsi[4];
08666 
08667    cfg = ast_config_load(VOICEMAIL_CONFIG);
08668 
08669    free_vm_users();
08670 
08671    AST_LIST_LOCK(&users);
08672 
08673    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
08674 
08675    if (cfg) {
08676       /* General settings */
08677 
08678       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
08679          ucontext = "default";
08680       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
08681       /* Attach voice message to mail message ? */
08682       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
08683          astattach = "yes";
08684       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
08685 
08686       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
08687          astsearch = "no";
08688       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
08689 
08690       volgain = 0.0;
08691       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
08692          sscanf(volgainstr, "%30lf", &volgain);
08693 
08694 #ifdef ODBC_STORAGE
08695       strcpy(odbc_database, "asterisk");
08696       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
08697          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
08698       }
08699       strcpy(odbc_table, "voicemessages");
08700       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
08701          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
08702       }
08703 #endif      
08704       /* Mail command */
08705       strcpy(mailcmd, SENDMAIL);
08706       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
08707          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
08708 
08709       if ((astpreprocesscmd = ast_variable_retrieve(cfg, "general", "preprocesscmd")))
08710          ast_copy_string(preprocesscmd, astpreprocesscmd, sizeof(preprocesscmd)); /* User setting */
08711 
08712       if ((astpreprocessfmt = ast_variable_retrieve(cfg, "general", "preprocessfmt")))
08713          ast_copy_string(preprocessfmt, astpreprocessfmt, sizeof(preprocessfmt)); /* User setting */
08714 
08715       maxsilence = 0;
08716       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
08717          maxsilence = atoi(silencestr);
08718          if (maxsilence > 0)
08719             maxsilence *= 1000;
08720       }
08721       
08722       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
08723          maxmsg = MAXMSG;
08724       } else {
08725          maxmsg = atoi(maxmsgstr);
08726          if (maxmsg <= 0) {
08727             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
08728             maxmsg = MAXMSG;
08729          } else if (maxmsg > MAXMSGLIMIT) {
08730             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
08731             maxmsg = MAXMSGLIMIT;
08732          }
08733       }
08734 
08735       /* Load date format config for voicemail mail */
08736       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
08737          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
08738       }
08739 
08740       /* External password changing command */
08741       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
08742          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
08743       }
08744 #ifdef IMAP_STORAGE
08745       /* IMAP server address */
08746       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
08747          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
08748       } else {
08749          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
08750       }
08751       /* IMAP server port */
08752       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
08753          ast_copy_string(imapport, imap_port, sizeof(imapport));
08754       } else {
08755          ast_copy_string(imapport,"143", sizeof(imapport));
08756       }
08757       /* IMAP server flags */
08758       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
08759          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
08760       }
08761       /* IMAP server master username */
08762       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
08763          ast_copy_string(authuser, auth_user, sizeof(authuser));
08764       }
08765       /* IMAP server master password */
08766       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
08767          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
08768       }
08769       /* Expunge on exit */
08770       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
08771          if (ast_false(expunge_on_hangup))
08772             expungeonhangup = 0;
08773          else
08774             expungeonhangup = 1;
08775       } else {
08776          expungeonhangup = 1;
08777       }
08778       /* IMAP voicemail folder */
08779       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
08780          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
08781       } else {
08782          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
08783       }
08784 
08785       /* There is some very unorthodox casting done here. This is due
08786        * to the way c-client handles the argument passed in. It expects a 
08787        * void pointer and casts the pointer directly to a long without
08788        * first dereferencing it. */
08789 
08790       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
08791          mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(imap_timeout)));
08792       } else {
08793          mail_parameters(NIL, SET_READTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08794       }
08795 
08796       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
08797          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(imap_timeout)));
08798       } else {
08799          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08800       }
08801 
08802       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
08803          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(imap_timeout)));
08804       } else {
08805          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08806       }
08807 
08808       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
08809          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(imap_timeout)));
08810       } else {
08811          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08812       }
08813 
08814       /* Increment configuration version */
08815       imapversion++;
08816 #endif
08817       /* External voicemail notify application */
08818       
08819       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
08820          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
08821          if (option_debug > 2)
08822             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
08823          if (!strcasecmp(externnotify, "smdi")) {
08824             if (option_debug)
08825                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
08826             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
08827                smdi_iface = ast_smdi_interface_find(smdistr);
08828             } else {
08829                if (option_debug)
08830                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
08831                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
08832             }
08833 
08834             if (!smdi_iface) {
08835                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
08836                externnotify[0] = '\0';
08837             }
08838          }
08839       } else {
08840          externnotify[0] = '\0';
08841       }
08842 
08843       /* Silence treshold */
08844       silencethreshold = 256;
08845       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
08846          silencethreshold = atoi(thresholdstr);
08847       
08848       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
08849          astemail = ASTERISK_USERNAME;
08850       ast_copy_string(serveremail, astemail, sizeof(serveremail));
08851       
08852       vmmaxmessage = 0;
08853       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
08854          if (sscanf(s, "%30d", &x) == 1) {
08855             vmmaxmessage = x;
08856          } else {
08857             ast_log(LOG_WARNING, "Invalid max message time length\n");
08858          }
08859       }
08860 
08861       vmminmessage = 0;
08862       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
08863          if (sscanf(s, "%30d", &x) == 1) {
08864             vmminmessage = x;
08865             if (maxsilence / 1000 >= vmminmessage)
08866                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
08867          } else {
08868             ast_log(LOG_WARNING, "Invalid min message time length\n");
08869          }
08870       }
08871       fmt = ast_variable_retrieve(cfg, "general", "format");
08872       if (!fmt) {
08873          fmt = "wav";   
08874       } else {
08875          tmp = ast_strdupa(fmt);
08876          fmt = ast_format_str_reduce(tmp);
08877          if (!fmt) {
08878             ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n");
08879             fmt = "wav";
08880          }
08881       }
08882 
08883       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
08884 
08885       skipms = 3000;
08886       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
08887          if (sscanf(s, "%30d", &x) == 1) {
08888             maxgreet = x;
08889          } else {
08890             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
08891          }
08892       }
08893 
08894       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
08895          if (sscanf(s, "%30d", &x) == 1) {
08896             skipms = x;
08897          } else {
08898             ast_log(LOG_WARNING, "Invalid skipms value\n");
08899          }
08900       }
08901 
08902       maxlogins = 3;
08903       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
08904          if (sscanf(s, "%30d", &x) == 1) {
08905             maxlogins = x;
08906          } else {
08907             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
08908          }
08909       }
08910 
08911       /* Force new user to record name ? */
08912       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
08913          astforcename = "no";
08914       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
08915 
08916       /* Force new user to record greetings ? */
08917       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
08918          astforcegreet = "no";
08919       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
08920 
08921       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
08922          if (option_debug > 2)
08923             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
08924          stringp = ast_strdupa(s);
08925          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
08926             if (!ast_strlen_zero(stringp)) {
08927                q = strsep(&stringp,",");
08928                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
08929                   q++;
08930                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
08931                if (option_debug > 2)
08932                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
08933             } else {
08934                cidinternalcontexts[x][0] = '\0';
08935             }
08936          }
08937       }
08938       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
08939          if (option_debug)
08940             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
08941          astreview = "no";
08942       }
08943       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
08944 
08945       /*Temperary greeting reminder */
08946       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
08947          if (option_debug)
08948             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
08949          asttempgreetwarn = "no";
08950       } else {
08951          if (option_debug)
08952             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
08953       }
08954       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
08955 
08956       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
08957          if (option_debug)
08958             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
08959          astcallop = "no";
08960       }
08961       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
08962 
08963       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
08964          if (option_debug)
08965             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
08966          astsaycid = "no";
08967       } 
08968       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
08969 
08970       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
08971          if (option_debug)
08972             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
08973          send_voicemail = "no";
08974       }
08975       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
08976    
08977       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
08978          if (option_debug)
08979             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
08980          asthearenv = "yes";
08981       }
08982       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
08983 
08984       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
08985          if (option_debug)
08986             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
08987          astsaydurationinfo = "yes";
08988       }
08989       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
08990 
08991       saydurationminfo = 2;
08992       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
08993          if (sscanf(astsaydurationminfo, "%30d", &x) == 1) {
08994             saydurationminfo = x;
08995          } else {
08996             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
08997          }
08998       }
08999 
09000       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
09001          if (option_debug)
09002             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
09003          astskipcmd = "no";
09004       }
09005       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
09006 
09007       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
09008          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
09009          if (option_debug)
09010             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
09011       } else {
09012          dialcontext[0] = '\0';  
09013       }
09014       
09015       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
09016          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
09017          if (option_debug)
09018             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
09019       } else {
09020          callcontext[0] = '\0';
09021       }
09022 
09023       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
09024          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
09025          if (option_debug)
09026             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
09027       } else {
09028          exitcontext[0] = '\0';
09029       }
09030 
09031       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
09032          astdirfwd = "no";
09033       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
09034       if ((ucfg = ast_config_load("users.conf"))) {   
09035          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
09036             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
09037                continue;
09038             if ((cur = find_or_create(userscontext, cat))) {
09039                populate_defaults(cur);
09040                apply_options_full(cur, ast_variable_browse(ucfg, cat));
09041                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
09042             }
09043          }
09044          ast_config_destroy(ucfg);
09045       }
09046       cat = ast_category_browse(cfg, NULL);
09047       while (cat) {
09048          if (strcasecmp(cat, "general")) {
09049             var = ast_variable_browse(cfg, cat);
09050             if (strcasecmp(cat, "zonemessages")) {
09051                /* Process mailboxes in this context */
09052                while (var) {
09053                   append_mailbox(cat, var->name, var->value);
09054                   var = var->next;
09055                }
09056             } else {
09057                /* Timezones in this context */
09058                while (var) {
09059                   struct vm_zone *z;
09060                   if ((z = ast_malloc(sizeof(*z)))) {
09061                      char *msg_format, *timezone;
09062                      msg_format = ast_strdupa(var->value);
09063                      timezone = strsep(&msg_format, "|");
09064                      if (msg_format) {
09065                         ast_copy_string(z->name, var->name, sizeof(z->name));
09066                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
09067                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
09068                         AST_LIST_LOCK(&zones);
09069                         AST_LIST_INSERT_HEAD(&zones, z, list);
09070                         AST_LIST_UNLOCK(&zones);
09071                      } else {
09072                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
09073                         free(z);
09074                      }
09075                   } else {
09076                      free(z);
09077                      AST_LIST_UNLOCK(&users);
09078                      ast_config_destroy(cfg);
09079                      return -1;
09080                   }
09081                   var = var->next;
09082                }
09083             }
09084          }
09085          cat = ast_category_browse(cfg, cat);
09086       }
09087       memset(fromstring,0,sizeof(fromstring));
09088       memset(pagerfromstring,0,sizeof(pagerfromstring));
09089       memset(emailtitle,0,sizeof(emailtitle));
09090       strcpy(charset, "ISO-8859-1");
09091       if (emailbody) {
09092          free(emailbody);
09093          emailbody = NULL;
09094       }
09095       if (emailsubject) {
09096          free(emailsubject);
09097          emailsubject = NULL;
09098       }
09099       if (pagerbody) {
09100          free(pagerbody);
09101          pagerbody = NULL;
09102       }
09103       if (pagersubject) {
09104          free(pagersubject);
09105          pagersubject = NULL;
09106       }
09107       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
09108          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
09109       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
09110          ast_copy_string(fromstring,s,sizeof(fromstring));
09111       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
09112          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
09113       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
09114          ast_copy_string(charset,s,sizeof(charset));
09115       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
09116          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
09117          for (x = 0; x < 4; x++) {
09118             memcpy(&adsifdn[x], &tmpadsi[x], 1);
09119          }
09120       }
09121       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
09122          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
09123          for (x = 0; x < 4; x++) {
09124             memcpy(&adsisec[x], &tmpadsi[x], 1);
09125          }
09126       }
09127       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
09128          if (atoi(s)) {
09129             adsiver = atoi(s);
09130          }
09131       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
09132          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
09133          ast_copy_string(emailtitle,s,sizeof(emailtitle));
09134       }
09135       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
09136          emailsubject = ast_strdup(s);
09137       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
09138          char *tmpread, *tmpwrite;
09139          emailbody = ast_strdup(s);
09140 
09141          /* substitute strings \t and \n into the appropriate characters */
09142          tmpread = tmpwrite = emailbody;
09143          while ((tmpwrite = strchr(tmpread,'\\'))) {
09144             switch (tmpwrite[1]) {
09145             case 'r':
09146                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
09147                *tmpwrite = '\r';
09148                break;
09149             case 'n':
09150                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
09151                *tmpwrite = '\n';
09152                break;
09153             case 't':
09154                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
09155                *tmpwrite = '\t';
09156                break;
09157             default:
09158                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
09159             }
09160             tmpread = tmpwrite + 1;
09161          }
09162       }
09163       if ((s = ast_variable_retrieve(cfg, "general", "tz"))) {
09164          ast_copy_string(zonetag, s, sizeof(zonetag));
09165       }
09166       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
09167          pagersubject = ast_strdup(s);
09168       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
09169          char *tmpread, *tmpwrite;
09170          pagerbody = ast_strdup(s);
09171 
09172          /* substitute strings \t and \n into the appropriate characters */
09173          tmpread = tmpwrite = pagerbody;
09174          while ((tmpwrite = strchr(tmpread, '\\'))) {
09175             switch (tmpwrite[1]) {
09176             case 'r':
09177                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
09178                *tmpwrite = '\r';
09179                break;
09180             case 'n':
09181                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
09182                *tmpwrite = '\n';
09183                break;
09184             case 't':
09185                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
09186                *tmpwrite = '\t';
09187                break;
09188             default:
09189                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
09190             }
09191             tmpread = tmpwrite + 1;
09192          }
09193       }
09194       AST_LIST_UNLOCK(&users);
09195       ast_config_destroy(cfg);
09196       return 0;
09197    } else {
09198       AST_LIST_UNLOCK(&users);
09199       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
09200       return 0;
09201    }
09202 }

static int load_module ( void   )  [static]

Definition at line 9226 of file app_voicemail.c.

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

09227 {
09228    int res;
09229    char *adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
09230    char *smdi_loaded = ast_module_helper("", "res_smdi", 0, 0, 0, 0);
09231    free(adsi_loaded);
09232    free(smdi_loaded);
09233 
09234    if (!adsi_loaded) {
09235       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
09236       return AST_MODULE_LOAD_DECLINE;
09237    }
09238 
09239    if (!smdi_loaded) {
09240       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_smdi.so\n");
09241       return AST_MODULE_LOAD_DECLINE;
09242    }
09243 
09244    if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) {
09245       return AST_MODULE_LOAD_DECLINE;
09246    }
09247 
09248    my_umask = umask(0);
09249    umask(my_umask);
09250    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
09251    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
09252    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
09253    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
09254    if (res)
09255       return(res);
09256 
09257    if ((res=load_config())) {
09258       return(res);
09259    }
09260 
09261    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
09262 
09263    /* compute the location of the voicemail spool directory */
09264    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
09265 
09266    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
09267 
09268    return res;
09269 }

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

Definition at line 995 of file app_voicemail.c.

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

00996 {
00997    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00998 }

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

Definition at line 3405 of file app_voicemail.c.

References ast_channel_alloc(), ast_channel_free(), ast_config_destroy(), ast_config_load(), ast_copy_string(), ast_localtime(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), base_encode(), check_mime(), ast_vm_user::context, create_dirpath(), ast_vm_user::email, encode_mime_str(), ENDL, ast_vm_user::fullname, globalflags, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), ast_channel::name, ast_vm_user::next, option_debug, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_vm_user::preprocesscmd, ast_vm_user::preprocessfmt, ast_channel::priority, quote(), strip_control_and_high(), VM_PBXSKIP, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by sendmail().

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

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

Definition at line 1000 of file app_voicemail.c.

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

01001 {
01002    return snprintf(dest, len, "%s/msg%04d", dir, num);
01003 }

static char* mbox ( int  id  )  [static]

Definition at line 1057 of file app_voicemail.c.

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

01058 {
01059    static char *msgs[] = {
01060       "INBOX",
01061       "Old",
01062       "Work",
01063       "Family",
01064       "Friends",
01065       "Cust1",
01066       "Cust2",
01067       "Cust3",
01068       "Cust4",
01069       "Cust5",
01070    };
01071    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
01072 }

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

Definition at line 4122 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

04123 {
04124    return __has_voicemail(context, mailbox, folder, 0);
04125 }

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

Definition at line 5395 of file app_voicemail.c.

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

Referenced by copy_message(), and leave_voicemail().

05396 {
05397    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
05398    int newmsgs = 0, oldmsgs = 0;
05399    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
05400 
05401 #ifndef IMAP_STORAGE
05402    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
05403 #else
05404    snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR);
05405 #endif
05406    make_file(fn, sizeof(fn), todir, msgnum);
05407    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
05408 
05409    if (!ast_strlen_zero(vmu->attachfmt)) {
05410       if (strstr(fmt, vmu->attachfmt)) {
05411          fmt = vmu->attachfmt;
05412       } else {
05413          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);
05414       }
05415    }
05416 
05417    /* Attach only the first format */
05418    fmt = ast_strdupa(fmt);
05419    stringp = fmt;
05420    strsep(&stringp, "|");
05421 
05422    if (!ast_strlen_zero(vmu->email)) {
05423       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
05424       char *myserveremail = serveremail;
05425       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
05426       if (!ast_strlen_zero(vmu->serveremail))
05427          myserveremail = vmu->serveremail;
05428       
05429       if (attach_user_voicemail)
05430          RETRIEVE(todir, msgnum, vmu);
05431 
05432       /*XXX possible imap issue, should category be NULL XXX*/
05433       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
05434 
05435       if (attach_user_voicemail)
05436          DISPOSE(todir, msgnum);
05437    }
05438 
05439    if (!ast_strlen_zero(vmu->pager)) {
05440       char *myserveremail = serveremail;
05441       if (!ast_strlen_zero(vmu->serveremail))
05442          myserveremail = vmu->serveremail;
05443       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category);
05444    }
05445 
05446    if (ast_test_flag(vmu, VM_DELETE)) {
05447       DELETE(todir, msgnum, fn, vmu);
05448    }
05449 
05450    /* Leave voicemail for someone */
05451    if (ast_app_has_voicemail(ext_context, NULL)) {
05452       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
05453    }
05454    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);
05455    run_externnotify(vmu->context, vmu->mailbox);
05456    return 0;
05457 }

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

Definition at line 3157 of file app_voicemail.c.

References BASELINELEN, ENDL, and baseio::linelength.

Referenced by base_encode().

03158 {
03159    if (bio->linelength >= BASELINELEN) {
03160       if (fputs(ENDL, so) == EOF) {
03161          return -1;
03162       }
03163 
03164       bio->linelength = 0;
03165    }
03166 
03167    if (putc(((unsigned char) c), so) == EOF) {
03168       return -1;
03169    }
03170 
03171    bio->linelength++;
03172 
03173    return 1;
03174 }

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

Definition at line 6084 of file app_voicemail.c.

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

Referenced by vm_execmain().

06085 {
06086    int count_msg, last_msg;
06087 
06088    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
06089    
06090    /* Rename the member vmbox HERE so that we don't try to return before
06091     * we know what's going on.
06092     */
06093    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
06094    
06095    /* Faster to make the directory than to check if it exists. */
06096    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
06097 
06098    /* traverses directory using readdir (or select query for ODBC) */
06099    count_msg = count_messages(vmu, vms->curdir);
06100    if (count_msg < 0)
06101       return count_msg;
06102    else
06103       vms->lastmsg = count_msg - 1;
06104 
06105    if (vm_allocate_dh(vms, vmu, count_msg)) {
06106       return -1;
06107    }
06108 
06109    /*
06110    The following test is needed in case sequencing gets messed up.
06111    There appears to be more than one way to mess up sequence, so
06112    we will not try to find all of the root causes--just fix it when
06113    detected.
06114    */
06115 
06116    /* for local storage, checks directory for messages up to maxmsg limit */
06117    last_msg = last_message_index(vmu, vms->curdir);
06118 
06119    if (last_msg < -1) {
06120       return last_msg;
06121    } else if (vms->lastmsg != last_msg) {
06122       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg);
06123       resequence_mailbox(vmu, vms->curdir, count_msg);
06124    }
06125 
06126    return 0;
06127 }

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

Definition at line 3856 of file app_voicemail.c.

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

Referenced by invent_message(), and leave_voicemail().

03857 {
03858    int res = -2;
03859 
03860 #ifdef ODBC_STORAGE
03861    int success = 
03862 #endif
03863    RETRIEVE(filename, -1, vmu);
03864    if (ast_fileexists(filename, NULL, NULL) > 0) {
03865       res = ast_streamfile(chan, filename, chan->language);
03866       if (res > -1) 
03867          res = ast_waitstream(chan, ecodes);
03868 #ifdef ODBC_STORAGE
03869       if (success == -1) {
03870          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03871          if (option_debug)
03872             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03873          store_file(filename, vmu->mailbox, vmu->context, -1);
03874       }
03875 #endif
03876    }
03877    DISPOSE(filename, -1);
03878 
03879    return res;
03880 }

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

Definition at line 5950 of file app_voicemail.c.

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

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

05951 {
05952    int res = 0;
05953    char filename[256], *cid;
05954    const char *origtime, *context, *category, *duration;
05955    struct ast_config *msg_cfg;
05956 
05957    vms->starting = 0; 
05958    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05959    adsi_message(chan, vms);
05960    
05961    if (!strncasecmp(chan->language, "he", 2)) {        /* HEBREW FORMAT */
05962       /*
05963        * The syntax in hebrew for counting the number of message is up side down
05964        * in comparison to english.
05965        */
05966       if (!vms->curmsg) {
05967          res = wait_file2(chan, vms, "vm-message");
05968          res = wait_file2(chan, vms, "vm-first");    /* "First" */
05969       } else if (vms->curmsg == vms->lastmsg) {
05970          res = wait_file2(chan, vms, "vm-message");
05971          res = wait_file2(chan, vms, "vm-last");     /* "last" */
05972       } else {
05973          res = wait_file2(chan, vms, "vm-message");  /* "message" */
05974          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05975             ast_log(LOG_DEBUG, "curmsg: %d\n", vms->curmsg);
05976             ast_log(LOG_DEBUG, "lagmsg: %d\n", vms->lastmsg);
05977             if (!res) {
05978                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
05979             }
05980          }
05981       }
05982 
05983    } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH FORMAT */
05984       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05985          int ten, one;
05986          char nextmsg[256];
05987          ten = (vms->curmsg + 1) / 10;
05988          one = (vms->curmsg + 1) % 10;
05989 
05990          if (vms->curmsg < 20) {
05991             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
05992             res = wait_file2(chan, vms, nextmsg);
05993          } else {
05994             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
05995             res = wait_file2(chan, vms, nextmsg);
05996             if (one > 0) {
05997                if (!res) {
05998                   snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
05999                   res = wait_file2(chan, vms, nextmsg);
06000                }
06001             }
06002          }
06003       }
06004       if (!res)
06005          res = wait_file2(chan, vms, "vm-message");         
06006 
06007    } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH FORMAT */
06008       if (!vms->curmsg)
06009          res = wait_file2(chan, vms, "vm-first");  /* "First" */
06010       else if (vms->curmsg == vms->lastmsg)
06011          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
06012       res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
06013       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
06014          if (!res)
06015             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
06016       }
06017       /* We know that the difference between English and Swedish
06018        * is very small, however, we differ the two for standartization
06019        * purposes, and possible changes to either of these in the 
06020        * future
06021        */
06022    } else {
06023       if (!vms->curmsg)                      /* Default syntax */
06024          res = wait_file2(chan, vms, "vm-first");  /* "First" */
06025       else if (vms->curmsg == vms->lastmsg)
06026          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
06027       res = wait_file2(chan, vms, "vm-message");
06028       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
06029          if (!res)
06030             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
06031       }
06032    }
06033 
06034    /* Retrieve info from VM attribute file */
06035    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
06036    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
06037    RETRIEVE(vms->curdir, vms->curmsg, vmu);
06038    msg_cfg = ast_config_load(filename);
06039    if (!msg_cfg) {
06040       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
06041       return 0;
06042    }
06043 
06044    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
06045       ast_log(LOG_WARNING, "No origtime?!\n");
06046       DISPOSE(vms->curdir, vms->curmsg);
06047       ast_config_destroy(msg_cfg);
06048       return 0;
06049    }
06050 
06051    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
06052    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
06053    category = ast_variable_retrieve(msg_cfg, "message", "category");
06054 
06055    context = ast_variable_retrieve(msg_cfg, "message", "context");
06056    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
06057       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
06058    if (!res)
06059       res = play_message_category(chan, category);
06060    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
06061       res = play_message_datetime(chan, vmu, origtime, filename);
06062    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
06063       res = play_message_callerid(chan, vms, cid, context, 0);
06064    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
06065       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
06066    /* Allow pressing '1' to skip envelope / callerid */
06067    if (res == '1')
06068       res = 0;
06069    ast_config_destroy(msg_cfg);
06070 
06071    if (!res) {
06072       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
06073       vms->heard[vms->curmsg] = 1;
06074       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
06075          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
06076          res = 0;
06077       }
06078    }
06079    DISPOSE(vms->curdir, vms->curmsg);
06080    return res;
06081 }

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

Definition at line 5832 of file app_voicemail.c.

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

Referenced by advanced_options(), and play_message().

05833 {
05834    int res = 0;
05835    int i;
05836    char *callerid, *name;
05837    char prefile[PATH_MAX] = "";
05838    
05839 
05840    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
05841    /* BB: Still need to change this so that if this function is called by the message envelope (and someone is explicitly requesting to hear the CID), it does not check to see if CID is enabled in the config file */
05842    if ((cid == NULL)||(context == NULL))
05843       return res;
05844 
05845    /* Strip off caller ID number from name */
05846    if (option_debug > 2)
05847       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05848    ast_callerid_parse(cid, &name, &callerid);
05849    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05850       /* Check for internal contexts and only */
05851       /* say extension when the call didn't come from an internal context in the list */
05852       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
05853          if (option_debug > 2)
05854             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05855          if ((strcmp(cidinternalcontexts[i], context) == 0))
05856             break;
05857       }
05858       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
05859          if (!res) {
05860             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05861             if (!ast_strlen_zero(prefile)) {
05862             /* See if we can find a recorded name for this person instead of their extension number */
05863                if (ast_fileexists(prefile, NULL, NULL) > 0) {
05864                   if (option_verbose > 2)
05865                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05866                   if (!callback)
05867                      res = wait_file2(chan, vms, "vm-from");
05868                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
05869                } else {
05870                   if (option_verbose > 2)
05871                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
05872                   /* BB: Say "from extension" as one saying to sound smoother */
05873                   if (!callback)
05874                      res = wait_file2(chan, vms, "vm-from-extension");
05875                   res = ast_say_digit_str(chan, callerid, "", chan->language);
05876                }
05877             }
05878          }
05879       }
05880 
05881       else if (!res){
05882          if (option_debug > 2)
05883             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
05884          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
05885          if (!callback)
05886             res = wait_file2(chan, vms, "vm-from-phonenumber");
05887          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05888       }
05889    } else {
05890       /* Number unknown */
05891       if (option_debug)
05892          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
05893       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05894       res = wait_file2(chan, vms, "vm-unknown-caller");
05895    }
05896    return res;
05897 }

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

Definition at line 5744 of file app_voicemail.c.

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

Referenced by play_message().

05745 {
05746    int res = 0;
05747 
05748    if (!ast_strlen_zero(category))
05749       res = ast_play_and_wait(chan, category);
05750 
05751    if (res) {
05752       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05753       res = 0;
05754    }
05755 
05756    return res;
05757 }

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

Definition at line 5759 of file app_voicemail.c.

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

Referenced by advanced_options(), and play_message().

05760 {
05761    int res = 0;
05762    struct vm_zone *the_zone = NULL;
05763    time_t t;
05764 
05765    if (ast_get_time_t(origtime, &t, 0, NULL)) {
05766       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05767       return 0;
05768    }
05769 
05770    /* Does this user have a timezone specified? */
05771    if (!ast_strlen_zero(vmu->zonetag)) {
05772       /* Find the zone in the list */
05773       struct vm_zone *z;
05774       AST_LIST_LOCK(&zones);
05775       AST_LIST_TRAVERSE(&zones, z, list) {
05776          if (!strcmp(z->name, vmu->zonetag)) {
05777             the_zone = z;
05778             break;
05779          }
05780       }
05781       AST_LIST_UNLOCK(&zones);
05782    }
05783 
05784 /* No internal variable parsing for now, so we'll comment it out for the time being */
05785 #if 0
05786    /* Set the DIFF_* variables */
05787    ast_localtime(&t, &time_now, NULL);
05788    tv_now = ast_tvnow();
05789    tnow = tv_now.tv_sec;
05790    ast_localtime(&tnow, &time_then, NULL);
05791 
05792    /* Day difference */
05793    if (time_now.tm_year == time_then.tm_year)
05794       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
05795    else
05796       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05797    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05798 
05799    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05800 #endif
05801    if (the_zone) {
05802       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05803    } else if (!strncasecmp(chan->language, "de", 2)) {    /* GERMAN syntax */
05804       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05805    } else if (!strncasecmp(chan->language, "gr", 2)) {    /* GREEK syntax */
05806       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05807    } else if (!strncasecmp(chan->language, "he", 2)) {    /* HEBREW syntax */
05808       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'at2' kM", NULL);
05809    } else if (!strncasecmp(chan->language, "it", 2)) {    /* ITALIAN syntax */
05810       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);
05811    } else if (!strncasecmp(chan->language, "nl", 2)) {    /* DUTCH syntax */
05812       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05813    } else if (!strncasecmp(chan->language, "no", 2)) {    /* NORWEGIAN syntax */
05814       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05815    } else if (!strncasecmp(chan->language, "pl", 2)) {    /* POLISH syntax */
05816       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05817    } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* PORTUGUESE syntax */
05818       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);
05819    } else if (!strncasecmp(chan->language, "se", 2)) {    /* SWEDISH syntax */
05820       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05821    } else {
05822       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05823    }
05824 #if 0
05825    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05826 #endif
05827    return res;
05828 }

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

Definition at line 5899 of file app_voicemail.c.

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

Referenced by play_message().

05900 {
05901    int res = 0;
05902    int durationm;
05903    int durations;
05904    /* Verify that we have a duration for the message */
05905    if (duration == NULL)
05906       return res;
05907 
05908    /* Convert from seconds to minutes */
05909    durations=atoi(duration);
05910    durationm=(durations / 60);
05911 
05912    if (option_debug > 2)
05913       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05914 
05915    if ((!res) && (durationm >= minduration)) {
05916       res = wait_file2(chan, vms, "vm-duration");
05917 
05918       /* POLISH syntax */
05919       if (!strncasecmp(chan->language, "pl", 2)) {
05920          div_t num = div(durationm, 10);
05921 
05922          if (durationm == 1) {
05923             res = ast_play_and_wait(chan, "digits/1z");
05924             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05925          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05926             if (num.rem == 2) {
05927                if (!num.quot) {
05928                   res = ast_play_and_wait(chan, "digits/2-ie");
05929                } else {
05930                   res = say_and_wait(chan, durationm - 2 , chan->language);
05931                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05932                }
05933             } else {
05934                res = say_and_wait(chan, durationm, chan->language);
05935             }
05936             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05937          } else {
05938             res = say_and_wait(chan, durationm, chan->language);
05939             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05940          }
05941       /* DEFAULT syntax */
05942       } else {
05943          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05944          res = wait_file2(chan, vms, "vm-minutes");
05945       }
05946    }
05947    return res;
05948 }

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

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

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

09526 {
09527    /* Record message & let caller review or re-record it, or set options if applicable */
09528    int res = 0;
09529    int cmd = 0;
09530    int max_attempts = 3;
09531    int attempts = 0;
09532    int recorded = 0;
09533    int message_exists = 0;
09534    signed char zero_gain = 0;
09535    char tempfile[PATH_MAX];
09536    char *acceptdtmf = "#";
09537    char *canceldtmf = "";
09538    int canceleddtmf = 0;
09539 
09540    /* Note that urgent and private are for flagging messages as such in the future */
09541 
09542    /* barf if no pointer passed to store duration in */
09543    if (duration == NULL) {
09544       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
09545       return -1;
09546    }
09547 
09548    if (!outsidecaller)
09549       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
09550    else
09551       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
09552 
09553    cmd = '3';  /* Want to start by recording */
09554 
09555    while ((cmd >= 0) && (cmd != 't')) {
09556       switch (cmd) {
09557       case '1':
09558          if (!message_exists) {
09559             /* In this case, 1 is to record a message */
09560             cmd = '3';
09561             break;
09562          } else {
09563             /* Otherwise 1 is to save the existing message */
09564             if (option_verbose > 2)
09565                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
09566             if (!outsidecaller)
09567                ast_filerename(tempfile, recordfile, NULL);
09568             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
09569             if (!outsidecaller) {
09570                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
09571                DISPOSE(recordfile, -1);
09572             }
09573             cmd = 't';
09574             return res;
09575          }
09576       case '2':
09577          /* Review */
09578          if (option_verbose > 2)
09579             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
09580          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
09581          break;
09582       case '3':
09583          message_exists = 0;
09584          /* Record */
09585          if (recorded == 1) {
09586             if (option_verbose > 2)
09587                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
09588          } else { 
09589             if (option_verbose > 2)
09590                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
09591          }
09592          if (recorded && outsidecaller) {
09593             cmd = ast_play_and_wait(chan, INTRO);
09594             cmd = ast_play_and_wait(chan, "beep");
09595          }
09596          recorded = 1;
09597          /* 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 */
09598          if (record_gain)
09599             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
09600          if (ast_test_flag(vmu, VM_OPERATOR))
09601             canceldtmf = "0";
09602          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
09603          if (strchr(canceldtmf, cmd)) {
09604          /* need this flag here to distinguish between pressing '0' during message recording or after */
09605             canceleddtmf = 1;
09606          }
09607          if (record_gain)
09608             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
09609          if (cmd == -1) {
09610             /* User has hung up, no options to give */
09611             if (!outsidecaller) {
09612                /* user was recording a greeting and they hung up, so let's delete the recording. */
09613                ast_filedelete(tempfile, NULL);
09614             }
09615             return cmd;
09616          }
09617          if (cmd == '0') {
09618             break;
09619          } else if (cmd == '*') {
09620             break;
09621          } 
09622 #if 0       
09623          else if (vmu->review && (*duration < 5)) {
09624             /* Message is too short */
09625             if (option_verbose > 2)
09626                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
09627             cmd = ast_play_and_wait(chan, "vm-tooshort");
09628             cmd = ast_filedelete(tempfile, NULL);
09629             break;
09630          }
09631          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
09632             /* Message is all silence */
09633             if (option_verbose > 2)
09634                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
09635             cmd = ast_filedelete(tempfile, NULL);
09636             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
09637             if (!cmd)
09638                cmd = ast_play_and_wait(chan, "vm-speakup");
09639             break;
09640          }
09641 #endif
09642          else {
09643             /* If all is well, a message exists */
09644             message_exists = 1;
09645             cmd = 0;
09646          }
09647          break;
09648       case '4':
09649       case '5':
09650       case '6':
09651       case '7':
09652       case '8':
09653       case '9':
09654       case '*':
09655       case '#':
09656          cmd = ast_play_and_wait(chan, "vm-sorry");
09657          break;
09658 #if 0 
09659 /*  XXX Commented out for the moment because of the dangers of deleting
09660     a message while recording (can put the message numbers out of sync) */
09661       case '*':
09662          /* Cancel recording, delete message, offer to take another message*/
09663          cmd = ast_play_and_wait(chan, "vm-deleted");
09664          cmd = ast_filedelete(tempfile, NULL);
09665          if (outsidecaller) {
09666             res = vm_exec(chan, NULL);
09667             return res;
09668          }
09669          else
09670             return 1;
09671 #endif
09672       case '0':
09673          if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) {
09674             cmd = ast_play_and_wait(chan, "vm-sorry");
09675             break;
09676          }
09677          if (message_exists || recorded) {
09678             cmd = ast_play_and_wait(chan, "vm-saveoper");
09679             if (!cmd)
09680                cmd = ast_waitfordigit(chan, 3000);
09681             if (cmd == '1') {
09682                ast_filerename(tempfile, recordfile, NULL);
09683                ast_play_and_wait(chan, "vm-msgsaved");
09684                cmd = '0';
09685             } else {
09686                ast_play_and_wait(chan, "vm-deleted");
09687                DELETE(tempfile, -1, tempfile, vmu);
09688                cmd = '0';
09689             }
09690          }
09691          return cmd;
09692       default:
09693          /* If the caller is an ouside caller, and the review option is enabled,
09694             allow them to review the message, but let the owner of the box review
09695             their OGM's */
09696          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
09697             return cmd;
09698          if (message_exists) {
09699             cmd = ast_play_and_wait(chan, "vm-review");
09700          } else {
09701             cmd = ast_play_and_wait(chan, "vm-torerecord");
09702             if (!cmd)
09703                cmd = ast_waitfordigit(chan, 600);
09704          }
09705          
09706          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
09707             cmd = ast_play_and_wait(chan, "vm-reachoper");
09708             if (!cmd)
09709                cmd = ast_waitfordigit(chan, 600);
09710          }
09711 #if 0
09712          if (!cmd)
09713             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
09714 #endif
09715          if (!cmd)
09716             cmd = ast_waitfordigit(chan, 6000);
09717          if (!cmd) {
09718             attempts++;
09719          }
09720          if (attempts > max_attempts) {
09721             cmd = 't';
09722          }
09723       }
09724    }
09725    if (!outsidecaller && (cmd == -1 || cmd == 't')) {
09726       /* Hang up or timeout, so delete the recording. */
09727       ast_filedelete(tempfile, NULL);
09728    }
09729 
09730    if (cmd != 't' && outsidecaller)
09731       ast_play_and_wait(chan, "vm-goodbye");
09732 
09733    return cmd;
09734 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

Definition at line 671 of file app_voicemail.c.

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

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

00672 {
00673    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00674    if (saydurationminfo)
00675       vmu->saydurationm = saydurationminfo;
00676    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00677    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00678    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00679    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00680    if (maxmsg)
00681       vmu->maxmsg = maxmsg;
00682    vmu->volgain = volgain;
00683 }

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 3249 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_strlen_zero(), ast_variable_retrieve(), ast_vm_user::context, ast_vm_user::fullname, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, and pbx_builtin_setvar_helper().

Referenced by make_email_file(), and sendpage().

03250 {
03251    char callerid[256];
03252    char fromdir[256], fromfile[256];
03253    struct ast_config *msg_cfg;
03254    const char *origcallerid, *origtime;
03255    char origcidname[80], origcidnum[80], origdate[80];
03256    int inttime;
03257 
03258    /* Prepare variables for substition in email body and subject */
03259    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
03260    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
03261    snprintf(passdata, passdatasize, "%d", msgnum);
03262    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
03263    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
03264    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
03265    pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
03266       ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
03267    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
03268    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
03269    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
03270    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
03271 
03272    /* Retrieve info from VM attribute file */
03273    make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03274    make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
03275    if (strlen(fromfile) < sizeof(fromfile) - 5) {
03276       strcat(fromfile, ".txt");
03277    }
03278    if (!(msg_cfg = ast_config_load(fromfile))) {
03279       if (option_debug > 0) {
03280          ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
03281       }
03282       return;
03283    }
03284 
03285    if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03286       pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
03287       ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
03288       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
03289       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
03290    }
03291 
03292    if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) {
03293       time_t ttime = inttime;
03294       struct tm tm;
03295       ast_localtime(&ttime, &tm, NULL);
03296       strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03297       pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
03298    }
03299    ast_config_destroy(msg_cfg);
03300 }

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

Definition at line 3302 of file app_voicemail.c.

03303 {
03304    char *ptr = to;
03305    *ptr++ = '"';
03306    for (; ptr < to + len - 1; from++) {
03307       if (*from == '"')
03308          *ptr++ = '\\';
03309       else if (*from == '\0')
03310          break;
03311       *ptr++ = *from;
03312    }
03313    if (ptr < to + len - 1)
03314       *ptr++ = '"';
03315    *ptr = '\0';
03316    return to;
03317 }

static int reload ( void   )  [static]

Definition at line 9204 of file app_voicemail.c.

References load_config().

09205 {
09206    return(load_config());
09207 }

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

Definition at line 2955 of file app_voicemail.c.

References ast_filerename().

02956 {
02957    char stxt[PATH_MAX];
02958    char dtxt[PATH_MAX];
02959    ast_filerename(sfn,dfn,NULL);
02960    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02961    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02962    rename(stxt, dtxt);
02963 }

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

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

04648 {
04649    /* we know the actual number of messages, so stop process when number is hit */
04650 
04651    int x,dest;
04652    char sfn[PATH_MAX];
04653    char dfn[PATH_MAX];
04654 
04655    if (vm_lock_path(dir))
04656       return ERROR_LOCK_PATH;
04657 
04658    for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) {
04659       make_file(sfn, sizeof(sfn), dir, x);
04660       if (EXISTS(dir, x, sfn, NULL)) {
04661          
04662          if (x != dest) {
04663             make_file(dfn, sizeof(dfn), dir, dest);
04664             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04665          }
04666          
04667          dest++;
04668       }
04669    }
04670    ast_unlock_path(dir);
04671 
04672    return dest;
04673 }

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

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

00890 {
00891    /* This function could be made to generate one from a database, too */
00892    struct ast_vm_user *cur;
00893    int res = -1;
00894    AST_LIST_LOCK(&users);
00895    AST_LIST_TRAVERSE(&users, cur, list) {
00896       if ((!context || !strcasecmp(context, cur->context)) &&
00897          (!strcasecmp(mailbox, cur->mailbox)))
00898             break;
00899    }
00900    if (cur) {
00901       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00902       res = 0;
00903    }
00904    AST_LIST_UNLOCK(&users);
00905    return res;
00906 }

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

Definition at line 4223 of file app_voicemail.c.

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

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

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

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

Definition at line 4683 of file app_voicemail.c.

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

Referenced by vm_execmain().

04684 {
04685 #ifdef IMAP_STORAGE
04686    /* we must use mbox(x) folder names, and copy the message there */
04687    /* simple. huh? */
04688    char sequence[10];
04689    /* get the real IMAP message number for this message */
04690    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04691    if (option_debug > 2)
04692       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
04693    ast_mutex_lock(&vms->lock);
04694    if (box == 1) {
04695       mail_setflag(vms->mailstream, sequence, "\\Seen");
04696    } else if (box == 0) {
04697       mail_clearflag(vms->mailstream, sequence, "\\Seen");
04698    }
04699    if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
04700       ast_mutex_unlock(&vms->lock);
04701       return 0;
04702    } else {
04703       int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
04704       ast_mutex_unlock(&vms->lock);
04705       return res;
04706    }
04707 #else
04708    char *dir = vms->curdir;
04709    char *username = vms->username;
04710    char *context = vmu->context;
04711    char sfn[PATH_MAX];
04712    char dfn[PATH_MAX];
04713    char ddir[PATH_MAX];
04714    const char *dbox = mbox(box);
04715    int x;
04716    make_file(sfn, sizeof(sfn), dir, msg);
04717    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04718 
04719    if (vm_lock_path(ddir))
04720       return ERROR_LOCK_PATH;
04721 
04722    for (x = 0; x < vmu->maxmsg; x++) {
04723       make_file(dfn, sizeof(dfn), ddir, x);
04724       if (!EXISTS(ddir, x, dfn, NULL))
04725          break;
04726    }
04727    if (x >= vmu->maxmsg) {
04728       ast_unlock_path(ddir);
04729       return ERROR_MAILBOX_FULL;
04730    }
04731    if (strcmp(sfn, dfn)) {
04732       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04733    }
04734    ast_unlock_path(ddir);
04735 #endif
04736    return 0;
04737 }

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

Definition at line 4676 of file app_voicemail.c.

References AST_DIGIT_ANY, and ast_say_number().

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

04677 {
04678    int d;
04679    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04680    return d;
04681 }

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

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

Referenced by forward_message(), and notify_new_message().

03724 {
03725    FILE *p=NULL;
03726    char tmp[80] = "/tmp/astmail-XXXXXX";
03727    char tmp2[256];
03728    char *stringp;
03729 
03730    if (vmu && ast_strlen_zero(vmu->email)) {
03731       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03732       return(0);
03733    }
03734 
03735    /* Mail only the first format */
03736    format = ast_strdupa(format);
03737    stringp = format;
03738    strsep(&stringp, "|");
03739 
03740    if (!strcmp(format, "wav49"))
03741       format = "WAV";
03742    if (option_debug > 2)
03743       ast_log(LOG_DEBUG, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
03744    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03745       command hangs */
03746    if ((p = vm_mkftemp(tmp)) == NULL) {
03747       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03748       return -1;
03749    } else {
03750       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03751       fclose(p);
03752       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03753       ast_safe_system(tmp2);
03754       if (option_debug > 2)
03755          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03756    }
03757    return 0;
03758 }

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

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

Referenced by notify_new_message().

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

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

Strips control and non 7-bit clean characters from input string.

Note:
To map control and none 7-bit characters to a 7-bit clean characters please use ast_str_encode_mine().

Definition at line 655 of file app_voicemail.c.

Referenced by make_email_file().

00656 {
00657    char *bufptr = buf;
00658    for (; *input; input++) {
00659       if (*input < 32) {
00660          continue;
00661       }
00662       *bufptr++ = *input;
00663       if (bufptr == buf + buflen - 1) {
00664          break;
00665       }
00666    }
00667    *bufptr = '\0';
00668    return buf;
00669 }

static int unload_module ( void   )  [static]

Definition at line 9209 of file app_voicemail.c.

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

09210 {
09211    int res;
09212    
09213    res = ast_unregister_application(app);
09214    res |= ast_unregister_application(app2);
09215    res |= ast_unregister_application(app3);
09216    res |= ast_unregister_application(app4);
09217    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
09218    ast_uninstall_vm_functions();
09219    ao2_ref(inprocess_container, -1);
09220    
09221    ast_module_user_hangup_all();
09222 
09223    return res;
09224 }

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

Definition at line 1080 of file app_voicemail.c.

References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.

Referenced by open_mailbox().

01080                                                                                         {
01081 
01082    int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg);
01083    if (!vms->dh_arraysize) {
01084       /* initial allocation */
01085       if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) {
01086          return -1;
01087       }
01088       if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) {
01089          return -1;
01090       }
01091       vms->dh_arraysize = arraysize;
01092    } else if (vms->dh_arraysize < arraysize) {
01093       if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) {
01094          return -1;
01095       }
01096       if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) {
01097          return -1;
01098       }
01099       memset(vms->deleted, 0, arraysize * sizeof(int));
01100       memset(vms->heard, 0, arraysize * sizeof(int));
01101       vms->dh_arraysize = arraysize;
01102    }
01103 
01104    return 0;
01105 }

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

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

Referenced by vm_execmain(), and vmauthenticate().

07556 {
07557    int useadsi=0, valid=0, logretries=0;
07558    char password[AST_MAX_EXTENSION]="", *passptr;
07559    struct ast_vm_user vmus, *vmu = NULL;
07560 
07561    /* If ADSI is supported, setup login screen */
07562    adsi_begin(chan, &useadsi);
07563    if (!skipuser && useadsi)
07564       adsi_login(chan);
07565    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
07566       ast_log(LOG_WARNING, "Couldn't stream login file\n");
07567       return -1;
07568    }
07569    
07570    /* Authenticate them and get their mailbox/password */
07571    
07572    while (!valid && (logretries < maxlogins)) {
07573       /* Prompt for, and read in the username */
07574       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
07575          ast_log(LOG_WARNING, "Couldn't read username\n");
07576          return -1;
07577       }
07578       if (ast_strlen_zero(mailbox)) {
07579          if (chan->cid.cid_num) {
07580             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
07581          } else {
07582             if (option_verbose > 2)
07583                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
07584             return -1;
07585          }
07586       }
07587       if (useadsi)
07588          adsi_password(chan);
07589 
07590       if (!ast_strlen_zero(prefix)) {
07591          char fullusername[80] = "";
07592          ast_copy_string(fullusername, prefix, sizeof(fullusername));
07593          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
07594          ast_copy_string(mailbox, fullusername, mailbox_size);
07595       }
07596 
07597       if (option_debug)
07598          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
07599       vmu = find_user(&vmus, context, mailbox);
07600       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
07601          /* saved password is blank, so don't bother asking */
07602          password[0] = '\0';
07603       } else {
07604          if (ast_streamfile(chan, "vm-password", chan->language)) {
07605             ast_log(LOG_WARNING, "Unable to stream password file\n");
07606             return -1;
07607          }
07608          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
07609             ast_log(LOG_WARNING, "Unable to read password\n");
07610             return -1;
07611          }
07612       }
07613 
07614       if (vmu) {
07615          passptr = vmu->password;
07616          if (passptr[0] == '-') passptr++;
07617       }
07618       if (vmu && !strcmp(passptr, password))
07619          valid++;
07620       else {
07621          if (option_verbose > 2)
07622             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
07623          if (!ast_strlen_zero(prefix))
07624             mailbox[0] = '\0';
07625       }
07626       logretries++;
07627       if (!valid) {
07628          if (skipuser || logretries >= maxlogins) {
07629             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
07630                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
07631                return -1;
07632             }
07633          } else {
07634             if (useadsi)
07635                adsi_login(chan);
07636             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
07637                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
07638                return -1;
07639             }
07640          }
07641          if (ast_waitstream(chan, "")) /* Channel is hung up */
07642             return -1;
07643       }
07644    }
07645    if (!valid && (logretries >= maxlogins)) {
07646       ast_stopstream(chan);
07647       ast_play_and_wait(chan, "vm-goodbye");
07648       return -1;
07649    }
07650    if (vmu && !skipuser) {
07651       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
07652    }
07653    return 0;
07654 }

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

Definition at line 8391 of file app_voicemail.c.

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

Referenced by load_module().

08392 {
08393    struct ast_module_user *u;
08394    struct ast_vm_user svm;
08395    char *context, *box;
08396    int priority_jump = 0;
08397    AST_DECLARE_APP_ARGS(args,
08398       AST_APP_ARG(mbox);
08399       AST_APP_ARG(options);
08400    );
08401 
08402    if (ast_strlen_zero(data)) {
08403       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
08404       return -1;
08405    }
08406 
08407    u = ast_module_user_add(chan);
08408 
08409    box = ast_strdupa(data);
08410 
08411    AST_STANDARD_APP_ARGS(args, box);
08412 
08413    if (args.options) {
08414       if (strchr(args.options, 'j'))
08415          priority_jump = 1;
08416    }
08417 
08418    if ((context = strchr(args.mbox, '@'))) {
08419       *context = '\0';
08420       context++;
08421    }
08422 
08423    if (find_user(&svm, context, args.mbox)) {
08424       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
08425       if (priority_jump || ast_opt_priority_jumping)
08426          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
08427             ast_log(LOG_WARNING, "VM box %s@%s exists, but extension %s, priority %d doesn't exist\n", box, context, chan->exten, chan->priority + 101);
08428    } else
08429       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
08430    ast_module_user_remove(u);
08431    return 0;
08432 }

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

Definition at line 7539 of file app_voicemail.c.

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

Referenced by vm_execmain().

07540 {
07541    if (!strncasecmp(chan->language, "es", 2) ||
07542          !strncasecmp(chan->language, "it", 2) ||
07543          !strncasecmp(chan->language, "pt", 2) ||
07544          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
07545       return vm_browse_messages_latin(chan, vms, vmu);
07546    } else if (!strncasecmp(chan->language, "he", 2)) {  /* HEBREW */
07547       return vm_browse_messages_he(chan, vms, vmu);
07548    } else {                                             /* Default to English syntax */
07549       return vm_browse_messages_en(chan, vms, vmu);
07550    }
07551 }

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

Definition at line 7474 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07475 {
07476    int cmd=0;
07477 
07478    if (vms->lastmsg > -1) {
07479       cmd = play_message(chan, vmu, vms);
07480    } else {
07481       cmd = ast_play_and_wait(chan, "vm-youhave");
07482       if (!cmd) 
07483          cmd = ast_play_and_wait(chan, "vm-no");
07484       if (!cmd) {
07485          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07486          cmd = ast_play_and_wait(chan, vms->fn);
07487       }
07488       if (!cmd)
07489          cmd = ast_play_and_wait(chan, "vm-messages");
07490    }
07491    return cmd;
07492 }

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

Definition at line 7495 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07496 {
07497    int cmd = 0;
07498 
07499    if (vms->lastmsg > -1) {
07500       cmd = play_message(chan, vmu, vms);
07501    } else {
07502       if (!strcasecmp(vms->fn, "INBOX")) {
07503          cmd = ast_play_and_wait(chan, "vm-nonewmessages");
07504       } else {
07505          cmd = ast_play_and_wait(chan, "vm-nomessages");
07506       }
07507    }
07508    return cmd;
07509 }

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

Definition at line 7512 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07513 {
07514    int cmd=0;
07515 
07516    if (vms->lastmsg > -1) {
07517       cmd = play_message(chan, vmu, vms);
07518    } else {
07519       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07520       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
07521          if (!cmd) {
07522             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07523             cmd = ast_play_and_wait(chan, vms->fn);
07524          }
07525          if (!cmd)
07526             cmd = ast_play_and_wait(chan, "vm-messages");
07527       } else {
07528          if (!cmd)
07529             cmd = ast_play_and_wait(chan, "vm-messages");
07530          if (!cmd) {
07531             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07532             cmd = ast_play_and_wait(chan, vms->fn);
07533          }
07534       }
07535    }
07536    return cmd;
07537 }

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

Definition at line 908 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00909 {
00910    struct ast_config   *cfg=NULL;
00911    struct ast_variable *var=NULL;
00912    struct ast_category *cat=NULL;
00913    char *category=NULL, *value=NULL, *new=NULL;
00914    const char *tmp=NULL;
00915                
00916    if (!change_password_realtime(vmu, newpassword))
00917       return;
00918 
00919    /* check voicemail.conf */
00920    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00921       while ((category = ast_category_browse(cfg, category))) {
00922          if (!strcasecmp(category, vmu->context)) {
00923             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00924             if (!tmp) {
00925                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00926                break;
00927             }
00928             value = strstr(tmp,",");
00929             if (!value) {
00930                new = alloca(strlen(newpassword)+1);
00931                sprintf(new, "%s", newpassword);
00932             } else {
00933                new = alloca((strlen(value)+strlen(newpassword)+1));
00934                sprintf(new,"%s%s", newpassword, value);
00935             }
00936             if (!(cat = ast_category_get(cfg, category))) {
00937                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00938                break;
00939             }
00940             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00941          }
00942       }
00943       /* save the results */
00944       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00945       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00946       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00947    }
00948    category = NULL;
00949    var = NULL;
00950    /* check users.conf and update the password stored for the mailbox*/
00951    /* if no vmsecret entry exists create one. */
00952    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00953       if (option_debug > 3)
00954          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00955       while ((category = ast_category_browse(cfg, category))) {
00956          if (option_debug > 3)
00957             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00958          if (!strcasecmp(category, vmu->mailbox)) {
00959             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00960                if (option_debug > 3)
00961                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00962                var = ast_variable_new("vmsecret", newpassword);
00963             } 
00964             new = alloca(strlen(newpassword)+1);
00965             sprintf(new, "%s", newpassword);
00966             if (!(cat = ast_category_get(cfg, category))) {
00967                if (option_debug > 3)
00968                   ast_log(LOG_DEBUG, "failed to get category!\n");
00969                break;
00970             }
00971             if (!var)      
00972                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00973             else
00974                ast_variable_append(cat, var);
00975          }
00976       }
00977       /* save the results and clean things up */
00978       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00979       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00980       config_text_file_save("users.conf", cfg, "AppVoicemail");
00981    }
00982 }

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

Definition at line 984 of file app_voicemail.c.

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

Referenced by vm_newuser(), and vm_options().

00985 {
00986    char buf[255];
00987    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00988    if (!ast_safe_system(buf)) {
00989       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00990       /* Reset the password in memory, too */
00991       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00992    }
00993 }

static int vm_delete ( char *  file  )  [static]

Definition at line 3110 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message().

03111 {
03112    char *txt;
03113    int txtsize = 0;
03114 
03115    txtsize = (strlen(file) + 5)*sizeof(char);
03116    txt = alloca(txtsize);
03117    /* Sprintf here would safe because we alloca'd exactly the right length,
03118     * but trying to eliminate all sprintf's anyhow
03119     */
03120    snprintf(txt, txtsize, "%s.txt", file);
03121    unlink(txt);
03122    return ast_filedelete(file, NULL);
03123 }

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

Definition at line 8228 of file app_voicemail.c.

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

Referenced by load_module(), and play_record_review().

08229 {
08230    int res = 0;
08231    struct ast_module_user *u;
08232    char *tmp;
08233    struct leave_vm_options leave_options;
08234    struct ast_flags flags = { 0 };
08235    static int deprecate_warning = 0;
08236    char *opts[OPT_ARG_ARRAY_SIZE];
08237    AST_DECLARE_APP_ARGS(args,
08238       AST_APP_ARG(argv0);
08239       AST_APP_ARG(argv1);
08240    );
08241 
08242    u = ast_module_user_add(chan);
08243    
08244    memset(&leave_options, 0, sizeof(leave_options));
08245 
08246    if (chan->_state != AST_STATE_UP)
08247       ast_answer(chan);
08248 
08249    if (!ast_strlen_zero(data)) {
08250       tmp = ast_strdupa(data);
08251       AST_STANDARD_APP_ARGS(args, tmp);
08252       if (args.argc == 2) {
08253          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
08254             ast_module_user_remove(u);
08255             return -1;
08256          }
08257          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
08258          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
08259             int gain;
08260 
08261             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
08262                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
08263                ast_module_user_remove(u);
08264                return -1;
08265             } else {
08266                leave_options.record_gain = (signed char) gain;
08267             }
08268          }
08269       } else {
08270          /* old style options parsing */
08271          int old = 0;
08272          char *orig_argv0 = args.argv0;
08273          while (*(args.argv0)) {
08274             if (*(args.argv0) == 's') {
08275                old = 1;
08276                ast_set_flag(&leave_options, OPT_SILENT);
08277             } else if (*(args.argv0) == 'b') {
08278                old = 1;
08279                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
08280             } else if (*(args.argv0) == 'u') {
08281                old = 1;
08282                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
08283             } else if (*(args.argv0) == 'j') {
08284                old = 1;
08285                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
08286             } else
08287                break;
08288             (args.argv0)++;
08289          }
08290          if (!deprecate_warning && old) {
08291             deprecate_warning = 1;
08292             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
08293             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
08294          }
08295       }
08296    } else {
08297       char tmp[256];
08298       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
08299       if (res < 0) {
08300          ast_module_user_remove(u);
08301          return res;
08302       }
08303       if (ast_strlen_zero(tmp)) {
08304          ast_module_user_remove(u);
08305          return 0;
08306       }
08307       args.argv0 = ast_strdupa(tmp);
08308    }
08309 
08310    res = leave_voicemail(chan, args.argv0, &leave_options);
08311    if (res == 't') {
08312       ast_play_and_wait(chan, "vm-goodbye");
08313       res = 0;
08314    }
08315 
08316    if (res == OPERATOR_EXIT) {
08317       res = 0;
08318    }
08319 
08320    if (res == ERROR_LOCK_PATH) {
08321       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
08322       /*Send the call to n+101 priority, where n is the current priority*/
08323       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
08324          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
08325             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
08326       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
08327       res = 0;
08328    }
08329    
08330    ast_module_user_remove(u);
08331 
08332    return res;
08333 }

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

Definition at line 7656 of file app_voicemail.c.

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

Referenced by load_module().

07657 {
07658    /* XXX This is, admittedly, some pretty horrendus code.  For some
07659       reason it just seemed a lot easier to do with GOTO's.  I feel
07660       like I'm back in my GWBASIC days. XXX */
07661    int res=-1;
07662    int cmd=0;
07663    int valid = 0;
07664    struct ast_module_user *u;
07665    char prefixstr[80] ="";
07666    char ext_context[256]="";
07667    int box;
07668    int useadsi = 0;
07669    int skipuser = 0;
07670    struct vm_state vms;
07671    struct ast_vm_user *vmu = NULL, vmus;
07672    char *context=NULL;
07673    int silentexit = 0;
07674    struct ast_flags flags = { 0 };
07675    signed char record_gain = 0;
07676    int play_auto = 0;
07677    int play_folder = 0;
07678 #ifdef IMAP_STORAGE
07679    int deleted = 0;
07680 #endif
07681    u = ast_module_user_add(chan);
07682 
07683    /* Add the vm_state to the active list and keep it active */
07684    memset(&vms, 0, sizeof(vms));
07685    vms.lastmsg = -1;
07686 
07687    memset(&vmus, 0, sizeof(vmus));
07688 
07689    if (chan->_state != AST_STATE_UP) {
07690       if (option_debug)
07691          ast_log(LOG_DEBUG, "Before ast_answer\n");
07692       ast_answer(chan);
07693    }
07694 
07695    if (!ast_strlen_zero(data)) {
07696       char *opts[OPT_ARG_ARRAY_SIZE];
07697       char *parse;
07698       AST_DECLARE_APP_ARGS(args,
07699          AST_APP_ARG(argv0);
07700          AST_APP_ARG(argv1);
07701       );
07702 
07703       parse = ast_strdupa(data);
07704 
07705       AST_STANDARD_APP_ARGS(args, parse);
07706 
07707       if (args.argc == 2) {
07708          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07709             ast_module_user_remove(u);
07710             return -1;
07711          }
07712          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07713             int gain;
07714             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
07715                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
07716                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07717                   ast_module_user_remove(u);
07718                   return -1;
07719                } else {
07720                   record_gain = (signed char) gain;
07721                }
07722             } else {
07723                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
07724             }
07725          }
07726          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
07727             play_auto = 1;
07728             if (opts[OPT_ARG_PLAYFOLDER]) {
07729                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) {
07730                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
07731                }
07732             } else {
07733                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
07734             }  
07735             if ( play_folder > 9 || play_folder < 0) {
07736                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
07737                play_folder = 0;
07738             }
07739          }
07740       } else {
07741          /* old style options parsing */
07742          while (*(args.argv0)) {
07743             if (*(args.argv0) == 's')
07744                ast_set_flag(&flags, OPT_SILENT);
07745             else if (*(args.argv0) == 'p')
07746                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
07747             else 
07748                break;
07749             (args.argv0)++;
07750          }
07751 
07752       }
07753 
07754       valid = ast_test_flag(&flags, OPT_SILENT);
07755 
07756       if ((context = strchr(args.argv0, '@')))
07757          *context++ = '\0';
07758 
07759       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
07760          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
07761       else
07762          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
07763 
07764       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
07765          skipuser++;
07766       else
07767          valid = 0;
07768    }
07769 
07770    if (!valid)
07771       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
07772 
07773    if (option_debug)
07774       ast_log(LOG_DEBUG, "After vm_authenticate\n");
07775    if (!res) {
07776       valid = 1;
07777       if (!skipuser)
07778          vmu = &vmus;
07779    } else {
07780       res = 0;
07781    }
07782 
07783    /* If ADSI is supported, setup login screen */
07784    adsi_begin(chan, &useadsi);
07785 
07786    if (!valid) {
07787       goto out;
07788    }
07789 
07790 #ifdef IMAP_STORAGE
07791    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
07792    pthread_setspecific(ts_vmstate.key, &vms);
07793 
07794    vms.interactive = 1;
07795    vms.updated = 1;
07796    if (vmu)
07797       ast_copy_string(vms.context, vmu->context, sizeof(vms.context));
07798    vmstate_insert(&vms);
07799    init_vm_state(&vms);
07800 #endif
07801 
07802    /* Set language from config to override channel language */
07803    if (!ast_strlen_zero(vmu->language))
07804       ast_string_field_set(chan, language, vmu->language);
07805    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
07806    /* Retrieve old and new message counts */
07807    if (option_debug)
07808       ast_log(LOG_DEBUG, "Before open_mailbox\n");
07809    res = open_mailbox(&vms, vmu, 1);
07810    if (res < 0)
07811       goto out;
07812    vms.oldmessages = vms.lastmsg + 1;
07813    if (option_debug > 2)
07814       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
07815    /* Start in INBOX */
07816    res = open_mailbox(&vms, vmu, 0);
07817    if (res < 0)
07818       goto out;
07819    vms.newmessages = vms.lastmsg + 1;
07820    if (option_debug > 2)
07821       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
07822       
07823    /* Select proper mailbox FIRST!! */
07824    if (play_auto) {
07825       res = open_mailbox(&vms, vmu, play_folder);
07826       if (res < 0)
07827          goto out;
07828 
07829       /* If there are no new messages, inform the user and hangup */
07830       if (vms.lastmsg == -1) {
07831          cmd = vm_browse_messages(chan, &vms, vmu);
07832          res = 0;
07833          goto out;
07834       }
07835    } else {
07836       if (!vms.newmessages && vms.oldmessages) {
07837          /* If we only have old messages start here */
07838          res = open_mailbox(&vms, vmu, 1);
07839          play_folder = 1;
07840          if (res < 0)
07841             goto out;
07842       }
07843    }
07844 
07845    if (useadsi)
07846       adsi_status(chan, &vms);
07847    res = 0;
07848 
07849    /* Check to see if this is a new user */
07850    if (!strcasecmp(vmu->mailbox, vmu->password) && 
07851       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
07852       if (ast_play_and_wait(chan, "vm-newuser") == -1)
07853          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
07854       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
07855       if ((cmd == 't') || (cmd == '#')) {
07856          /* Timeout */
07857          res = 0;
07858          goto out;
07859       } else if (cmd < 0) {
07860          /* Hangup */
07861          res = -1;
07862          goto out;
07863       }
07864    }
07865 #ifdef IMAP_STORAGE
07866       if (option_debug > 2)
07867          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
07868       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
07869          if (option_debug)
07870             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
07871          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07872       }
07873       if (option_debug > 2)
07874          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07875       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
07876          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07877          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07878       }
07879 #endif
07880    if (play_auto) {
07881       cmd = '1';
07882    } else {
07883       cmd = vm_intro(chan, vmu, &vms);
07884    }
07885 
07886    vms.repeats = 0;
07887    vms.starting = 1;
07888    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07889       /* Run main menu */
07890       switch (cmd) {
07891       case '1':
07892          vms.curmsg = 0;
07893          /* Fall through */
07894       case '5':
07895          cmd = vm_browse_messages(chan, &vms, vmu);
07896          break;
07897       case '2': /* Change folders */
07898          if (useadsi)
07899             adsi_folders(chan, 0, "Change to folder...");
07900          cmd = get_folder2(chan, "vm-changeto", 0);
07901          if (cmd == '#') {
07902             cmd = 0;
07903          } else if (cmd > 0) {
07904             cmd = cmd - '0';
07905             res = close_mailbox(&vms, vmu);
07906             if (res == ERROR_LOCK_PATH)
07907                goto out;
07908             res = open_mailbox(&vms, vmu, cmd);
07909             if (res < 0)
07910                goto out;
07911             play_folder = cmd;
07912             cmd = 0;
07913          }
07914          if (useadsi)
07915             adsi_status2(chan, &vms);
07916             
07917          if (!cmd)
07918             cmd = vm_play_folder_name(chan, vms.vmbox);
07919 
07920          vms.starting = 1;
07921          break;
07922       case '3': /* Advanced options */
07923          cmd = 0;
07924          vms.repeats = 0;
07925          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07926             switch (cmd) {
07927             case '1': /* Reply */
07928                if (vms.lastmsg > -1 && !vms.starting) {
07929                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
07930                   if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) {
07931                      res = cmd;
07932                      goto out;
07933                   }
07934                } else
07935                   cmd = ast_play_and_wait(chan, "vm-sorry");
07936                cmd = 't';
07937                break;
07938             case '2': /* Callback */
07939                if (option_verbose > 2 && !vms.starting)
07940                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
07941                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
07942                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
07943                   if (cmd == 9) {
07944                      silentexit = 1;
07945                      goto out;
07946                   } else if (cmd == ERROR_LOCK_PATH) {
07947                      res = cmd;
07948                      goto out;
07949                   }
07950                }
07951                else 
07952                   cmd = ast_play_and_wait(chan, "vm-sorry");
07953                cmd = 't';
07954                break;
07955             case '3': /* Envelope */
07956                if (vms.lastmsg > -1 && !vms.starting) {
07957                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
07958                   if (cmd == ERROR_LOCK_PATH) {
07959                      res = cmd;
07960                      goto out;
07961                   }
07962                } else
07963                   cmd = ast_play_and_wait(chan, "vm-sorry");
07964                cmd = 't';
07965                break;
07966             case '4': /* Dialout */
07967                if (!ast_strlen_zero(vmu->dialout)) {
07968                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
07969                   if (cmd == 9) {
07970                      silentexit = 1;
07971                      goto out;
07972                   }
07973                }
07974                else 
07975                   cmd = ast_play_and_wait(chan, "vm-sorry");
07976                cmd = 't';
07977                break;
07978 
07979             case '5': /* Leave VoiceMail */
07980                if (ast_test_flag(vmu, VM_SVMAIL)) {
07981                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
07982                   if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) {
07983                      res = cmd;
07984                      goto out;
07985                   }
07986                } else
07987                   cmd = ast_play_and_wait(chan,"vm-sorry");
07988                cmd='t';
07989                break;
07990                
07991             case '*': /* Return to main menu */
07992                cmd = 't';
07993                break;
07994 
07995             default:
07996                cmd = 0;
07997                if (!vms.starting) {
07998                   cmd = ast_play_and_wait(chan, "vm-toreply");
07999                }
08000                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
08001                   cmd = ast_play_and_wait(chan, "vm-tocallback");
08002                }
08003                if (!cmd && !vms.starting) {
08004                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
08005                }
08006                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
08007                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
08008                }
08009                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
08010                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
08011                if (!cmd)
08012                   cmd = ast_play_and_wait(chan, "vm-starmain");
08013                if (!cmd)
08014                   cmd = ast_waitfordigit(chan,6000);
08015                if (!cmd)
08016                   vms.repeats++;
08017                if (vms.repeats > 3)
08018                   cmd = 't';
08019             }
08020          }
08021          if (cmd == 't') {
08022             cmd = 0;
08023             vms.repeats = 0;
08024          }
08025          break;
08026       case '4':
08027          if (vms.curmsg > 0) {
08028             vms.curmsg--;
08029             cmd = play_message(chan, vmu, &vms);
08030          } else {
08031             cmd = ast_play_and_wait(chan, "vm-nomore");
08032          }
08033          break;
08034       case '6':
08035          if (vms.curmsg < vms.lastmsg) {
08036             vms.curmsg++;
08037             cmd = play_message(chan, vmu, &vms);
08038          } else {
08039             cmd = ast_play_and_wait(chan, "vm-nomore");
08040          }
08041          break;
08042       case '7':
08043          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
08044             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
08045             if (useadsi)
08046                adsi_delete(chan, &vms);
08047             if (vms.deleted[vms.curmsg]) {
08048                if (play_folder == 0)
08049                   vms.newmessages--;
08050                else if (play_folder == 1)
08051                   vms.oldmessages--;
08052                cmd = ast_play_and_wait(chan, "vm-deleted");
08053             }
08054             else {
08055                if (play_folder == 0)
08056                   vms.newmessages++;
08057                else if (play_folder == 1)
08058                   vms.oldmessages++;
08059                cmd = ast_play_and_wait(chan, "vm-undeleted");
08060             }
08061             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
08062                if (vms.curmsg < vms.lastmsg) {
08063                   vms.curmsg++;
08064                   cmd = play_message(chan, vmu, &vms);
08065                } else {
08066                   cmd = ast_play_and_wait(chan, "vm-nomore");
08067                }
08068             }
08069          } else /* Delete not valid if we haven't selected a message */
08070             cmd = 0;
08071 #ifdef IMAP_STORAGE
08072          deleted = 1;
08073 #endif
08074          break;
08075    
08076       case '8':
08077          if (vms.lastmsg > -1) {
08078             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, 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-nomore");
08085          break;
08086       case '9':
08087          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
08088             /* No message selected */
08089             cmd = 0;
08090             break;
08091          }
08092          if (useadsi)
08093             adsi_folders(chan, 1, "Save to folder...");
08094          cmd = get_folder2(chan, "vm-savefolder", 1);
08095          box = 0; /* Shut up compiler */
08096          if (cmd == '#') {
08097             cmd = 0;
08098             break;
08099          } else if (cmd > 0) {
08100             box = cmd = cmd - '0';
08101             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
08102             if (cmd == ERROR_LOCK_PATH) {
08103                res = cmd;
08104                goto out;
08105 #ifndef IMAP_STORAGE
08106             } else if (!cmd) {
08107                vms.deleted[vms.curmsg] = 1;
08108 #endif
08109             } else {
08110                vms.deleted[vms.curmsg] = 0;
08111                vms.heard[vms.curmsg] = 0;
08112             }
08113          }
08114          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
08115          if (useadsi)
08116             adsi_message(chan, &vms);
08117          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
08118          if (!cmd) {
08119             cmd = ast_play_and_wait(chan, "vm-message");
08120             if (!cmd)
08121                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
08122             if (!cmd)
08123                cmd = ast_play_and_wait(chan, "vm-savedto");
08124             if (!cmd)
08125                cmd = vm_play_folder_name(chan, vms.fn);
08126          } else {
08127             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
08128          }
08129          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
08130             if (vms.curmsg < vms.lastmsg) {
08131                vms.curmsg++;
08132                cmd = play_message(chan, vmu, &vms);
08133             } else {
08134                cmd = ast_play_and_wait(chan, "vm-nomore");
08135             }
08136          }
08137          break;
08138       case '*':
08139          if (!vms.starting) {
08140             cmd = ast_play_and_wait(chan, "vm-onefor");
08141             if (!strncasecmp(chan->language, "he", 2)) {
08142                cmd = ast_play_and_wait(chan, "vm-for");
08143             }
08144             if (!cmd)
08145                cmd = vm_play_folder_name(chan, vms.vmbox);
08146             if (!cmd)
08147                cmd = ast_play_and_wait(chan, "vm-opts");
08148             if (!cmd)
08149                cmd = vm_instructions(chan, &vms, 1);
08150          } else
08151             cmd = 0;
08152          break;
08153       case '0':
08154          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
08155          if (useadsi)
08156             adsi_status(chan, &vms);
08157          break;
08158       default: /* Nothing */
08159          cmd = vm_instructions(chan, &vms, 0);
08160          break;
08161       }
08162    }
08163    if ((cmd == 't') || (cmd == '#')) {
08164       /* Timeout */
08165       res = 0;
08166    } else {
08167       /* Hangup */
08168       res = -1;
08169    }
08170 
08171 out:
08172    if (res > -1) {
08173       ast_stopstream(chan);
08174       adsi_goodbye(chan);
08175       if (valid && res != OPERATOR_EXIT) {
08176          if (silentexit)
08177             res = ast_play_and_wait(chan, "vm-dialout");
08178          else 
08179             res = ast_play_and_wait(chan, "vm-goodbye");
08180       }
08181       if ((valid && res > 0) || res == OPERATOR_EXIT) {
08182          res = 0;
08183       }
08184       if (useadsi)
08185          ast_adsi_unload_session(chan);
08186    }
08187    if (vmu)
08188       close_mailbox(&vms, vmu);
08189    if (valid) {
08190       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
08191       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
08192       run_externnotify(vmu->context, vmu->mailbox);
08193    }
08194 #ifdef IMAP_STORAGE
08195    /* expunge message - use UID Expunge if supported on IMAP server*/
08196    if (option_debug > 2)
08197       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
08198    if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) {
08199       ast_mutex_lock(&vms.lock);
08200 #ifdef HAVE_IMAP_TK2006
08201       if (LEVELUIDPLUS (vms.mailstream)) {
08202          mail_expunge_full(vms.mailstream,NIL,EX_UID);
08203       } else 
08204 #endif
08205          mail_expunge(vms.mailstream);
08206       ast_mutex_unlock(&vms.lock);
08207    }
08208    /*  before we delete the state, we should copy pertinent info
08209     *  back to the persistent model */
08210    if (vmu) {
08211       vmstate_delete(&vms);
08212    }
08213 #endif
08214    if (vmu)
08215       free_user(vmu);
08216    if (vms.deleted)
08217       free(vms.deleted);
08218    if (vms.heard)
08219       free(vms.heard);
08220 
08221 #ifdef IMAP_STORAGE
08222    pthread_setspecific(ts_vmstate.key, NULL);
08223 #endif
08224    ast_module_user_remove(u);
08225    return res;
08226 }

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

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load(), ast_copy_string(), ast_filecopy(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_strlen_zero(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), config_text_file_save(), copy(), LOG_NOTICE, and make_file().

Referenced by forward_message().

05283 {
05284    int cmd = 0;
05285    int retries = 0, prepend_duration = 0, already_recorded = 0;
05286    signed char zero_gain = 0;
05287    struct ast_config *msg_cfg;
05288    const char *duration_cstr;
05289    char msgfile[PATH_MAX], backup[PATH_MAX];
05290    char textfile[PATH_MAX];
05291    char backup_textfile[PATH_MAX];
05292    struct ast_category *msg_cat;
05293    char duration_str[12] = "";
05294 
05295    ast_log(LOG_NOTICE, "curdir=%s\n", curdir);
05296    /* Must always populate duration correctly */
05297    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
05298    strcpy(textfile, msgfile);
05299    strcpy(backup, msgfile);
05300    strcpy(backup_textfile, msgfile);
05301    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
05302    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
05303    strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
05304 
05305    if (!(msg_cfg = ast_config_load(textfile))) {
05306       return -1;
05307    }
05308 
05309    *duration = 0;
05310    if ((duration_cstr = ast_variable_retrieve(msg_cfg, "message", "duration"))) {
05311       *duration = atoi(duration_cstr);
05312    }
05313 
05314    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
05315       if (cmd)
05316          retries = 0;
05317       switch (cmd) {
05318       case '1': 
05319          /* prepend a message to the current message, update the metadata and return */
05320       {
05321          prepend_duration = 0;
05322 
05323          /* Back up the original file, so we can retry the prepend */
05324 #ifndef IMAP_STORAGE
05325          if (already_recorded) {
05326             ast_filecopy(backup, msgfile, NULL);
05327             copy(textfile, backup_textfile);
05328          } else {
05329             ast_filecopy(msgfile, backup, NULL);
05330             copy(textfile, backup_textfile);
05331          }
05332 #endif
05333          already_recorded = 1;
05334 
05335          if (record_gain)
05336             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
05337 
05338          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
05339          if (cmd == 'S') {
05340             ast_filerename(backup, msgfile, NULL);
05341          }
05342 
05343          if (record_gain)
05344             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
05345 
05346          if (prepend_duration) {
05347             prepend_duration += *duration;
05348          }
05349 
05350          break;
05351       }
05352       case '2': 
05353          cmd = 't';
05354          break;
05355       case '*':
05356          cmd = '*';
05357          break;
05358       default: 
05359          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
05360             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
05361          if (!cmd)
05362             cmd = ast_play_and_wait(chan,"vm-starmain");
05363             /* "press star to return to the main menu" */
05364          if (!cmd)
05365             cmd = ast_waitfordigit(chan,6000);
05366          if (!cmd)
05367             retries++;
05368          if (retries > 3)
05369             cmd = 't';
05370       }
05371    }
05372 
05373    if (already_recorded && cmd == -1) {
05374       /* Restore original files, if operation cancelled */
05375       ast_filerename(backup, msgfile, NULL);
05376       if (duration_cstr) {
05377          ast_copy_string(duration_str, duration_cstr, sizeof(duration_str));
05378       }
05379    } else if (prepend_duration) {
05380       *duration = prepend_duration;
05381       snprintf(duration_str, sizeof(duration_str), "%d", prepend_duration);
05382    }
05383 
05384    msg_cat = ast_category_get(msg_cfg, "message");
05385    if (!ast_strlen_zero(duration_str) && !ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
05386       config_text_file_save(textfile, msg_cfg, "app_voicemail");
05387    }
05388    ast_config_destroy(msg_cfg);
05389 
05390    if (cmd == 't' || cmd == 'S')
05391       cmd = 0;
05392    return cmd;
05393 }

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

Definition at line 7162 of file app_voicemail.c.

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

Referenced by vm_execmain().

07163 {
07164    int res = 0;
07165    /* Play instructions and wait for new command */
07166    while (!res) {
07167       if (vms->starting) {
07168          if (vms->lastmsg > -1) {
07169             res = ast_play_and_wait(chan, "vm-onefor");
07170             if (!strncasecmp(chan->language, "he", 2)) {
07171                res = ast_play_and_wait(chan, "vm-for");
07172             }
07173             if (!res)
07174                res = vm_play_folder_name(chan, vms->vmbox);
07175          }
07176          if (!res)
07177             res = ast_play_and_wait(chan, "vm-opts");
07178       } else {
07179          if (vms->curmsg)
07180             res = ast_play_and_wait(chan, "vm-prev");
07181          if (!res && !skipadvanced)
07182             res = ast_play_and_wait(chan, "vm-advopts");
07183          if (!res)
07184             res = ast_play_and_wait(chan, "vm-repeat");
07185          if (!res && (vms->curmsg != vms->lastmsg))
07186             res = ast_play_and_wait(chan, "vm-next");
07187          if (!res) {
07188             if (!vms->deleted[vms->curmsg])
07189                res = ast_play_and_wait(chan, "vm-delete");
07190             else
07191                res = ast_play_and_wait(chan, "vm-undelete");
07192             if (!res)
07193                res = ast_play_and_wait(chan, "vm-toforward");
07194             if (!res)
07195                res = ast_play_and_wait(chan, "vm-savemessage");
07196          }
07197       }
07198       if (!res)
07199          res = ast_play_and_wait(chan, "vm-helpexit");
07200       if (!res)
07201          res = ast_waitfordigit(chan, 6000);
07202       if (!res) {
07203          vms->repeats++;
07204          if (vms->repeats > 2) {
07205             res = 't';
07206          }
07207       }
07208    }
07209    return res;
07210 }

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

Definition at line 7105 of file app_voicemail.c.

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

Referenced by vm_execmain().

07106 {
07107    char prefile[256];
07108    
07109    /* Notify the user that the temp greeting is set and give them the option to remove it */
07110    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07111    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
07112       RETRIEVE(prefile, -1, vmu);
07113       if (ast_fileexists(prefile, NULL, NULL) > 0)
07114          ast_play_and_wait(chan, "vm-tempgreetactive");
07115       DISPOSE(prefile, -1);
07116    }
07117 
07118    /* Play voicemail intro - syntax is different for different languages */
07119    if (0) {
07120       return 0;
07121    } else if (!strncasecmp(chan->language, "cs", 2)) {  /* CZECH syntax */
07122       return vm_intro_cs(chan, vms);
07123    } else if (!strncasecmp(chan->language, "cz", 2)) {  /* deprecated CZECH syntax */
07124       static int deprecation_warning = 0;
07125       if (deprecation_warning++ % 10 == 0) {
07126          ast_log(LOG_WARNING, "cz is not a standard language code.  Please switch to using cs instead.\n");
07127       }
07128       return vm_intro_cs(chan, vms);
07129    } else if (!strncasecmp(chan->language, "de", 2)) {  /* GERMAN syntax */
07130       return vm_intro_de(chan, vms);
07131    } else if (!strncasecmp(chan->language, "es", 2)) {  /* SPANISH syntax */
07132       return vm_intro_es(chan, vms);
07133    } else if (!strncasecmp(chan->language, "fr", 2)) {  /* FRENCH syntax */
07134       return vm_intro_fr(chan, vms);
07135    } else if (!strncasecmp(chan->language, "gr", 2)) {  /* GREEK syntax */
07136       return vm_intro_gr(chan, vms);
07137    } else if (!strncasecmp(chan->language, "he", 2)) {  /* HEBREW syntax */
07138       return vm_intro_he(chan, vms);
07139    } else if (!strncasecmp(chan->language, "it", 2)) {  /* ITALIAN syntax */
07140       return vm_intro_it(chan, vms);
07141    } else if (!strncasecmp(chan->language, "nl", 2)) {  /* DUTCH syntax */
07142       return vm_intro_nl(chan, vms);
07143    } else if (!strncasecmp(chan->language, "no", 2)) {  /* NORWEGIAN syntax */
07144       return vm_intro_no(chan, vms);
07145    } else if (!strncasecmp(chan->language, "pl", 2)) {  /* POLISH syntax */
07146       return vm_intro_pl(chan, vms);
07147    } else if (!strncasecmp(chan->language, "pt_BR", 5)) {  /* BRAZILIAN PORTUGUESE syntax */
07148       return vm_intro_pt_BR(chan, vms);
07149    } else if (!strncasecmp(chan->language, "pt", 2)) {  /* PORTUGUESE syntax */
07150       return vm_intro_pt(chan, vms);
07151    } else if (!strncasecmp(chan->language, "ru", 2)) {  /* RUSSIAN syntax */
07152       return vm_intro_multilang(chan, vms, "n");
07153    } else if (!strncasecmp(chan->language, "se", 2)) {  /* SWEDISH syntax */
07154       return vm_intro_se(chan, vms);
07155    } else if (!strncasecmp(chan->language, "ua", 2)) {  /* UKRAINIAN syntax */
07156       return vm_intro_multilang(chan, vms, "n");
07157    } else {                                             /* Default to ENGLISH */
07158       return vm_intro_en(chan, vms);
07159    }
07160 }

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

Definition at line 7045 of file app_voicemail.c.

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

Referenced by vm_intro().

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

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

Definition at line 6738 of file app_voicemail.c.

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

Referenced by vm_intro().

06739 {
06740    /* Introduce messages they have */
06741    int res;
06742    res = ast_play_and_wait(chan, "vm-youhave");
06743    if (!res) {
06744       if (vms->newmessages) {
06745          if ((vms->newmessages == 1))
06746             res = ast_play_and_wait(chan, "digits/1F");
06747          else
06748             res = say_and_wait(chan, vms->newmessages, chan->language);
06749          if (!res)
06750             res = ast_play_and_wait(chan, "vm-INBOX");
06751          if (vms->oldmessages && !res)
06752             res = ast_play_and_wait(chan, "vm-and");
06753          else if (!res) {
06754             if ((vms->newmessages == 1))
06755                res = ast_play_and_wait(chan, "vm-message");
06756             else
06757                res = ast_play_and_wait(chan, "vm-messages");
06758          }
06759             
06760       }
06761       if (!res && vms->oldmessages) {
06762          if (vms->oldmessages == 1)
06763             res = ast_play_and_wait(chan, "digits/1F");
06764          else
06765             res = say_and_wait(chan, vms->oldmessages, chan->language);
06766          if (!res)
06767             res = ast_play_and_wait(chan, "vm-Old");
06768          if (!res) {
06769             if (vms->oldmessages == 1)
06770                res = ast_play_and_wait(chan, "vm-message");
06771             else
06772                res = ast_play_and_wait(chan, "vm-messages");
06773          }
06774       }
06775       if (!res) {
06776          if (!vms->oldmessages && !vms->newmessages) {
06777             res = ast_play_and_wait(chan, "vm-no");
06778             if (!res)
06779                res = ast_play_and_wait(chan, "vm-messages");
06780          }
06781       }
06782    }
06783    return res;
06784 }

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

Definition at line 6336 of file app_voicemail.c.

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

Referenced by vm_intro().

06337 {
06338    int res;
06339 
06340    /* Introduce messages they have */
06341    res = ast_play_and_wait(chan, "vm-youhave");
06342    if (!res) {
06343       if (vms->newmessages) {
06344          res = say_and_wait(chan, vms->newmessages, chan->language);
06345          if (!res)
06346             res = ast_play_and_wait(chan, "vm-INBOX");
06347          if (vms->oldmessages && !res)
06348             res = ast_play_and_wait(chan, "vm-and");
06349          else if (!res) {
06350             if ((vms->newmessages == 1))
06351                res = ast_play_and_wait(chan, "vm-message");
06352             else
06353                res = ast_play_and_wait(chan, "vm-messages");
06354          }
06355             
06356       }
06357       if (!res && vms->oldmessages) {
06358          res = say_and_wait(chan, vms->oldmessages, chan->language);
06359          if (!res)
06360             res = ast_play_and_wait(chan, "vm-Old");
06361          if (!res) {
06362             if (vms->oldmessages == 1)
06363                res = ast_play_and_wait(chan, "vm-message");
06364             else
06365                res = ast_play_and_wait(chan, "vm-messages");
06366          }
06367       }
06368       if (!res) {
06369          if (!vms->oldmessages && !vms->newmessages) {
06370             res = ast_play_and_wait(chan, "vm-no");
06371             if (!res)
06372                res = ast_play_and_wait(chan, "vm-messages");
06373          }
06374       }
06375    }
06376    return res;
06377 }

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

Definition at line 6787 of file app_voicemail.c.

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

Referenced by vm_intro().

06788 {
06789    /* Introduce messages they have */
06790    int res;
06791    if (!vms->oldmessages && !vms->newmessages) {
06792       res = ast_play_and_wait(chan, "vm-youhaveno");
06793       if (!res)
06794          res = ast_play_and_wait(chan, "vm-messages");
06795    } else {
06796       res = ast_play_and_wait(chan, "vm-youhave");
06797    }
06798    if (!res) {
06799       if (vms->newmessages) {
06800          if (!res) {
06801             if ((vms->newmessages == 1)) {
06802                res = ast_play_and_wait(chan, "digits/1");
06803                if (!res)
06804                   res = ast_play_and_wait(chan, "vm-message");
06805                if (!res)
06806                   res = ast_play_and_wait(chan, "vm-INBOXs");
06807             } else {
06808                res = say_and_wait(chan, vms->newmessages, chan->language);
06809                if (!res)
06810                   res = ast_play_and_wait(chan, "vm-messages");
06811                if (!res)
06812                   res = ast_play_and_wait(chan, "vm-INBOX");
06813             }
06814          }
06815          if (vms->oldmessages && !res)
06816             res = ast_play_and_wait(chan, "vm-and");
06817       }
06818       if (vms->oldmessages) {
06819          if (!res) {
06820             if (vms->oldmessages == 1) {
06821                res = ast_play_and_wait(chan, "digits/1");
06822                if (!res)
06823                   res = ast_play_and_wait(chan, "vm-message");
06824                if (!res)
06825                   res = ast_play_and_wait(chan, "vm-Olds");
06826             } else {
06827                res = say_and_wait(chan, vms->oldmessages, chan->language);
06828                if (!res)
06829                   res = ast_play_and_wait(chan, "vm-messages");
06830                if (!res)
06831                   res = ast_play_and_wait(chan, "vm-Old");
06832             }
06833          }
06834       }
06835    }
06836 return res;
06837 }

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

Definition at line 6888 of file app_voicemail.c.

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

Referenced by vm_intro().

06889 {
06890    /* Introduce messages they have */
06891    int res;
06892    res = ast_play_and_wait(chan, "vm-youhave");
06893    if (!res) {
06894       if (vms->newmessages) {
06895          res = say_and_wait(chan, vms->newmessages, chan->language);
06896          if (!res)
06897             res = ast_play_and_wait(chan, "vm-INBOX");
06898          if (vms->oldmessages && !res)
06899             res = ast_play_and_wait(chan, "vm-and");
06900          else if (!res) {
06901             if ((vms->newmessages == 1))
06902                res = ast_play_and_wait(chan, "vm-message");
06903             else
06904                res = ast_play_and_wait(chan, "vm-messages");
06905          }
06906             
06907       }
06908       if (!res && vms->oldmessages) {
06909          res = say_and_wait(chan, vms->oldmessages, chan->language);
06910          if (!res)
06911             res = ast_play_and_wait(chan, "vm-Old");
06912          if (!res) {
06913             if (vms->oldmessages == 1)
06914                res = ast_play_and_wait(chan, "vm-message");
06915             else
06916                res = ast_play_and_wait(chan, "vm-messages");
06917          }
06918       }
06919       if (!res) {
06920          if (!vms->oldmessages && !vms->newmessages) {
06921             res = ast_play_and_wait(chan, "vm-no");
06922             if (!res)
06923                res = ast_play_and_wait(chan, "vm-messages");
06924          }
06925       }
06926    }
06927    return res;
06928 }

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

Definition at line 6298 of file app_voicemail.c.

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

Referenced by vm_intro().

06299 {
06300    int res = 0;
06301 
06302    if (vms->newmessages) {
06303       res = ast_play_and_wait(chan, "vm-youhave");
06304       if (!res) 
06305          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
06306       if (!res) {
06307          if ((vms->newmessages == 1)) {
06308             res = ast_play_and_wait(chan, "vm-INBOX");
06309             if (!res)
06310                res = ast_play_and_wait(chan, "vm-message");
06311          } else {
06312             res = ast_play_and_wait(chan, "vm-INBOXs");
06313             if (!res)
06314                res = ast_play_and_wait(chan, "vm-messages");
06315          }
06316       }
06317    } else if (vms->oldmessages){
06318       res = ast_play_and_wait(chan, "vm-youhave");
06319       if (!res)
06320          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
06321       if ((vms->oldmessages == 1)){
06322          res = ast_play_and_wait(chan, "vm-Old");
06323          if (!res)
06324             res = ast_play_and_wait(chan, "vm-message");
06325       } else {
06326          res = ast_play_and_wait(chan, "vm-Olds");
06327          if (!res)
06328             res = ast_play_and_wait(chan, "vm-messages");
06329       }
06330    } else if (!vms->oldmessages && !vms->newmessages) 
06331       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
06332    return res;
06333 }

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

Definition at line 6476 of file app_voicemail.c.

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

Referenced by vm_intro().

06477 {
06478    int res=0;
06479 
06480    /* Introduce messages they have */
06481    if (!res) {
06482       if ((vms->newmessages) || (vms->oldmessages)) {
06483          res = ast_play_and_wait(chan, "vm-youhave");
06484       }
06485       /*
06486        * The word "shtei" refers to the number 2 in hebrew when performing a count
06487        * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
06488        * an element, this is one of them.
06489        */
06490       if (vms->newmessages) {
06491          if (!res) {
06492             if (vms->newmessages == 1) {
06493                res = ast_play_and_wait(chan, "vm-INBOX1");
06494             } else {
06495                if (vms->newmessages == 2) {
06496                   res = ast_play_and_wait(chan, "vm-shtei");
06497                } else {
06498                   res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06499                }
06500                res = ast_play_and_wait(chan, "vm-INBOX");
06501             }
06502          }
06503          if (vms->oldmessages && !res) {
06504             res = ast_play_and_wait(chan, "vm-and");
06505             if (vms->oldmessages == 1) {
06506                res = ast_play_and_wait(chan, "vm-Old1");
06507             } else {
06508                if (vms->oldmessages == 2) {
06509                   res = ast_play_and_wait(chan, "vm-shtei");
06510                } else {
06511                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06512                }
06513                res = ast_play_and_wait(chan, "vm-Old");
06514             }
06515          }
06516       }
06517       if (!res && vms->oldmessages && !vms->newmessages) {
06518          if (!res) {
06519             if (vms->oldmessages == 1) {
06520                res = ast_play_and_wait(chan, "vm-Old1");
06521             } else {
06522                if (vms->oldmessages == 2) {
06523                   res = ast_play_and_wait(chan, "vm-shtei");
06524                } else {
06525                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");            
06526                }
06527                res = ast_play_and_wait(chan, "vm-Old");
06528             }
06529          }
06530       }
06531       if (!res) {
06532          if (!vms->oldmessages && !vms->newmessages) {
06533             if (!res) {
06534                res = ast_play_and_wait(chan, "vm-nomessages");
06535             }
06536          }
06537       }
06538    }
06539    return res;
06540 }

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

Definition at line 6544 of file app_voicemail.c.

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

Referenced by vm_intro().

06545 {
06546    /* Introduce messages they have */
06547    int res;
06548    if (!vms->oldmessages && !vms->newmessages)
06549       res = ast_play_and_wait(chan, "vm-no") ||
06550          ast_play_and_wait(chan, "vm-message");
06551    else
06552       res = ast_play_and_wait(chan, "vm-youhave");
06553    if (!res && vms->newmessages) {
06554       res = (vms->newmessages == 1) ?
06555          ast_play_and_wait(chan, "digits/un") ||
06556          ast_play_and_wait(chan, "vm-nuovo") ||
06557          ast_play_and_wait(chan, "vm-message") :
06558          /* 2 or more new messages */
06559          say_and_wait(chan, vms->newmessages, chan->language) ||
06560          ast_play_and_wait(chan, "vm-nuovi") ||
06561          ast_play_and_wait(chan, "vm-messages");
06562       if (!res && vms->oldmessages)
06563          res = ast_play_and_wait(chan, "vm-and");
06564    }
06565    if (!res && vms->oldmessages) {
06566       res = (vms->oldmessages == 1) ?
06567          ast_play_and_wait(chan, "digits/un") ||
06568          ast_play_and_wait(chan, "vm-vecchio") ||
06569          ast_play_and_wait(chan, "vm-message") :
06570          /* 2 or more old messages */
06571          say_and_wait(chan, vms->oldmessages, chan->language) ||
06572          ast_play_and_wait(chan, "vm-vecchi") ||
06573          ast_play_and_wait(chan, "vm-messages");
06574    }
06575    return res;
06576 }

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

Definition at line 6436 of file app_voicemail.c.

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

Referenced by vm_intro().

06437 {
06438    int res;
06439    int lastnum = 0;
06440 
06441    res = ast_play_and_wait(chan, "vm-youhave");
06442 
06443    if (!res && vms->newmessages) {
06444       lastnum = vms->newmessages;
06445 
06446       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06447          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
06448       }
06449 
06450       if (!res && vms->oldmessages) {
06451          res = ast_play_and_wait(chan, "vm-and");
06452       }
06453    }
06454 
06455    if (!res && vms->oldmessages) {
06456       lastnum = vms->oldmessages;
06457 
06458       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06459          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
06460       }
06461    }
06462 
06463    if (!res) {
06464       if (lastnum == 0) {
06465          res = ast_play_and_wait(chan, "vm-no");
06466       }
06467       if (!res) {
06468          res = ast_say_counted_noun(chan, lastnum, "vm-message");
06469       }
06470    }
06471 
06472    return res;
06473 }

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

Definition at line 6931 of file app_voicemail.c.

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

Referenced by vm_intro().

06932 {
06933    /* Introduce messages they have */
06934    int res;
06935    res = ast_play_and_wait(chan, "vm-youhave");
06936    if (!res) {
06937       if (vms->newmessages) {
06938          res = say_and_wait(chan, vms->newmessages, chan->language);
06939          if (!res) {
06940             if (vms->newmessages == 1)
06941                res = ast_play_and_wait(chan, "vm-INBOXs");
06942             else
06943                res = ast_play_and_wait(chan, "vm-INBOX");
06944          }
06945          if (vms->oldmessages && !res)
06946             res = ast_play_and_wait(chan, "vm-and");
06947          else if (!res) {
06948             if ((vms->newmessages == 1))
06949                res = ast_play_and_wait(chan, "vm-message");
06950             else
06951                res = ast_play_and_wait(chan, "vm-messages");
06952          }
06953             
06954       }
06955       if (!res && vms->oldmessages) {
06956          res = say_and_wait(chan, vms->oldmessages, chan->language);
06957          if (!res) {
06958             if (vms->oldmessages == 1)
06959                res = ast_play_and_wait(chan, "vm-Olds");
06960             else
06961                res = ast_play_and_wait(chan, "vm-Old");
06962          }
06963          if (!res) {
06964             if (vms->oldmessages == 1)
06965                res = ast_play_and_wait(chan, "vm-message");
06966             else
06967                res = ast_play_and_wait(chan, "vm-messages");
06968          }
06969       }
06970       if (!res) {
06971          if (!vms->oldmessages && !vms->newmessages) {
06972             res = ast_play_and_wait(chan, "vm-no");
06973             if (!res)
06974                res = ast_play_and_wait(chan, "vm-messages");
06975          }
06976       }
06977    }
06978    return res;
06979 }

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

Definition at line 6694 of file app_voicemail.c.

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

Referenced by vm_intro().

06695 {
06696    /* Introduce messages they have */
06697    int res;
06698 
06699    res = ast_play_and_wait(chan, "vm-youhave");
06700    if (res)
06701       return res;
06702 
06703    if (!vms->oldmessages && !vms->newmessages) {
06704       res = ast_play_and_wait(chan, "vm-no");
06705       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06706       return res;
06707    }
06708 
06709    if (vms->newmessages) {
06710       if ((vms->newmessages == 1)) {
06711          res = ast_play_and_wait(chan, "digits/1");
06712          res = res ? res : ast_play_and_wait(chan, "vm-ny");
06713          res = res ? res : ast_play_and_wait(chan, "vm-message");
06714       } else {
06715          res = say_and_wait(chan, vms->newmessages, chan->language);
06716          res = res ? res : ast_play_and_wait(chan, "vm-nye");
06717          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06718       }
06719       if (!res && vms->oldmessages)
06720          res = ast_play_and_wait(chan, "vm-and");
06721    }
06722    if (!res && vms->oldmessages) {
06723       if (vms->oldmessages == 1) {
06724          res = ast_play_and_wait(chan, "digits/1");
06725          res = res ? res : ast_play_and_wait(chan, "vm-gamel");
06726          res = res ? res : ast_play_and_wait(chan, "vm-message");
06727       } else {
06728          res = say_and_wait(chan, vms->oldmessages, chan->language);
06729          res = res ? res : ast_play_and_wait(chan, "vm-gamle");
06730          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06731       }
06732    }
06733 
06734    return res;
06735 }

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

Definition at line 6579 of file app_voicemail.c.

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

Referenced by vm_intro().

06580 {
06581    /* Introduce messages they have */
06582    int res;
06583    div_t num;
06584 
06585    if (!vms->oldmessages && !vms->newmessages) {
06586       res = ast_play_and_wait(chan, "vm-no");
06587       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06588       return res;
06589    } else {
06590       res = ast_play_and_wait(chan, "vm-youhave");
06591    }
06592 
06593    if (vms->newmessages) {
06594       num = div(vms->newmessages, 10);
06595       if (vms->newmessages == 1) {
06596          res = ast_play_and_wait(chan, "digits/1-a");
06597          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
06598          res = res ? res : ast_play_and_wait(chan, "vm-message");
06599       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06600          if (num.rem == 2) {
06601             if (!num.quot) {
06602                res = ast_play_and_wait(chan, "digits/2-ie");
06603             } else {
06604                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
06605                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06606             }
06607          } else {
06608             res = say_and_wait(chan, vms->newmessages, chan->language);
06609          }
06610          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
06611          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06612       } else {
06613          res = say_and_wait(chan, vms->newmessages, chan->language);
06614          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
06615          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06616       }
06617       if (!res && vms->oldmessages)
06618          res = ast_play_and_wait(chan, "vm-and");
06619    }
06620    if (!res && vms->oldmessages) {
06621       num = div(vms->oldmessages, 10);
06622       if (vms->oldmessages == 1) {
06623          res = ast_play_and_wait(chan, "digits/1-a");
06624          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
06625          res = res ? res : ast_play_and_wait(chan, "vm-message");
06626       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06627          if (num.rem == 2) {
06628             if (!num.quot) {
06629                res = ast_play_and_wait(chan, "digits/2-ie");
06630             } else {
06631                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
06632                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06633             }
06634          } else {
06635             res = say_and_wait(chan, vms->oldmessages, chan->language);
06636          }
06637          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
06638          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06639       } else {
06640          res = say_and_wait(chan, vms->oldmessages, chan->language);
06641          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
06642          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06643       }
06644    }
06645 
06646    return res;
06647 }

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

Definition at line 6982 of file app_voicemail.c.

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

Referenced by vm_intro().

06983 {
06984    /* Introduce messages they have */
06985    int res;
06986    res = ast_play_and_wait(chan, "vm-youhave");
06987    if (!res) {
06988       if (vms->newmessages) {
06989          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06990          if (!res) {
06991             if ((vms->newmessages == 1)) {
06992                res = ast_play_and_wait(chan, "vm-message");
06993                if (!res)
06994                   res = ast_play_and_wait(chan, "vm-INBOXs");
06995             } else {
06996                res = ast_play_and_wait(chan, "vm-messages");
06997                if (!res)
06998                   res = ast_play_and_wait(chan, "vm-INBOX");
06999             }
07000          }
07001          if (vms->oldmessages && !res)
07002             res = ast_play_and_wait(chan, "vm-and");
07003       }
07004       if (!res && vms->oldmessages) {
07005          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
07006          if (!res) {
07007             if (vms->oldmessages == 1) {
07008                res = ast_play_and_wait(chan, "vm-message");
07009                if (!res)
07010                   res = ast_play_and_wait(chan, "vm-Olds");
07011             } else {
07012                res = ast_play_and_wait(chan, "vm-messages");
07013                if (!res)
07014                   res = ast_play_and_wait(chan, "vm-Old");
07015             }
07016          }
07017       }
07018       if (!res) {
07019          if (!vms->oldmessages && !vms->newmessages) {
07020             res = ast_play_and_wait(chan, "vm-no");
07021             if (!res)
07022                res = ast_play_and_wait(chan, "vm-messages");
07023          }
07024       }
07025    }
07026    return res;
07027 }

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

Definition at line 6840 of file app_voicemail.c.

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

Referenced by vm_intro().

06840                                                                          {
06841    /* Introduce messages they have */
06842    int res;
06843    if (!vms->oldmessages && !vms->newmessages) {
06844       res = ast_play_and_wait(chan, "vm-nomessages");
06845       return res;
06846    }
06847    else {
06848       res = ast_play_and_wait(chan, "vm-youhave");
06849    }
06850    if (vms->newmessages) {
06851       if (!res)
06852          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06853       if ((vms->newmessages == 1)) {
06854          if (!res)
06855             res = ast_play_and_wait(chan, "vm-message");
06856          if (!res)
06857             res = ast_play_and_wait(chan, "vm-INBOXs");
06858       }
06859       else {
06860          if (!res)
06861             res = ast_play_and_wait(chan, "vm-messages");
06862          if (!res)
06863             res = ast_play_and_wait(chan, "vm-INBOX");
06864       }
06865       if (vms->oldmessages && !res)
06866          res = ast_play_and_wait(chan, "vm-and");
06867    }
06868    if (vms->oldmessages) {
06869       if (!res)
06870          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06871       if (vms->oldmessages == 1) {
06872          if (!res)
06873             res = ast_play_and_wait(chan, "vm-message");
06874          if (!res)
06875             res = ast_play_and_wait(chan, "vm-Olds");
06876       }
06877       else {
06878          if (!res)
06879       res = ast_play_and_wait(chan, "vm-messages");
06880          if (!res)
06881             res = ast_play_and_wait(chan, "vm-Old");
06882       }
06883    }
06884    return res;
06885 }

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

Definition at line 6650 of file app_voicemail.c.

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

Referenced by vm_intro().

06651 {
06652    /* Introduce messages they have */
06653    int res;
06654 
06655    res = ast_play_and_wait(chan, "vm-youhave");
06656    if (res)
06657       return res;
06658 
06659    if (!vms->oldmessages && !vms->newmessages) {
06660       res = ast_play_and_wait(chan, "vm-no");
06661       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06662       return res;
06663    }
06664 
06665    if (vms->newmessages) {
06666       if ((vms->newmessages == 1)) {
06667          res = ast_play_and_wait(chan, "digits/ett");
06668          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
06669          res = res ? res : ast_play_and_wait(chan, "vm-message");
06670       } else {
06671          res = say_and_wait(chan, vms->newmessages, chan->language);
06672          res = res ? res : ast_play_and_wait(chan, "vm-nya");
06673          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06674       }
06675       if (!res && vms->oldmessages)
06676          res = ast_play_and_wait(chan, "vm-and");
06677    }
06678    if (!res && vms->oldmessages) {
06679       if (vms->oldmessages == 1) {
06680          res = ast_play_and_wait(chan, "digits/ett");
06681          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
06682          res = res ? res : ast_play_and_wait(chan, "vm-message");
06683       } else {
06684          res = say_and_wait(chan, vms->oldmessages, chan->language);
06685          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
06686          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06687       }
06688    }
06689 
06690    return res;
06691 }

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

Definition at line 2357 of file app_voicemail.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

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

02358 {
02359    switch (ast_lock_path(path)) {
02360    case AST_LOCK_TIMEOUT:
02361       return -1;
02362    default:
02363       return 0;
02364    }
02365 }

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

Definition at line 1006 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

01007 {
01008    FILE *p = NULL;
01009    int pfd = mkstemp(template);
01010    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
01011    if (pfd > -1) {
01012       p = fdopen(pfd, "w+");
01013       if (!p) {
01014          close(pfd);
01015          pfd = -1;
01016       }
01017    }
01018    return p;
01019 }

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

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

Referenced by vm_execmain().

07213 {
07214    int cmd = 0;
07215    int duration = 0;
07216    int tries = 0;
07217    char newpassword[80] = "";
07218    char newpassword2[80] = "";
07219    char prefile[PATH_MAX] = "";
07220    unsigned char buf[256];
07221    int bytes=0;
07222 
07223    if (ast_adsi_available(chan)) {
07224       bytes += adsi_logo(buf + bytes);
07225       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
07226       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07227       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07228       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07229       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07230    }
07231 
07232    /* First, have the user change their password 
07233       so they won't get here again */
07234    for (;;) {
07235       newpassword[1] = '\0';
07236       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
07237       if (cmd == '#')
07238          newpassword[0] = '\0';
07239       if (cmd < 0 || cmd == 't' || cmd == '#')
07240          return cmd;
07241       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
07242       if (cmd < 0 || cmd == 't' || cmd == '#')
07243          return cmd;
07244       newpassword2[1] = '\0';
07245       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
07246       if (cmd == '#')
07247          newpassword2[0] = '\0';
07248       if (cmd < 0 || cmd == 't' || cmd == '#')
07249          return cmd;
07250       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
07251       if (cmd < 0 || cmd == 't' || cmd == '#')
07252          return cmd;
07253       if (!strcmp(newpassword, newpassword2))
07254          break;
07255       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
07256       cmd = ast_play_and_wait(chan, "vm-mismatch");
07257       if (++tries == 3)
07258          return -1;
07259       if (cmd == 0) {
07260          cmd = ast_play_and_wait(chan, "vm-pls-try-again");
07261       }
07262    }
07263    if (ast_strlen_zero(ext_pass_cmd)) 
07264       vm_change_password(vmu,newpassword);
07265    else 
07266       vm_change_password_shell(vmu,newpassword);
07267    if (option_debug > 2)
07268       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
07269    cmd = ast_play_and_wait(chan,"vm-passchanged");
07270 
07271    /* If forcename is set, have the user record their name */  
07272    if (ast_test_flag(vmu, VM_FORCENAME)) {
07273       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
07274       if (ast_fileexists(prefile, NULL, NULL) < 1) {
07275          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07276          if (cmd < 0 || cmd == 't' || cmd == '#')
07277             return cmd;
07278       }
07279    }
07280 
07281    /* If forcegreetings is set, have the user record their greetings */
07282    if (ast_test_flag(vmu, VM_FORCEGREET)) {
07283       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
07284       if (ast_fileexists(prefile, NULL, NULL) < 1) {
07285          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07286          if (cmd < 0 || cmd == 't' || cmd == '#')
07287             return cmd;
07288       }
07289 
07290       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
07291       if (ast_fileexists(prefile, NULL, NULL) < 1) {
07292          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07293          if (cmd < 0 || cmd == 't' || cmd == '#')
07294             return cmd;
07295       }
07296    }
07297 
07298    return cmd;
07299 }

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

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

Referenced by vm_execmain().

07302 {
07303    int cmd = 0;
07304    int retries = 0;
07305    int duration = 0;
07306    char newpassword[80] = "";
07307    char newpassword2[80] = "";
07308    char prefile[PATH_MAX] = "";
07309    unsigned char buf[256];
07310    int bytes=0;
07311 
07312    if (ast_adsi_available(chan))
07313    {
07314       bytes += adsi_logo(buf + bytes);
07315       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
07316       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07317       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07318       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07319       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07320    }
07321    while ((cmd >= 0) && (cmd != 't')) {
07322       if (cmd)
07323          retries = 0;
07324       switch (cmd) {
07325       case '1':
07326          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
07327          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07328          break;
07329       case '2': 
07330          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
07331          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07332          break;
07333       case '3': 
07334          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
07335          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07336          break;
07337       case '4': 
07338          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
07339          break;
07340       case '5':
07341          if (vmu->password[0] == '-') {
07342             cmd = ast_play_and_wait(chan, "vm-no");
07343             break;
07344          }
07345          newpassword[1] = '\0';
07346          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
07347          if (cmd == '#')
07348             newpassword[0] = '\0';
07349          else {
07350             if (cmd < 0)
07351                break;
07352             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
07353                break;
07354             }
07355          }
07356          newpassword2[1] = '\0';
07357          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
07358          if (cmd == '#')
07359             newpassword2[0] = '\0';
07360          else {
07361             if (cmd < 0)
07362                break;
07363 
07364             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) {
07365                break;
07366             }
07367          }
07368          if (strcmp(newpassword, newpassword2)) {
07369             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
07370             cmd = ast_play_and_wait(chan, "vm-mismatch");
07371             if (!cmd) {
07372                cmd = ast_play_and_wait(chan, "vm-pls-try-again");
07373             }
07374             break;
07375          }
07376          if (ast_strlen_zero(ext_pass_cmd)) 
07377             vm_change_password(vmu,newpassword);
07378          else 
07379             vm_change_password_shell(vmu,newpassword);
07380          if (option_debug > 2)
07381             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
07382          cmd = ast_play_and_wait(chan,"vm-passchanged");
07383          break;
07384       case '*': 
07385          cmd = 't';
07386          break;
07387       default: 
07388          cmd = 0;
07389          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07390          RETRIEVE(prefile, -1, vmu);
07391          if (ast_fileexists(prefile, NULL, NULL))
07392             cmd = ast_play_and_wait(chan, "vm-tmpexists");
07393          DISPOSE(prefile, -1);
07394          if (!cmd)
07395             cmd = ast_play_and_wait(chan, "vm-options");
07396          if (!cmd)
07397             cmd = ast_waitfordigit(chan,6000);
07398          if (!cmd)
07399             retries++;
07400          if (retries > 3)
07401             cmd = 't';
07402       }
07403    }
07404    if (cmd == 't')
07405       cmd = 0;
07406    return cmd;
07407 }

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

Definition at line 6262 of file app_voicemail.c.

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

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

06263 {
06264    int cmd;
06265 
06266    if (  !strncasecmp(chan->language, "it", 2) ||
06267         !strncasecmp(chan->language, "es", 2) ||
06268         !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */
06269       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
06270       return cmd ? cmd : ast_play_and_wait(chan, mbox);
06271    } else if (!strncasecmp(chan->language, "gr", 2)) {
06272       return vm_play_folder_name_gr(chan, mbox);
06273    } else if (!strncasecmp(chan->language, "pl", 2)) {
06274       return vm_play_folder_name_pl(chan, mbox);
06275    } else if (!strncasecmp(chan->language, "ua", 2)) {  /* Ukrainian syntax */
06276       return vm_play_folder_name_ua(chan, mbox);
06277    } else if (!strncasecmp(chan->language, "he", 2)) {  /* Hebrew syntax */
06278       cmd = ast_play_and_wait(chan, mbox);
06279       return cmd;
06280    } else {  /* Default English */
06281       cmd = ast_play_and_wait(chan, mbox);
06282       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
06283    }
06284 }

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

Definition at line 6215 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

06216 {
06217    int cmd;
06218    char *buf;
06219 
06220    buf = alloca(strlen(mbox)+2); 
06221    strcpy(buf, mbox);
06222    strcat(buf,"s");
06223 
06224    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
06225       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
06226       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
06227    } else {
06228       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
06229       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
06230    }
06231 }

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

Definition at line 6233 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

06234 {
06235    int cmd;
06236 
06237    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
06238       if (!strcasecmp(mbox, "vm-INBOX"))
06239          cmd = ast_play_and_wait(chan, "vm-new-e");
06240       else
06241          cmd = ast_play_and_wait(chan, "vm-old-e");
06242       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
06243    } else {
06244       cmd = ast_play_and_wait(chan, "vm-messages");
06245       return cmd ? cmd : ast_play_and_wait(chan, mbox);
06246    }
06247 }

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

Definition at line 6249 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

06250 {
06251    int cmd;
06252 
06253    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
06254       cmd = ast_play_and_wait(chan, "vm-messages");
06255       return cmd ? cmd : ast_play_and_wait(chan, mbox);
06256    } else {
06257       cmd = ast_play_and_wait(chan, mbox);
06258       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
06259    }
06260 }

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

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

Referenced by vm_options().

07410 {
07411    int res;
07412    int cmd = 0;
07413    int retries = 0;
07414    int duration = 0;
07415    char prefile[PATH_MAX] = "";
07416    unsigned char buf[256];
07417    char dest[PATH_MAX];
07418    int bytes = 0;
07419 
07420    if (ast_adsi_available(chan)) {
07421       bytes += adsi_logo(buf + bytes);
07422       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
07423       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07424       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07425       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07426       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07427    }
07428 
07429    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07430    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
07431       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
07432       return -1;
07433    }
07434    while ((cmd >= 0) && (cmd != 't')) {
07435       if (cmd)
07436          retries = 0;
07437       RETRIEVE(prefile, -1, vmu);
07438       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
07439          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07440          cmd = 't';  
07441       } else {
07442          switch (cmd) {
07443          case '1':
07444             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07445             break;
07446          case '2':
07447             DELETE(prefile, -1, prefile, vmu);
07448             ast_play_and_wait(chan, "vm-tempremoved");
07449             cmd = 't';  
07450             break;
07451          case '*': 
07452             cmd = 't';
07453             break;
07454          default:
07455             cmd = ast_play_and_wait(chan,
07456                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
07457                   "vm-tempgreeting2" : "vm-tempgreeting");
07458             if (!cmd)
07459                cmd = ast_waitfordigit(chan,6000);
07460             if (!cmd)
07461                retries++;
07462             if (retries > 3)
07463                cmd = 't';
07464          }
07465       }
07466       DISPOSE(prefile, -1);
07467    }
07468    if (cmd == 't')
07469       cmd = 0;
07470    return cmd;
07471 }

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

Definition at line 8434 of file app_voicemail.c.

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

Referenced by load_module().

08435 {
08436    struct ast_module_user *u;
08437    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
08438    struct ast_vm_user vmus;
08439    char *options = NULL;
08440    int silent = 0, skipuser = 0;
08441    int res = -1;
08442 
08443    u = ast_module_user_add(chan);
08444    
08445    if (s) {
08446       s = ast_strdupa(s);
08447       user = strsep(&s, "|");
08448       options = strsep(&s, "|");
08449       if (user) {
08450          s = user;
08451          user = strsep(&s, "@");
08452          context = strsep(&s, "");
08453          if (!ast_strlen_zero(user))
08454             skipuser++;
08455          ast_copy_string(mailbox, user, sizeof(mailbox));
08456       }
08457    }
08458 
08459    if (options) {
08460       silent = (strchr(options, 's')) != NULL;
08461    }
08462 
08463    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
08464       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
08465       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
08466       ast_play_and_wait(chan, "auth-thankyou");
08467       res = 0;
08468    }
08469 
08470    ast_module_user_remove(u);
08471    return res;
08472 }

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

Definition at line 3322 of file app_voicemail.c.

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

Referenced by make_email_file(), and sendpage().

03323 {
03324    const struct vm_zone *z = NULL;
03325    time_t t = time(NULL);
03326 
03327    /* Does this user have a timezone specified? */
03328    if (!ast_strlen_zero(vmu->zonetag)) {
03329       /* Find the zone in the list */
03330       AST_LIST_LOCK(&zones);
03331       AST_LIST_TRAVERSE(&zones, z, list) {
03332          if (!strcmp(z->name, vmu->zonetag))
03333             break;
03334       }
03335       AST_LIST_UNLOCK(&zones);
03336    }
03337    ast_localtime(&t, tm, z ? z->timezone : NULL);
03338    return tm;
03339 }

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

Definition at line 5739 of file app_voicemail.c.

References ast_control_streamfile().

05740 {
05741    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05742 }

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

Definition at line 5731 of file app_voicemail.c.

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

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

05732 {
05733    int res;
05734    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05735       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05736    return res;
05737 }


Variable Documentation

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

Definition at line 9744 of file app_voicemail.c.

char* addesc = "Comedian Mail" [static]

Definition at line 519 of file app_voicemail.c.

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

Definition at line 643 of file app_voicemail.c.

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

Definition at line 644 of file app_voicemail.c.

int adsiver = 1 [static]

Definition at line 645 of file app_voicemail.c.

char* app = "VoiceMail" [static]

Definition at line 595 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 598 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 600 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 601 of file app_voicemail.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 9744 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 628 of file app_voicemail.c.

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

Definition at line 641 of file app_voicemail.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 631 of file app_voicemail.c.

struct ast_cli_entry cli_show_voicemail_users_deprecated [static]

Initial value:

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

Definition at line 8576 of file app_voicemail.c.

struct ast_cli_entry cli_show_voicemail_zones_deprecated [static]

Initial value:

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

Definition at line 8581 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 8586 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 524 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 570 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 552 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 584 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 627 of file app_voicemail.c.

Referenced by directory_exec().

char* emailbody = NULL [static]

Definition at line 634 of file app_voicemail.c.

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

Definition at line 646 of file app_voicemail.c.

char* emailsubject = NULL [static]

Definition at line 635 of file app_voicemail.c.

char emailtitle[100] [static]

Definition at line 640 of file app_voicemail.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 629 of file app_voicemail.c.

Referenced by conf_run().

char ext_pass_cmd[128] [static]

Definition at line 505 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 613 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 638 of file app_voicemail.c.

struct ast_flags globalflags = {0} [static]

Definition at line 623 of file app_voicemail.c.

struct ao2_container* inprocess_container

Definition at line 420 of file app_voicemail.c.

Referenced by inprocess_count(), load_module(), and unload_module().

char mailcmd[160] [static]

Definition at line 610 of file app_voicemail.c.

int maxgreet [static]

Definition at line 619 of file app_voicemail.c.

int maxlogins [static]

Definition at line 621 of file app_voicemail.c.

int maxmsg [static]

Definition at line 607 of file app_voicemail.c.

int maxsilence [static]

Definition at line 606 of file app_voicemail.c.

Referenced by ast_record_review().

int my_umask [static]

Definition at line 507 of file app_voicemail.c.

char* pagerbody = NULL [static]

Definition at line 636 of file app_voicemail.c.

char pagerfromstring[100] [static]

Definition at line 639 of file app_voicemail.c.

char* pagersubject = NULL [static]

Definition at line 637 of file app_voicemail.c.

char preprocesscmd[160] [static]

Definition at line 611 of file app_voicemail.c.

char preprocessfmt[20] [static]

Definition at line 612 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 625 of file app_voicemail.c.

char serveremail[80] [static]

Definition at line 609 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 608 of file app_voicemail.c.

int skipms [static]

Definition at line 620 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

struct ast_smdi_interface* smdi_iface = NULL [static]

Definition at line 614 of file app_voicemail.c.

Referenced by load_config(), and run_externnotify().

char* synopsis_vm [static]

Initial value:

"Leave a Voicemail message"

Definition at line 521 of file app_voicemail.c.

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 567 of file app_voicemail.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 549 of file app_voicemail.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 581 of file app_voicemail.c.

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

Definition at line 517 of file app_voicemail.c.

Referenced by pbx_load_users().

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

Definition at line 243 of file app_voicemail.c.

Referenced by vm_exec(), and vm_execmain().

enum { ... } vm_option_args

enum { ... } vm_option_flags

char VM_SPOOL_DIR[PATH_MAX] [static]

Definition at line 503 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 615 of file app_voicemail.c.

int vmmaxmessage [static]

Definition at line 618 of file app_voicemail.c.

int vmminmessage [static]

Definition at line 617 of file app_voicemail.c.

char voicemail_show_users_help[] [static]

Initial value:

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

Definition at line 8474 of file app_voicemail.c.

char voicemail_show_zones_help[] [static]

Initial value:

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

Definition at line 8478 of file app_voicemail.c.

double volgain [static]

Definition at line 616 of file app_voicemail.c.

char zonetag[80] [static]

Definition at line 605 of file app_voicemail.c.

Referenced by build_peer().


Generated on Sat Aug 6 00:39:38 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7