Fri Feb 19 17:12:53 2010

Asterisk developer's documentation


app_voicemail.c File Reference

Comedian Mail - Voicemail System. More...

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

Go to the source code of this file.

Data Structures

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

Enumerations

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

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
static void __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 flag, signed char record_gain)
static void free_user (struct ast_vm_user *vmu)
static void free_vm_users (void)
static void free_zone (struct vm_zone *z)
static int get_date (char *s, int len)
static int get_folder (struct ast_channel *chan, int start)
static int get_folder2 (struct ast_channel *chan, char *fn, int start)
static int handle_voicemail_show_users (int fd, int argc, char *argv[])
static int handle_voicemail_show_zones (int fd, int argc, char *argv[])
static int has_voicemail (const char *mailbox, const char *folder)
static int inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs)
static int inbuf (struct baseio *bio, FILE *fi)
static int inchar (struct baseio *bio, FILE *fi)
static int invent_message (struct ast_channel *chan, struct ast_vm_user *vmu, char *ext, int busy, char *ecodes)
static int last_message_index (struct ast_vm_user *vmu, char *dir)
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
static int load_config (void)
static int load_module (void)
static int make_dir (char *dest, int len, const char *context, const char *ext, const char *folder)
static void make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, 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)
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_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}
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 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 169 of file app_voicemail.c.

Referenced by load_config().

#define BASELINELEN   72

Definition at line 185 of file app_voicemail.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 186 of file app_voicemail.c.

#define BASEMAXINLINE   256

Definition at line 186 of file app_voicemail.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 166 of file app_voicemail.c.

#define COMMAND_TIMEOUT   5000

Definition at line 162 of file app_voicemail.c.

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

Definition at line 436 of file app_voicemail.c.

Referenced by copy_message().

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

Definition at line 437 of file app_voicemail.c.

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

#define DISPOSE ( a,
 ) 

Definition at line 432 of file app_voicemail.c.

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

#define ENDL   "\n"

Referenced by make_email_file().

#define eol   "\r\n"

Definition at line 187 of file app_voicemail.c.

Referenced by base_encode(), and ochar().

#define ERROR_LOCK_PATH   -100

Definition at line 208 of file app_voicemail.c.

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

#define ERROR_MAILBOX_FULL   -200

Definition at line 209 of file app_voicemail.c.

Referenced by save_to_folder().

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

Definition at line 434 of file app_voicemail.c.

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

#define INTRO   "vm-intro"

Definition at line 175 of file app_voicemail.c.

Referenced by leave_voicemail(), and play_record_review().

#define MAX_DATETIME_FORMAT   512

Definition at line 189 of file app_voicemail.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 190 of file app_voicemail.c.

Referenced by load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 177 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

#define MAXMSGLIMIT   9999

Definition at line 179 of file app_voicemail.c.

Referenced by apply_option(), and load_config().

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

Definition at line 435 of file app_voicemail.c.

Referenced by close_mailbox(), and resequence_mailbox().

#define RETRIEVE ( a,
b,
 ) 

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

Referenced by load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000

Definition at line 160 of file app_voicemail.c.

Referenced by run_externnotify().

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

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

#define VM_ALLOCED   (1 << 13)

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

Referenced by apply_option(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

directory_forward

Definition at line 202 of file app_voicemail.c.

Referenced by forward_message(), and load_config().

#define VM_ENVELOPE   (1 << 4)

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

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

#define VM_OPERATOR   (1 << 1)

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

Referenced by load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

Definition at line 192 of file app_voicemail.c.

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

#define VM_SAYCID   (1 << 2)

Definition at line 194 of file app_voicemail.c.

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

#define VM_SAYDURATION   (1 << 5)

Definition at line 197 of file app_voicemail.c.

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

#define VM_SEARCH   (1 << 14)

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

Referenced by load_config(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

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

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

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 168 of file app_voicemail.c.

#define VOICEMAIL_DIR_MODE   0777

Definition at line 164 of file app_voicemail.c.

Referenced by create_dirpath().

#define VOICEMAIL_FILE_MODE   0666

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

00212      {
00213    OPT_SILENT =           (1 << 0),
00214    OPT_BUSY_GREETING =    (1 << 1),
00215    OPT_UNAVAIL_GREETING = (1 << 2),
00216    OPT_RECORDGAIN =       (1 << 3),
00217    OPT_PREPEND_MAILBOX =  (1 << 4),
00218    OPT_PRIORITY_JUMP =    (1 << 5),
00219    OPT_AUTOPLAY =         (1 << 6),
00220 } vm_option_flags;

anonymous enum

Enumerator:
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_ARRAY_SIZE 

Definition at line 222 of file app_voicemail.c.

00222      {
00223    OPT_ARG_RECORDGAIN = 0,
00224    OPT_ARG_PLAYFOLDER = 1,
00225    /* This *must* be the last value in this enum! */
00226    OPT_ARG_ARRAY_SIZE = 2,
00227 } vm_option_args;


Function Documentation

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

Definition at line 3843 of file app_voicemail.c.

References ast_strlen_zero().

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

03844 {
03845    DIR *dir;
03846    struct dirent *de;
03847    char fn[256];
03848    int ret = 0;
03849    if (!folder)
03850       folder = "INBOX";
03851    /* If no mailbox, return immediately */
03852    if (ast_strlen_zero(mailbox))
03853       return 0;
03854    if (!context)
03855       context = "default";
03856    snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
03857    dir = opendir(fn);
03858    if (!dir)
03859       return 0;
03860    while ((de = readdir(dir))) {
03861       if (!strncasecmp(de->d_name, "msg", 3)) {
03862          if (shortcircuit) {
03863             ret = 1;
03864             break;
03865          } else if (!strncasecmp(de->d_name + 8, "txt", 3))
03866             ret++;
03867       }
03868    }
03869    closedir(dir);
03870    return ret;
03871 }

static void __reg_module ( void   )  [static]

Definition at line 9361 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 9361 of file app_voicemail.c.

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

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

04603 {
04604    int x;
04605    if (!ast_adsi_available(chan))
04606       return;
04607    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04608    if (x < 0)
04609       return;
04610    if (!x) {
04611       if (adsi_load_vmail(chan, useadsi)) {
04612          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04613          return;
04614       }
04615    } else
04616       *useadsi = 1;
04617 }

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

Definition at line 4791 of file app_voicemail.c.

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

Referenced by vm_execmain().

04792 {
04793    int bytes=0;
04794    unsigned char buf[256];
04795    unsigned char keys[8];
04796 
04797    int x;
04798 
04799    if (!ast_adsi_available(chan))
04800       return;
04801 
04802    /* New meaning for keys */
04803    for (x=0;x<5;x++)
04804       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04805 
04806    keys[6] = 0x0;
04807    keys[7] = 0x0;
04808 
04809    if (!vms->curmsg) {
04810       /* No prev key, provide "Folder" instead */
04811       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04812    }
04813    if (vms->curmsg >= vms->lastmsg) {
04814       /* If last message ... */
04815       if (vms->curmsg) {
04816          /* but not only message, provide "Folder" instead */
04817          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04818       } else {
04819          /* Otherwise if only message, leave blank */
04820          keys[3] = 1;
04821       }
04822    }
04823 
04824    /* If deleted, show "undeleted" */
04825    if (vms->deleted[vms->curmsg]) 
04826       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04827 
04828    /* Except "Exit" */
04829    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04830    bytes += ast_adsi_set_keys(buf + bytes, keys);
04831    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04832 
04833    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04834 }

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

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

04668 {
04669    unsigned char buf[256];
04670    int bytes=0;
04671    unsigned char keys[8];
04672    int x,y;
04673 
04674    if (!ast_adsi_available(chan))
04675       return;
04676 
04677    for (x=0;x<5;x++) {
04678       y = ADSI_KEY_APPS + 12 + start + x;
04679       if (y > ADSI_KEY_APPS + 12 + 4)
04680          y = 0;
04681       keys[x] = ADSI_KEY_SKT | y;
04682    }
04683    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
04684    keys[6] = 0;
04685    keys[7] = 0;
04686 
04687    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
04688    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
04689    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04690    bytes += ast_adsi_set_keys(buf + bytes, keys);
04691    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04692 
04693    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04694 }

static void adsi_goodbye ( struct ast_channel chan  )  [static]

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

04940 {
04941    unsigned char buf[256];
04942    int bytes=0;
04943 
04944    if (!ast_adsi_available(chan))
04945       return;
04946    bytes += adsi_logo(buf + bytes);
04947    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
04948    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
04949    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04950    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04951 
04952    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04953 }

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

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

04472 {
04473    unsigned char buf[256];
04474    int bytes=0;
04475    int x;
04476    char num[5];
04477 
04478    *useadsi = 0;
04479    bytes += ast_adsi_data_mode(buf + bytes);
04480    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04481 
04482    bytes = 0;
04483    bytes += adsi_logo(buf);
04484    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04485 #ifdef DISPLAY
04486    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .", "");
04487 #endif
04488    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04489    bytes += ast_adsi_data_mode(buf + bytes);
04490    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04491 
04492    if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) {
04493       bytes = 0;
04494       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
04495       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04496       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04497       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04498       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04499       return 0;
04500    }
04501 
04502 #ifdef DISPLAY
04503    /* Add a dot */
04504    bytes = 0;
04505    bytes += ast_adsi_logo(buf);
04506    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
04507    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ..", "");
04508    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04509    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04510 #endif
04511    bytes = 0;
04512    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
04513    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
04514    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
04515    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
04516    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
04517    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
04518    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04519 
04520 #ifdef DISPLAY
04521    /* Add another dot */
04522    bytes = 0;
04523    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ...", "");
04524    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04525 
04526    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04527    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04528 #endif
04529 
04530    bytes = 0;
04531    /* These buttons we load but don't use yet */
04532    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
04533    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
04534    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
04535    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
04536    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
04537    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
04538    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04539 
04540 #ifdef DISPLAY
04541    /* Add another dot */
04542    bytes = 0;
04543    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   ....", "");
04544    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04545    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04546 #endif
04547 
04548    bytes = 0;
04549    for (x=0;x<5;x++) {
04550       snprintf(num, sizeof(num), "%d", x);
04551       bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1);
04552    }
04553    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
04554    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04555 
04556 #ifdef DISPLAY
04557    /* Add another dot */
04558    bytes = 0;
04559    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, "   .....", "");
04560    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04561    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04562 #endif
04563 
04564    if (ast_adsi_end_download(chan)) {
04565       bytes = 0;
04566       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
04567       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
04568       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04569       bytes += ast_adsi_voice_mode(buf + bytes, 0);
04570       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04571       return 0;
04572    }
04573    bytes = 0;
04574    bytes += ast_adsi_download_disconnect(buf + bytes);
04575    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04576    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
04577 
04578    if (option_debug)
04579       ast_log(LOG_DEBUG, "Done downloading scripts...\n");
04580 
04581 #ifdef DISPLAY
04582    /* Add last dot */
04583    bytes = 0;
04584    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "   ......", "");
04585    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04586 #endif
04587    if (option_debug)
04588       ast_log(LOG_DEBUG, "Restarting session...\n");
04589 
04590    bytes = 0;
04591    /* Load the session now */
04592    if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
04593       *useadsi = 1;
04594       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
04595    } else
04596       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
04597 
04598    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04599    return 0;
04600 }

static void adsi_login ( struct ast_channel chan  )  [static]

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

04620 {
04621    unsigned char buf[256];
04622    int bytes=0;
04623    unsigned char keys[8];
04624    int x;
04625    if (!ast_adsi_available(chan))
04626       return;
04627 
04628    for (x=0;x<8;x++)
04629       keys[x] = 0;
04630    /* Set one key for next */
04631    keys[3] = ADSI_KEY_APPS + 3;
04632 
04633    bytes += adsi_logo(buf + bytes);
04634    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
04635    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
04636    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04637    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
04638    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
04639    bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
04640    bytes += ast_adsi_set_keys(buf + bytes, keys);
04641    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04642    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04643 }

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

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

04464 {
04465    int bytes = 0;
04466    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04467    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04468    return bytes;
04469 }

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

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

04697 {
04698    int bytes=0;
04699    unsigned char buf[256]; 
04700    char buf1[256], buf2[256];
04701    char fn2[PATH_MAX];
04702 
04703    char cid[256]="";
04704    char *val;
04705    char *name, *num;
04706    char datetime[21]="";
04707    FILE *f;
04708 
04709    unsigned char keys[8];
04710 
04711    int x;
04712 
04713    if (!ast_adsi_available(chan))
04714       return;
04715 
04716    /* Retrieve important info */
04717    snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
04718    f = fopen(fn2, "r");
04719    if (f) {
04720       while (!feof(f)) {   
04721          if (!fgets((char *)buf, sizeof(buf), f)) {
04722             continue;
04723          }
04724          if (!feof(f)) {
04725             char *stringp=NULL;
04726             stringp = (char *)buf;
04727             strsep(&stringp, "=");
04728             val = strsep(&stringp, "=");
04729             if (!ast_strlen_zero(val)) {
04730                if (!strcmp((char *)buf, "callerid"))
04731                   ast_copy_string(cid, val, sizeof(cid));
04732                if (!strcmp((char *)buf, "origdate"))
04733                   ast_copy_string(datetime, val, sizeof(datetime));
04734             }
04735          }
04736       }
04737       fclose(f);
04738    }
04739    /* New meaning for keys */
04740    for (x=0;x<5;x++)
04741       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
04742    keys[6] = 0x0;
04743    keys[7] = 0x0;
04744 
04745    if (!vms->curmsg) {
04746       /* No prev key, provide "Folder" instead */
04747       keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04748    }
04749    if (vms->curmsg >= vms->lastmsg) {
04750       /* If last message ... */
04751       if (vms->curmsg) {
04752          /* but not only message, provide "Folder" instead */
04753          keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
04754          bytes += ast_adsi_voice_mode(buf + bytes, 0);
04755 
04756       } else {
04757          /* Otherwise if only message, leave blank */
04758          keys[3] = 1;
04759       }
04760    }
04761 
04762    if (!ast_strlen_zero(cid)) {
04763       ast_callerid_parse(cid, &name, &num);
04764       if (!name)
04765          name = num;
04766    } else
04767       name = "Unknown Caller";
04768 
04769    /* If deleted, show "undeleted" */
04770 
04771    if (vms->deleted[vms->curmsg])
04772       keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
04773 
04774    /* Except "Exit" */
04775    keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
04776    snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
04777       strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
04778    snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
04779 
04780    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04781    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04782    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
04783    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
04784    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04785    bytes += ast_adsi_set_keys(buf + bytes, keys);
04786    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04787 
04788    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04789 }

static void adsi_password ( struct ast_channel chan  )  [static]

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

04646 {
04647    unsigned char buf[256];
04648    int bytes=0;
04649    unsigned char keys[8];
04650    int x;
04651    if (!ast_adsi_available(chan))
04652       return;
04653 
04654    for (x=0;x<8;x++)
04655       keys[x] = 0;
04656    /* Set one key for next */
04657    keys[3] = ADSI_KEY_APPS + 3;
04658 
04659    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04660    bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
04661    bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
04662    bytes += ast_adsi_set_keys(buf + bytes, keys);
04663    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04664    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04665 }

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

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

04837 {
04838    unsigned char buf[256] = "";
04839    char buf1[256] = "", buf2[256] = "";
04840    int bytes=0;
04841    unsigned char keys[8];
04842    int x;
04843 
04844    char *newm = (vms->newmessages == 1) ? "message" : "messages";
04845    char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
04846    if (!ast_adsi_available(chan))
04847       return;
04848    if (vms->newmessages) {
04849       snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
04850       if (vms->oldmessages) {
04851          strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
04852          snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
04853       } else {
04854          snprintf(buf2, sizeof(buf2), "%s.", newm);
04855       }
04856    } else if (vms->oldmessages) {
04857       snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
04858       snprintf(buf2, sizeof(buf2), "%s.", oldm);
04859    } else {
04860       strcpy(buf1, "You have no messages.");
04861       buf2[0] = ' ';
04862       buf2[1] = '\0';
04863    }
04864    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04865    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04866    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04867 
04868    for (x=0;x<6;x++)
04869       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04870    keys[6] = 0;
04871    keys[7] = 0;
04872 
04873    /* Don't let them listen if there are none */
04874    if (vms->lastmsg < 0)
04875       keys[0] = 1;
04876    bytes += ast_adsi_set_keys(buf + bytes, keys);
04877 
04878    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04879 
04880    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04881 }

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

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

04884 {
04885    unsigned char buf[256] = "";
04886    char buf1[256] = "", buf2[256] = "";
04887    int bytes=0;
04888    unsigned char keys[8];
04889    int x;
04890 
04891    char *mess = (vms->lastmsg == 0) ? "message" : "messages";
04892 
04893    if (!ast_adsi_available(chan))
04894       return;
04895 
04896    /* Original command keys */
04897    for (x=0;x<6;x++)
04898       keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
04899 
04900    keys[6] = 0;
04901    keys[7] = 0;
04902 
04903    if ((vms->lastmsg + 1) < 1)
04904       keys[0] = 0;
04905 
04906    snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
04907       strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
04908 
04909    if (vms->lastmsg + 1)
04910       snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
04911    else
04912       strcpy(buf2, "no messages.");
04913    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
04914    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
04915    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
04916    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04917    bytes += ast_adsi_set_keys(buf + bytes, keys);
04918 
04919    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04920 
04921    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04922    
04923 }

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

08959 {
08960    int res = 0;
08961    char filename[PATH_MAX];
08962    struct ast_config *msg_cfg = NULL;
08963    const char *origtime, *context;
08964    char *cid, *name, *num;
08965    int retries = 0;
08966 
08967    vms->starting = 0; 
08968    make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
08969 
08970    /* Retrieve info from VM attribute file */
08971    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
08972    snprintf(filename,sizeof(filename), "%s.txt", vms->fn2);
08973    RETRIEVE(vms->curdir, vms->curmsg, vmu);
08974    msg_cfg = ast_config_load(filename);
08975    DISPOSE(vms->curdir, vms->curmsg);
08976    if (!msg_cfg) {
08977       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
08978       return 0;
08979    }
08980 
08981    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
08982       ast_config_destroy(msg_cfg);
08983       return 0;
08984    }
08985 
08986    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
08987 
08988    context = ast_variable_retrieve(msg_cfg, "message", "context");
08989    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
08990       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
08991    switch (option) {
08992    case 3:
08993       if (!res)
08994          res = play_message_datetime(chan, vmu, origtime, filename);
08995       if (!res)
08996          res = play_message_callerid(chan, vms, cid, context, 0);
08997 
08998       res = 't';
08999       break;
09000 
09001    case 2:  /* Call back */
09002 
09003       if (ast_strlen_zero(cid))
09004          break;
09005 
09006       ast_callerid_parse(cid, &name, &num);
09007       while ((res > -1) && (res != 't')) {
09008          switch (res) {
09009          case '1':
09010             if (num) {
09011                /* Dial the CID number */
09012                res = dialout(chan, vmu, num, vmu->callback);
09013                if (res) {
09014                   ast_config_destroy(msg_cfg);
09015                   return 9;
09016                }
09017             } else {
09018                res = '2';
09019             }
09020             break;
09021 
09022          case '2':
09023             /* Want to enter a different number, can only do this if there's a dialout context for this user */
09024             if (!ast_strlen_zero(vmu->dialout)) {
09025                res = dialout(chan, vmu, NULL, vmu->dialout);
09026                if (res) {
09027                   ast_config_destroy(msg_cfg);
09028                   return 9;
09029                }
09030             } else {
09031                if (option_verbose > 2)
09032                   ast_verbose( VERBOSE_PREFIX_3 "Caller can not specify callback number - no dialout context available\n");
09033                res = ast_play_and_wait(chan, "vm-sorry");
09034             }
09035             ast_config_destroy(msg_cfg);
09036             return res;
09037          case '*':
09038             res = 't';
09039             break;
09040          case '3':
09041          case '4':
09042          case '5':
09043          case '6':
09044          case '7':
09045          case '8':
09046          case '9':
09047          case '0':
09048 
09049             res = ast_play_and_wait(chan, "vm-sorry");
09050             retries++;
09051             break;
09052          default:
09053             if (num) {
09054                if (option_verbose > 2)
09055                   ast_verbose( VERBOSE_PREFIX_3 "Confirm CID number '%s' is number to use for callback\n", num);
09056                res = ast_play_and_wait(chan, "vm-num-i-have");
09057                if (!res)
09058                   res = play_message_callerid(chan, vms, num, vmu->context, 1);
09059                if (!res)
09060                   res = ast_play_and_wait(chan, "vm-tocallnum");
09061                /* Only prompt for a caller-specified number if there is a dialout context specified */
09062                if (!ast_strlen_zero(vmu->dialout)) {
09063                   if (!res)
09064                      res = ast_play_and_wait(chan, "vm-calldiffnum");
09065                }
09066             } else {
09067                res = ast_play_and_wait(chan, "vm-nonumber");
09068                if (!ast_strlen_zero(vmu->dialout)) {
09069                   if (!res)
09070                      res = ast_play_and_wait(chan, "vm-toenternumber");
09071                }
09072             }
09073             if (!res)
09074                res = ast_play_and_wait(chan, "vm-star-cancel");
09075             if (!res)
09076                res = ast_waitfordigit(chan, 6000);
09077             if (!res) {
09078                retries++;
09079                if (retries > 3)
09080                   res = 't';
09081             }
09082             break; 
09083             
09084          }
09085          if (res == 't')
09086             res = 0;
09087          else if (res == '*')
09088             res = -1;
09089       }
09090       break;
09091       
09092    case 1:  /* Reply */
09093       /* Send reply directly to sender */
09094       if (ast_strlen_zero(cid))
09095          break;
09096 
09097       ast_callerid_parse(cid, &name, &num);
09098       if (!num) {
09099          if (option_verbose > 2)
09100             ast_verbose(VERBOSE_PREFIX_3 "No CID number available, no reply sent\n");
09101          if (!res)
09102             res = ast_play_and_wait(chan, "vm-nonumber");
09103          ast_config_destroy(msg_cfg);
09104          return res;
09105       } else {
09106          struct ast_vm_user vmu2;
09107          if (find_user(&vmu2, vmu->context, num)) {
09108             struct leave_vm_options leave_options;
09109             char mailbox[AST_MAX_EXTENSION * 2 + 2];
09110             snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
09111 
09112             if (option_verbose > 2)
09113                ast_verbose(VERBOSE_PREFIX_3 "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
09114             
09115             memset(&leave_options, 0, sizeof(leave_options));
09116             leave_options.record_gain = record_gain;
09117             res = leave_voicemail(chan, mailbox, &leave_options);
09118             if (!res)
09119                res = 't';
09120             ast_config_destroy(msg_cfg);
09121             return res;
09122          } else {
09123             /* Sender has no mailbox, can't reply */
09124             if (option_verbose > 2)
09125                ast_verbose( VERBOSE_PREFIX_3 "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
09126             ast_play_and_wait(chan, "vm-nobox");
09127             res = 't';
09128             ast_config_destroy(msg_cfg);
09129             return res;
09130          }
09131       } 
09132       res = 0;
09133 
09134       break;
09135    }
09136 
09137 #ifndef IMAP_STORAGE
09138    ast_config_destroy(msg_cfg);
09139 
09140    if (!res) {
09141       make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
09142       vms->heard[msg] = 1;
09143       res = wait_file(chan, vms, vms->fn);
09144    }
09145 #endif
09146    return res;
09147 }

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

Definition at line 8002 of file app_voicemail.c.

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

Referenced by load_config().

08003 {
08004    /* Assumes lock is already held */
08005    char *tmp;
08006    char *stringp;
08007    char *s;
08008    struct ast_vm_user *vmu;
08009 
08010    tmp = ast_strdupa(data);
08011 
08012    if ((vmu = find_or_create(context, mbox))) {
08013       populate_defaults(vmu);
08014 
08015       stringp = tmp;
08016       if ((s = strsep(&stringp, ","))) 
08017          ast_copy_string(vmu->password, s, sizeof(vmu->password));
08018       if (stringp && (s = strsep(&stringp, ","))) 
08019          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
08020       if (stringp && (s = strsep(&stringp, ","))) 
08021          ast_copy_string(vmu->email, s, sizeof(vmu->email));
08022       if (stringp && (s = strsep(&stringp, ","))) 
08023          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
08024       if (stringp && (s = strsep(&stringp, ","))) 
08025          apply_options(vmu, s);
08026    }
08027    return 0;
08028 }

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

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

00622 {
00623    int x;
00624    if (!strcasecmp(var, "attach")) {
00625       ast_set2_flag(vmu, ast_true(value), VM_ATTACH);
00626    } else if (!strcasecmp(var, "attachfmt")) {
00627       ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
00628    } else if (!strcasecmp(var, "serveremail")) {
00629       ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
00630    } else if (!strcasecmp(var, "language")) {
00631       ast_copy_string(vmu->language, value, sizeof(vmu->language));
00632    } else if (!strcasecmp(var, "tz")) {
00633       ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
00634 #ifdef IMAP_STORAGE
00635    } else if (!strcasecmp(var, "imapuser")) {
00636       ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
00637       vmu->imapversion = imapversion;
00638    } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
00639       ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
00640       vmu->imapversion = imapversion;
00641    } else if (!strcasecmp(var, "imapvmshareid")) {
00642       ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
00643       vmu->imapversion = imapversion;
00644 #endif
00645    } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
00646       ast_set2_flag(vmu, ast_true(value), VM_DELETE); 
00647    } else if (!strcasecmp(var, "saycid")){
00648       ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 
00649    } else if (!strcasecmp(var,"sendvoicemail")){
00650       ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 
00651    } else if (!strcasecmp(var, "review")){
00652       ast_set2_flag(vmu, ast_true(value), VM_REVIEW);
00653    } else if (!strcasecmp(var, "tempgreetwarn")){
00654       ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN);   
00655    } else if (!strcasecmp(var, "operator")){
00656       ast_set2_flag(vmu, ast_true(value), VM_OPERATOR);  
00657    } else if (!strcasecmp(var, "envelope")){
00658       ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE);  
00659    } else if (!strcasecmp(var, "sayduration")){
00660       ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION);  
00661    } else if (!strcasecmp(var, "saydurationm")){
00662       if (sscanf(value, "%30d", &x) == 1) {
00663          vmu->saydurationm = x;
00664       } else {
00665          ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
00666       }
00667    } else if (!strcasecmp(var, "forcename")){
00668       ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 
00669    } else if (!strcasecmp(var, "forcegreetings")){
00670       ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET);   
00671    } else if (!strcasecmp(var, "callback")) {
00672       ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
00673    } else if (!strcasecmp(var, "dialout")) {
00674       ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
00675    } else if (!strcasecmp(var, "exitcontext")) {
00676       ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
00677    } else if (!strcasecmp(var, "maxmsg")) {
00678       vmu->maxmsg = atoi(value);
00679       if (vmu->maxmsg <= 0) {
00680          ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %i\n", value, MAXMSG);
00681          vmu->maxmsg = MAXMSG;
00682       } else if (vmu->maxmsg > MAXMSGLIMIT) {
00683          ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
00684          vmu->maxmsg = MAXMSGLIMIT;
00685       }
00686    } else if (!strcasecmp(var, "volgain")) {
00687       sscanf(value, "%30lf", &vmu->volgain);
00688    } else if (!strcasecmp(var, "options")) {
00689       apply_options(vmu, value);
00690    }
00691 }

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

Definition at line 708 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00709 {  /* Destructively Parse options and apply */
00710    char *stringp;
00711    char *s;
00712    char *var, *value;
00713    stringp = ast_strdupa(options);
00714    while ((s = strsep(&stringp, "|"))) {
00715       value = s;
00716       if ((var = strsep(&value, "=")) && value) {
00717          apply_option(vmu, var, value);
00718       }
00719    }  
00720 }

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

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

00723 {
00724    struct ast_variable *tmp;
00725    tmp = var;
00726    while (tmp) {
00727       if (!strcasecmp(tmp->name, "vmsecret")) {
00728          ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00729       } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */
00730          if (ast_strlen_zero(retval->password))
00731             ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
00732       } else if (!strcasecmp(tmp->name, "uniqueid")) {
00733          ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
00734       } else if (!strcasecmp(tmp->name, "pager")) {
00735          ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager));
00736       } else if (!strcasecmp(tmp->name, "email")) {
00737          ast_copy_string(retval->email, tmp->value, sizeof(retval->email));
00738       } else if (!strcasecmp(tmp->name, "fullname")) {
00739          ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname));
00740       } else if (!strcasecmp(tmp->name, "context")) {
00741          ast_copy_string(retval->context, tmp->value, sizeof(retval->context));
00742 #ifdef IMAP_STORAGE
00743       } else if (!strcasecmp(tmp->name, "imapuser")) {
00744          ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser));
00745          retval->imapversion = imapversion;
00746       } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) {
00747          ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword));
00748          retval->imapversion = imapversion;
00749       } else if (!strcasecmp(tmp->name, "imapvmshareid")) {
00750          ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid));
00751          retval->imapversion = imapversion;
00752 #endif
00753       } else
00754          apply_option(retval, tmp->name, tmp->value);
00755       tmp = tmp->next;
00756    } 
00757 }

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

Definition at line 2945 of file app_voicemail.c.

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

Referenced by make_email_file().

02946 {
02947    unsigned char dtable[BASEMAXINLINE];
02948    int i,hiteof= 0;
02949    FILE *fi;
02950    struct baseio bio;
02951 
02952    memset(&bio, 0, sizeof(bio));
02953    bio.iocp = BASEMAXINLINE;
02954 
02955    if (!(fi = fopen(filename, "rb"))) {
02956       ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
02957       return -1;
02958    }
02959 
02960    for (i= 0;i<9;i++) {
02961       dtable[i]= 'A'+i;
02962       dtable[i+9]= 'J'+i;
02963       dtable[26+i]= 'a'+i;
02964       dtable[26+i+9]= 'j'+i;
02965    }
02966    for (i= 0;i<8;i++) {
02967       dtable[i+18]= 'S'+i;
02968       dtable[26+i+18]= 's'+i;
02969    }
02970    for (i= 0;i<10;i++) {
02971       dtable[52+i]= '0'+i;
02972    }
02973    dtable[62]= '+';
02974    dtable[63]= '/';
02975 
02976    while (!hiteof){
02977       unsigned char igroup[3],ogroup[4];
02978       int c,n;
02979 
02980       igroup[0]= igroup[1]= igroup[2]= 0;
02981 
02982       for (n= 0;n<3;n++) {
02983          if ((c = inchar(&bio, fi)) == EOF) {
02984             hiteof= 1;
02985             break;
02986          }
02987 
02988          igroup[n]= (unsigned char)c;
02989       }
02990 
02991       if (n> 0) {
02992          ogroup[0]= dtable[igroup[0]>>2];
02993          ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)];
02994          ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)];
02995          ogroup[3]= dtable[igroup[2]&0x3F];
02996 
02997          if (n<3) {
02998             ogroup[3]= '=';
02999 
03000             if (n<2)
03001                ogroup[2]= '=';
03002          }
03003 
03004          for (i= 0;i<4;i++)
03005             ochar(&bio, ogroup[i], so);
03006       }
03007    }
03008 
03009    fclose(fi);
03010    
03011    if (fputs(eol,so)==EOF)
03012       return 0;
03013 
03014    return 1;
03015 }

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

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

00694 {
00695    int res = -1;
00696    if (!strcmp(vmu->password, password)) {
00697       /* No change (but an update would return 0 rows updated, so we opt out here) */
00698       res = 0;
00699    } else if (!ast_strlen_zero(vmu->uniqueid)) {
00700       if (ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL) > 0) {
00701          ast_copy_string(vmu->password, password, sizeof(vmu->password));
00702          res = 0;
00703       }
00704    }
00705    return res;
00706 }

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

Referenced by make_email_file().

03114 {
03115    for (; *str; str++) {
03116       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03117          return 1;
03118       }
03119    }
03120    return 0;
03121 }

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

Definition at line 5780 of file app_voicemail.c.

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

Referenced by vm_execmain().

05781 {
05782    int x = 0;
05783 #ifndef IMAP_STORAGE
05784    int res = 0, nummsg;
05785 #endif
05786 
05787    if (vms->lastmsg <= -1)
05788       goto done;
05789 
05790    vms->curmsg = -1; 
05791 #ifndef IMAP_STORAGE
05792    /* Get the deleted messages fixed */ 
05793    if (vm_lock_path(vms->curdir))
05794       return ERROR_LOCK_PATH;
05795     
05796    for (x = 0; x < vmu->maxmsg; x++) { 
05797       if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x])) { 
05798          /* Save this message.  It's not in INBOX or hasn't been heard */ 
05799          make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
05800          if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
05801             break;
05802          vms->curmsg++; 
05803          make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 
05804          if (strcmp(vms->fn, vms->fn2)) { 
05805             RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2);
05806          } 
05807       } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && !vms->deleted[x]) { 
05808          /* Move to old folder before deleting */ 
05809          res = save_to_folder(vmu, vms, x, 1);
05810          if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) {
05811             /* If save failed do not delete the message */
05812             ast_log(LOG_WARNING, "Save failed.  Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
05813             vms->deleted[x] = 0;
05814             vms->heard[x] = 0;
05815             --x;
05816          } 
05817       } 
05818    } 
05819 
05820    /* Delete ALL remaining messages */
05821    nummsg = x - 1;
05822    for (x = vms->curmsg + 1; x <= nummsg; x++) {
05823       make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
05824       if (EXISTS(vms->curdir, x, vms->fn, NULL))
05825          DELETE(vms->curdir, x, vms->fn, vmu);
05826    }
05827    ast_unlock_path(vms->curdir);
05828 #else
05829    if (vms->deleted) {
05830       for (x=0;x < vmu->maxmsg;x++) { 
05831          if (vms->deleted[x]) { 
05832             if (option_debug > 2)
05833                ast_log(LOG_DEBUG,"IMAP delete of %d\n",x);
05834             DELETE(vms->curdir, x, vms->fn, vmu);
05835          }
05836       }
05837    }
05838 #endif
05839 
05840 done:
05841    if (vms->deleted)
05842       memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 
05843    if (vms->heard)
05844       memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 
05845 
05846    return 0;
05847 }

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

Definition at line 8191 of file app_voicemail.c.

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

08192 {
08193    int which = 0;
08194    int wordlen;
08195    struct ast_vm_user *vmu;
08196    const char *context = "";
08197 
08198    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08199    if (pos > 4)
08200       return NULL;
08201    if (pos == 3)
08202       return (state == 0) ? ast_strdup("for") : NULL;
08203    wordlen = strlen(word);
08204    AST_LIST_TRAVERSE(&users, vmu, list) {
08205       if (!strncasecmp(word, vmu->context, wordlen)) {
08206          if (context && strcmp(context, vmu->context) && ++which > state)
08207             return ast_strdup(vmu->context);
08208          /* ignore repeated contexts ? */
08209          context = vmu->context;
08210       }
08211    }
08212    return NULL;
08213 }

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

Definition at line 2823 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

02824 {
02825    int ifd;
02826    int ofd;
02827    int res;
02828    int len;
02829    char buf[4096];
02830 
02831 #ifdef HARDLINK_WHEN_POSSIBLE
02832    /* Hard link if possible; saves disk space & is faster */
02833    if (link(infile, outfile)) {
02834 #endif
02835       if ((ifd = open(infile, O_RDONLY)) < 0) {
02836          ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
02837          return -1;
02838       }
02839       if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
02840          ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
02841          close(ifd);
02842          return -1;
02843       }
02844       do {
02845          len = read(ifd, buf, sizeof(buf));
02846          if (len < 0) {
02847             ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
02848             close(ifd);
02849             close(ofd);
02850             unlink(outfile);
02851          }
02852          if (len) {
02853             res = write(ofd, buf, len);
02854             if (errno == ENOMEM || errno == ENOSPC || res != len) {
02855                ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
02856                close(ifd);
02857                close(ofd);
02858                unlink(outfile);
02859             }
02860          }
02861       } while (len);
02862       close(ifd);
02863       close(ofd);
02864       return 0;
02865 #ifdef HARDLINK_WHEN_POSSIBLE
02866    } else {
02867       /* Hard link succeeded */
02868       return 0;
02869    }
02870 #endif
02871 }

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

03788 {
03789    char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
03790    const char *frombox = mbox(imbox);
03791    int recipmsgnum;
03792 
03793    ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
03794 
03795    create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
03796    
03797    if (!dir)
03798       make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
03799    else
03800       ast_copy_string(fromdir, dir, sizeof(fromdir));
03801 
03802    make_file(frompath, sizeof(frompath), fromdir, msgnum);
03803 
03804    if (vm_lock_path(todir))
03805       return ERROR_LOCK_PATH;
03806 
03807    recipmsgnum = 0;
03808    do {
03809       make_file(topath, sizeof(topath), todir, recipmsgnum);
03810       if (!EXISTS(todir, recipmsgnum, topath, chan->language))
03811          break;
03812       recipmsgnum++;
03813    } while (recipmsgnum < recip->maxmsg);
03814    if (recipmsgnum < recip->maxmsg) {
03815       if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
03816          COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
03817       } else {
03818          /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL
03819           * copy will fail. Instead, we need to create a local copy, store it, and delete the local
03820           * copy. We don't have to #ifdef this because if file storage reaches this point, there's a
03821           * much worse problem happening and IMAP storage doesn't call this function
03822           */
03823          copy_plain_file(frompath, topath);
03824          STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL);
03825          vm_delete(topath);
03826       }
03827    } else {
03828       ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
03829    }
03830    ast_unlock_path(todir);
03831    notify_new_message(chan, recip, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
03832    
03833    return 0;
03834 }

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

Definition at line 2873 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message(), and forward_message().

02874 {
02875    char frompath2[PATH_MAX], topath2[PATH_MAX];
02876    ast_filecopy(frompath, topath, NULL);
02877    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
02878    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
02879    copy(frompath2, topath2);
02880 }

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

Definition at line 2739 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

02740 {
02741    /* Find all .txt files - even if they are not in sequence from 0000 */
02742 
02743    int vmcount = 0;
02744    DIR *vmdir = NULL;
02745    struct dirent *vment = NULL;
02746 
02747    if (vm_lock_path(dir))
02748       return ERROR_LOCK_PATH;
02749 
02750    if ((vmdir = opendir(dir))) {
02751       while ((vment = readdir(vmdir))) {
02752          if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 
02753             vmcount++;
02754       }
02755       closedir(vmdir);
02756    }
02757    ast_unlock_path(dir);
02758    
02759    return vmcount;
02760 }

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

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

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

00961 {
00962    mode_t   mode = VOICEMAIL_DIR_MODE;
00963 
00964    if (!ast_strlen_zero(context)) {
00965       make_dir(dest, len, context, "", "");
00966       if (mkdir(dest, mode) && errno != EEXIST) {
00967          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00968          return -1;
00969       }
00970    }
00971    if (!ast_strlen_zero(ext)) {
00972       make_dir(dest, len, context, ext, "");
00973       if (mkdir(dest, mode) && errno != EEXIST) {
00974          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00975          return -1;
00976       }
00977    }
00978    if (!ast_strlen_zero(folder)) {
00979       make_dir(dest, len, context, ext, folder);
00980       if (mkdir(dest, mode) && errno != EEXIST) {
00981          ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dest, strerror(errno));
00982          return -1;
00983       }
00984    }
00985    return 0;
00986 }

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

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

08898 {
08899    int cmd = 0;
08900    char destination[80] = "";
08901    int retries = 0;
08902 
08903    if (!num) {
08904       if (option_verbose > 2)
08905          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
08906       while (retries < 3 && cmd != 't') {
08907          destination[1] = '\0';
08908          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
08909          if (!cmd)
08910             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
08911          if (!cmd)
08912             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
08913          if (!cmd) {
08914             cmd = ast_waitfordigit(chan, 6000);
08915             if (cmd)
08916                destination[0] = cmd;
08917          }
08918          if (!cmd) {
08919             retries++;
08920          } else {
08921 
08922             if (cmd < 0)
08923                return 0;
08924             if (cmd == '*') {
08925                if (option_verbose > 2)
08926                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
08927                return 0;
08928             }
08929             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08930                retries++;
08931             else
08932                cmd = 't';
08933          }
08934       }
08935       if (retries >= 3) {
08936          return 0;
08937       }
08938       
08939    } else {
08940       if (option_verbose > 2)
08941          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08942       ast_copy_string(destination, num, sizeof(destination));
08943    }
08944 
08945    if (!ast_strlen_zero(destination)) {
08946       if (destination[strlen(destination) -1 ] == '*')
08947          return 0; 
08948       if (option_verbose > 2)
08949          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08950       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08951       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08952       chan->priority = 0;
08953       return 9;
08954    }
08955    return 0;
08956 }

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

Referenced by make_email_file().

03140 {
03141    char tmp[80];
03142    int first_section = 1;
03143    size_t endlen = 0, tmplen = 0;
03144    *end = '\0';
03145 
03146    tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03147    for (; *start; start++) {
03148       int need_encoding = 0;
03149       if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
03150          need_encoding = 1;
03151       }
03152       if ((first_section && need_encoding && preamble + tmplen > 70) ||
03153          (first_section && !need_encoding && preamble + tmplen > 72) ||
03154          (!first_section && need_encoding && tmplen > 70) ||
03155          (!first_section && !need_encoding && tmplen > 72)) {
03156          /* Start new line */
03157          endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp);
03158          tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset);
03159          first_section = 0;
03160       }
03161       if (need_encoding && *start == ' ') {
03162          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_");
03163       } else if (need_encoding) {
03164          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start);
03165       } else {
03166          tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start);
03167       }
03168    }
03169    snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : "");
03170    return end;
03171 }

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

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

07975 {
07976    struct ast_vm_user *vmu;
07977    AST_LIST_TRAVERSE(&users, vmu, list) {
07978       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
07979          if (strcasecmp(vmu->context, context)) {
07980             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
07981                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
07982                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
07983                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
07984          }
07985          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
07986          return NULL;
07987       }
07988       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
07989          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
07990          return NULL;
07991       }
07992    }
07993    
07994    if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07995       ast_copy_string(vmu->context, context, sizeof(vmu->context));
07996       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07997       AST_LIST_INSERT_TAIL(&users, vmu, list);
07998    }
07999    return vmu;
08000 }

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

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

00789 {
00790    /* This function could be made to generate one from a database, too */
00791    struct ast_vm_user *vmu=NULL, *cur;
00792    AST_LIST_LOCK(&users);
00793 
00794    if (!context && !ast_test_flag((&globalflags), VM_SEARCH))
00795       context = "default";
00796 
00797    AST_LIST_TRAVERSE(&users, cur, list) {
00798 #ifdef IMAP_STORAGE
00799       if (cur->imapversion != imapversion) {
00800          continue;
00801       }
00802 #endif
00803       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
00804          break;
00805       if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
00806          break;
00807    }
00808    if (cur) {
00809       /* Make a copy, so that on a reload, we have no race */
00810       if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
00811          memcpy(vmu, cur, sizeof(*vmu));
00812          ast_set2_flag(vmu, !ivm, VM_ALLOCED);
00813          AST_LIST_NEXT(vmu, list) = NULL;
00814       }
00815    } else
00816       vmu = find_user_realtime(ivm, context, mailbox);
00817    AST_LIST_UNLOCK(&users);
00818    return vmu;
00819 }

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

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

00760 {
00761    struct ast_variable *var;
00762    struct ast_vm_user *retval;
00763 
00764    if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
00765       if (!ivm)
00766          ast_set_flag(retval, VM_ALLOCED);   
00767       else
00768          memset(retval, 0, sizeof(*retval));
00769       if (mailbox) 
00770          ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
00771       populate_defaults(retval);
00772       if (!context && ast_test_flag((&globalflags), VM_SEARCH))
00773          var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL);
00774       else
00775          var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL);
00776       if (var) {
00777          apply_options_full(retval, var);
00778          ast_variables_destroy(var);
00779       } else { 
00780          if (!ivm) 
00781             free(retval);
00782          retval = NULL;
00783       }  
00784    } 
00785    return retval;
00786 }

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

Definition at line 5161 of file app_voicemail.c.

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

Referenced by vm_execmain().

05162 {
05163 #ifdef IMAP_STORAGE
05164    int todircount=0;
05165    struct vm_state *dstvms;
05166 #endif
05167    char username[70]="";
05168    int res = 0, cmd = 0;
05169    struct ast_vm_user *receiver = NULL, *vmtmp;
05170    AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user);
05171    char *stringp;
05172    const char *s;
05173    int saved_messages = 0, found = 0;
05174    int valid_extensions = 0;
05175    char *dir;
05176    int curmsg;
05177 
05178    if (vms == NULL) return -1;
05179    dir = vms->curdir;
05180    curmsg = vms->curmsg;
05181    
05182    while (!res && !valid_extensions) {
05183       int use_directory = 0;
05184       if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) {
05185          int done = 0;
05186          int retries = 0;
05187          cmd=0;
05188          while ((cmd >= 0) && !done ){
05189             if (cmd)
05190                retries = 0;
05191             switch (cmd) {
05192             case '1': 
05193                use_directory = 0;
05194                done = 1;
05195                break;
05196             case '2': 
05197                use_directory = 1;
05198                done=1;
05199                break;
05200             case '*': 
05201                cmd = 't';
05202                done = 1;
05203                break;
05204             default: 
05205                /* Press 1 to enter an extension press 2 to use the directory */
05206                cmd = ast_play_and_wait(chan,"vm-forward");
05207                if (!cmd)
05208                   cmd = ast_waitfordigit(chan,3000);
05209                if (!cmd)
05210                   retries++;
05211                if (retries > 3)
05212                {
05213                   cmd = 't';
05214                   done = 1;
05215                }
05216                
05217             }
05218          }
05219          if (cmd < 0 || cmd == 't')
05220             break;
05221       }
05222       
05223       if (use_directory) {
05224          /* use app_directory */
05225          
05226          char old_context[sizeof(chan->context)];
05227          char old_exten[sizeof(chan->exten)];
05228          int old_priority;
05229          struct ast_app* app;
05230 
05231          
05232          app = pbx_findapp("Directory");
05233          if (app) {
05234             char vmcontext[256];
05235             /* make backup copies */
05236             memcpy(old_context, chan->context, sizeof(chan->context));
05237             memcpy(old_exten, chan->exten, sizeof(chan->exten));
05238             old_priority = chan->priority;
05239             
05240             /* call the the Directory, changes the channel */
05241             snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default");
05242             res = pbx_exec(chan, app, vmcontext);
05243             
05244             ast_copy_string(username, chan->exten, sizeof(username));
05245             
05246             /* restore the old context, exten, and priority */
05247             memcpy(chan->context, old_context, sizeof(chan->context));
05248             memcpy(chan->exten, old_exten, sizeof(chan->exten));
05249             chan->priority = old_priority;
05250             
05251          } else {
05252             ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
05253             ast_clear_flag((&globalflags), VM_DIRECFORWARD);   
05254          }
05255       } else {
05256          /* Ask for an extension */
05257          res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
05258          if (res)
05259             break;
05260          if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
05261             break;
05262       }
05263       
05264       /* start all over if no username */
05265       if (ast_strlen_zero(username))
05266          continue;
05267       stringp = username;
05268       s = strsep(&stringp, "*");
05269       /* start optimistic */
05270       valid_extensions = 1;
05271       while (s) {
05272          /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1).  find_user is going to malloc since we have a NULL as first argument */
05273          if ((flag == 1 || strcmp(s,sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
05274             AST_LIST_INSERT_HEAD(&extensions, receiver, list);
05275             found++;
05276          } else {
05277             ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
05278             valid_extensions = 0;
05279             break;
05280          }
05281          s = strsep(&stringp, "*");
05282       }
05283       /* break from the loop of reading the extensions */
05284       if (valid_extensions)
05285          break;
05286       /* "I am sorry, that's not a valid extension.  Please try again." */
05287       res = ast_play_and_wait(chan, "pbx-invalid");
05288    }
05289    /* check if we're clear to proceed */
05290    if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
05291       return res;
05292    if (flag==1) {
05293       struct leave_vm_options leave_options;
05294       char mailbox[AST_MAX_EXTENSION * 2 + 2];
05295       /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */
05296       if (context)
05297          snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
05298       else
05299          ast_copy_string(mailbox, username, sizeof(mailbox));
05300 
05301       /* Send VoiceMail */
05302       memset(&leave_options, 0, sizeof(leave_options));
05303       leave_options.record_gain = record_gain;
05304       cmd = leave_voicemail(chan, mailbox, &leave_options);
05305    } else {
05306       /* Forward VoiceMail */
05307       long duration = 0;
05308       char origmsgfile[PATH_MAX], msgfile[PATH_MAX];
05309       struct vm_state vmstmp;
05310 
05311       memcpy(&vmstmp, vms, sizeof(vmstmp));
05312 
05313       make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg);
05314       create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp");
05315       make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg);
05316 
05317       RETRIEVE(dir, curmsg, sender);
05318 
05319       /* Alter a surrogate file, only */
05320       copy_plain_file(origmsgfile, msgfile);
05321 
05322       cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp);
05323       if (!cmd) {
05324          AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
05325 #ifdef IMAP_STORAGE
05326             char *myserveremail;
05327             int attach_user_voicemail;
05328             /* get destination mailbox */
05329             dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
05330             if (!dstvms) {
05331                dstvms = create_vm_state_from_user(vmtmp);
05332             }
05333             if (dstvms) {
05334                init_mailstream(dstvms, 0);
05335                if (!dstvms->mailstream) {
05336                   ast_log (LOG_ERROR,"IMAP mailstream for %s is NULL\n",vmtmp->mailbox);
05337                } else {
05338                   STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms);
05339                   run_externnotify(vmtmp->context, vmtmp->mailbox); 
05340                }
05341             } else {
05342                ast_log (LOG_ERROR,"Could not find state information for mailbox %s\n",vmtmp->mailbox);
05343             }
05344             myserveremail = serveremail;
05345             if (!ast_strlen_zero(vmtmp->serveremail))
05346                myserveremail = vmtmp->serveremail;
05347             attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
05348             /* NULL category for IMAP storage */
05349             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);
05350 #else
05351             copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir);
05352 #endif
05353             saved_messages++;
05354             AST_LIST_REMOVE_CURRENT(&extensions, list);
05355             free_user(vmtmp);
05356             if (res)
05357                break;
05358          }
05359          AST_LIST_TRAVERSE_SAFE_END;
05360          if (saved_messages > 0) {
05361             /* give confirmation that the message was saved */
05362             /* commented out since we can't forward batches yet
05363             if (saved_messages == 1)
05364                res = ast_play_and_wait(chan, "vm-message");
05365             else
05366                res = ast_play_and_wait(chan, "vm-messages");
05367             if (!res)
05368                res = ast_play_and_wait(chan, "vm-saved"); */
05369             res = ast_play_and_wait(chan, "vm-msgsaved");
05370          }  
05371       }
05372 
05373       /* Remove surrogate file */
05374       vm_delete(msgfile);
05375       DISPOSE(dir, curmsg);
05376    }
05377 
05378    /* If anything failed above, we still have this list to free */
05379    while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list)))
05380       free_user(vmtmp);
05381    return res ? res : cmd;
05382 }

static void free_user ( struct ast_vm_user vmu  )  [static]

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

01006 {
01007    if (ast_test_flag(vmu, VM_ALLOCED))
01008       free(vmu);
01009 }

static void free_vm_users ( void   )  [static]

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

08236 {
08237    struct ast_vm_user *cur;
08238    struct vm_zone *zcur;
08239 
08240    AST_LIST_LOCK(&users);
08241    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
08242       ast_set_flag(cur, VM_ALLOCED);
08243       free_user(cur);
08244    }
08245    AST_LIST_UNLOCK(&users);
08246 
08247    AST_LIST_LOCK(&zones);
08248    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
08249       free_zone(zcur);
08250    }
08251    AST_LIST_UNLOCK(&zones);
08252 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3630 of file app_voicemail.c.

References free.

03631 {
03632    free(z);
03633 }

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

Definition at line 3563 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03564 {
03565    struct tm tm;
03566    time_t t;
03567 
03568    time(&t);
03569 
03570    ast_localtime(&t, &tm, NULL);
03571 
03572    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03573 }

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

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

04960 {
04961    int x;
04962    int d;
04963    char fn[PATH_MAX];
04964    d = ast_play_and_wait(chan, "vm-press");  /* "Press" */
04965    if (d)
04966       return d;
04967    for (x = start; x< 5; x++) {  /* For all folders */
04968       if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, (char *) NULL)))
04969          return d;
04970       d = ast_play_and_wait(chan, "vm-for"); /* "for" */
04971       if (d)
04972          return d;
04973       snprintf(fn, sizeof(fn), "vm-%s", mbox(x));  /* Folder name */
04974       d = vm_play_folder_name(chan, fn);
04975       if (d)
04976          return d;
04977       d = ast_waitfordigit(chan, 500);
04978       if (d)
04979          return d;
04980    }
04981    d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
04982    if (d)
04983       return d;
04984    d = ast_waitfordigit(chan, 4000);
04985    return d;
04986 }

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

Definition at line 4988 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

04989 {
04990    int res = 0;
04991    res = ast_play_and_wait(chan, fn);  /* Folder name */
04992    while (((res < '0') || (res > '9')) &&
04993          (res != '#') && (res >= 0)) {
04994       res = get_folder(chan, 0);
04995    }
04996    return res;
04997 }

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

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

08122 {
08123    struct ast_vm_user *vmu;
08124    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
08125 
08126    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
08127    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
08128 
08129    AST_LIST_LOCK(&users);
08130    if (!AST_LIST_EMPTY(&users)) {
08131       if (argc == 3)
08132          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08133       else {
08134          int count = 0;
08135          AST_LIST_TRAVERSE(&users, vmu, list) {
08136             if (!strcmp(argv[4],vmu->context))
08137                count++;
08138          }
08139          if (count) {
08140             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08141          } else {
08142             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
08143             AST_LIST_UNLOCK(&users);
08144             return RESULT_FAILURE;
08145          }
08146       }
08147       AST_LIST_TRAVERSE(&users, vmu, list) {
08148          int newmsgs = 0, oldmsgs = 0;
08149          char count[12], tmp[256] = "";
08150 
08151          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
08152             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08153             inboxcount(tmp, &newmsgs, &oldmsgs);
08154             snprintf(count,sizeof(count),"%d",newmsgs);
08155             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08156          }
08157       }
08158    } else {
08159       ast_cli(fd, "There are no voicemail users currently defined\n");
08160       AST_LIST_UNLOCK(&users);
08161       return RESULT_FAILURE;
08162    }
08163    AST_LIST_UNLOCK(&users);
08164    return RESULT_SUCCESS;
08165 }

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

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

08168 {
08169    struct vm_zone *zone;
08170    char *output_format = "%-15s %-20s %-45s\n";
08171    int res = RESULT_SUCCESS;
08172 
08173    if (argc != 3)
08174       return RESULT_SHOWUSAGE;
08175 
08176    AST_LIST_LOCK(&zones);
08177    if (!AST_LIST_EMPTY(&zones)) {
08178       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
08179       AST_LIST_TRAVERSE(&zones, zone, list) {
08180          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
08181       }
08182    } else {
08183       ast_cli(fd, "There are no voicemail zones currently defined\n");
08184       res = RESULT_FAILURE;
08185    }
08186    AST_LIST_UNLOCK(&zones);
08187 
08188    return res;
08189 }

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

Definition at line 3874 of file app_voicemail.c.

References __has_voicemail(), and ast_copy_string().

03875 {
03876    char tmp[256], *tmp2 = tmp, *mbox, *context;
03877    ast_copy_string(tmp, mailbox, sizeof(tmp));
03878    while ((mbox = strsep(&tmp2, ","))) {
03879       if ((context = strchr(mbox, '@')))
03880          *context++ = '\0';
03881       else
03882          context = "default";
03883       if (__has_voicemail(context, mbox, folder, 1))
03884          return 1;
03885    }
03886    return 0;
03887 }

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

Definition at line 3890 of file app_voicemail.c.

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

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

03891 {
03892    char tmp[256];
03893    char *context;
03894 
03895    if (newmsgs)
03896       *newmsgs = 0;
03897    if (oldmsgs)
03898       *oldmsgs = 0;
03899    /* If no mailbox, return immediately */
03900    if (ast_strlen_zero(mailbox))
03901       return 0;
03902    if (strchr(mailbox, ',')) {
03903       int tmpnew, tmpold;
03904       char *mb, *cur;
03905 
03906       ast_copy_string(tmp, mailbox, sizeof(tmp));
03907       mb = tmp;
03908       while ((cur = strsep(&mb, ", "))) {
03909          if (!ast_strlen_zero(cur)) {
03910             if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
03911                return -1;
03912             else {
03913                if (newmsgs)
03914                   *newmsgs += tmpnew; 
03915                if (oldmsgs)
03916                   *oldmsgs += tmpold;
03917             }
03918          }
03919       }
03920       return 0;
03921    }
03922    ast_copy_string(tmp, mailbox, sizeof(tmp));
03923    context = strchr(tmp, '@');
03924    if (context) {
03925       *context = '\0';
03926       context++;
03927    } else
03928       context = "default";
03929    if (newmsgs)
03930       *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
03931    if (oldmsgs)
03932       *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
03933    return 0;
03934 }

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

Definition at line 2897 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

02898 {
02899    int l;
02900 
02901    if (bio->ateof)
02902       return 0;
02903 
02904    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
02905       if (ferror(fi))
02906          return -1;
02907 
02908       bio->ateof = 1;
02909       return 0;
02910    }
02911 
02912    bio->iolen= l;
02913    bio->iocp= 0;
02914 
02915    return 1;
02916 }

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

Definition at line 2918 of file app_voicemail.c.

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

Referenced by base_encode().

02919 {
02920    if (bio->iocp>=bio->iolen) {
02921       if (!inbuf(bio, fi))
02922          return EOF;
02923    }
02924 
02925    return bio->iobuf[bio->iocp++];
02926 }

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

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

03602 {
03603    int res;
03604    char fn[PATH_MAX];
03605    char dest[PATH_MAX];
03606 
03607    snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext);
03608 
03609    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "greet"))) {
03610       ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn);
03611       return -1;
03612    }
03613 
03614    res = play_greeting(chan, vmu, fn, ecodes);
03615    if (res == -2) {
03616       /* File did not exist */
03617       res = ast_stream_and_wait(chan, "vm-theperson", chan->language, ecodes);
03618       if (res)
03619          return res;
03620       res = ast_say_digit_str(chan, ext, ecodes, chan->language);
03621    }
03622 
03623    if (res)
03624       return res;
03625 
03626    res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language, ecodes);
03627    return res;
03628 }

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

Definition at line 2777 of file app_voicemail.c.

References ast_fileexists(), ast_unlock_path(), ERROR_LOCK_PATH, make_file(), ast_vm_user::maxmsg, and vm_lock_path().

Referenced by open_mailbox().

02778 {
02779    int x;
02780    char fn[PATH_MAX];
02781 
02782    if (vm_lock_path(dir))
02783       return ERROR_LOCK_PATH;
02784 
02785    for (x = 0; x < vmu->maxmsg; x++) {
02786       make_file(fn, sizeof(fn), dir, x);
02787       if (ast_fileexists(fn, NULL, NULL) < 1)
02788          break;
02789    }
02790    ast_unlock_path(dir);
02791 
02792    return x - 1;
02793 }

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

Definition at line 3985 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, EXISTS, ast_vm_user::exit, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), INTRO, invent_message(), ast_channel::language, 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(), 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, and VOICEMAIL_FILE_MODE.

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

03986 {
03987 #ifdef IMAP_STORAGE
03988    int newmsgs, oldmsgs;
03989 #endif
03990    struct vm_state *vms = NULL;
03991    char txtfile[PATH_MAX], tmptxtfile[PATH_MAX];
03992    char callerid[256];
03993    FILE *txt;
03994    char date[50];
03995    int txtdes;
03996    int res = 0;
03997    int msgnum;
03998    int duration = 0;
03999    int ausemacro = 0;
04000    int ousemacro = 0;
04001    int ouseexten = 0;
04002    char dir[PATH_MAX], tmpdir[PATH_MAX];
04003    char dest[PATH_MAX];
04004    char fn[PATH_MAX];
04005    char prefile[PATH_MAX] = "";
04006    char tempfile[PATH_MAX] = "";
04007    char ext_context[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2] = "";
04008    char fmt[80];
04009    char *context;
04010    char ecodes[16] = "#";
04011    char tmp[1324] = "", *tmpptr;
04012    struct ast_vm_user *vmu;
04013    struct ast_vm_user svm;
04014    const char *category = NULL;
04015 
04016    if (strlen(ext) > sizeof(tmp) - 1) {
04017       ast_log(LOG_WARNING, "List of extensions is too long (>%ld).  Truncating.\n", (long) sizeof(tmp) - 1);
04018    }
04019    ast_copy_string(tmp, ext, sizeof(tmp));
04020    ext = tmp;
04021    context = strchr(tmp, '@');
04022    if (context) {
04023       *context++ = '\0';
04024       tmpptr = strchr(context, '&');
04025    } else {
04026       tmpptr = strchr(ext, '&');
04027    }
04028 
04029    if (tmpptr)
04030       *tmpptr++ = '\0';
04031 
04032    category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
04033 
04034    if (option_debug > 2)
04035       ast_log(LOG_DEBUG, "Before find_user\n");
04036    if (!(vmu = find_user(&svm, context, ext))) {
04037       ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
04038       if (ast_test_flag(options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
04039          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
04040       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04041       return res;
04042    }
04043    /* Setup pre-file if appropriate */
04044    if (strcmp(vmu->context, "default"))
04045       snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
04046    else
04047       ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
04048    if (ast_test_flag(options, OPT_BUSY_GREETING)) {
04049       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "busy");
04050       snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
04051    } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
04052       res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "unavail");
04053       snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
04054    }
04055    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
04056    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, "temp"))) {
04057       ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
04058       return -1;
04059    }
04060    RETRIEVE(tempfile, -1, vmu);
04061    if (ast_fileexists(tempfile, NULL, NULL) > 0)
04062       ast_copy_string(prefile, tempfile, sizeof(prefile));
04063    DISPOSE(tempfile, -1);
04064    /* It's easier just to try to make it than to check for its existence */
04065    create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
04066    create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp");
04067 
04068    /* Check current or macro-calling context for special extensions */
04069    if (ast_test_flag(vmu, VM_OPERATOR)) {
04070       if (!ast_strlen_zero(vmu->exit)) {
04071          if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
04072             strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04073             ouseexten = 1;
04074          }
04075       } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
04076          strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04077          ouseexten = 1;
04078       }
04079       else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
04080       strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
04081       ousemacro = 1;
04082       }
04083    }
04084 
04085    if (!ast_strlen_zero(vmu->exit)) {
04086       if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
04087          strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04088    } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
04089       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04090    else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
04091       strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
04092       ausemacro = 1;
04093    }
04094 
04095    /* Play the beginning intro if desired */
04096    if (!ast_strlen_zero(prefile)) {
04097       res = play_greeting(chan, vmu, prefile, ecodes);
04098       if (res == -2) {
04099          /* The file did not exist */
04100          if (option_debug)
04101             ast_log(LOG_DEBUG, "%s doesn't exist, doing what we can\n", prefile);
04102          res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
04103       }
04104       if (res < 0) {
04105          if (option_debug)
04106             ast_log(LOG_DEBUG, "Hang up during prefile playback\n");
04107          free_user(vmu);
04108          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04109          return -1;
04110       }
04111    }
04112    if (res == '#') {
04113       /* On a '#' we skip the instructions */
04114       ast_set_flag(options, OPT_SILENT);
04115       res = 0;
04116    }
04117    if (!res && !ast_test_flag(options, OPT_SILENT)) {
04118       res = ast_stream_and_wait(chan, INTRO, chan->language, ecodes);
04119       if (res == '#') {
04120          ast_set_flag(options, OPT_SILENT);
04121          res = 0;
04122       }
04123    }
04124    if (res > 0)
04125       ast_stopstream(chan);
04126    /* Check for a '*' here in case the caller wants to escape from voicemail to something
04127     other than the operator -- an automated attendant or mailbox login for example */
04128    if (res == '*') {
04129       chan->exten[0] = 'a';
04130       chan->exten[1] = '\0';
04131       if (!ast_strlen_zero(vmu->exit)) {
04132          ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04133       } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
04134          ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04135       }
04136       chan->priority = 0;
04137       free_user(vmu);
04138       pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04139       return 0;
04140    }
04141 
04142    /* Check for a '0' here */
04143    if (res == '0') {
04144    transfer:
04145       if (ouseexten || ousemacro) {
04146          chan->exten[0] = 'o';
04147          chan->exten[1] = '\0';
04148          if (!ast_strlen_zero(vmu->exit)) {
04149             ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
04150          } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
04151             ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
04152          }
04153          ast_play_and_wait(chan, "transfer");
04154          chan->priority = 0;
04155          free_user(vmu);
04156          pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
04157       }
04158       return 0;
04159    }
04160    if (res < 0) {
04161       free_user(vmu);
04162       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04163       return -1;
04164    }
04165    /* The meat of recording the message...  All the announcements and beeps have been played*/
04166    ast_copy_string(fmt, vmfmts, sizeof(fmt));
04167    if (!ast_strlen_zero(fmt)) {
04168       msgnum = 0;
04169 
04170 #ifdef IMAP_STORAGE
04171       /* Is ext a mailbox? */
04172       /* must open stream for this user to get info! */
04173       res = inboxcount(ext_context, &newmsgs, &oldmsgs);
04174       if (res < 0) {
04175          ast_log(LOG_NOTICE,"Can not leave voicemail, unable to count messages\n");
04176          return -1;
04177       }
04178       if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) {
04179       /*It is possible under certain circumstances that inboxcount did not create a vm_state when it was needed. This is a catchall which will
04180        * rarely be used*/
04181          if (!(vms = create_vm_state_from_user(vmu))) {
04182             ast_log(LOG_ERROR, "Couldn't allocate necessary space\n");
04183             return -1;
04184          }
04185       }
04186       vms->newmessages++;
04187       /* here is a big difference! We add one to it later */
04188       msgnum = newmsgs + oldmsgs;
04189       if (option_debug > 2)
04190          ast_log(LOG_DEBUG, "Messagecount set to %d\n",msgnum);
04191       snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
04192       /* set variable for compatability */
04193       pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04194 
04195       /* Check if mailbox is full */
04196       check_quota(vms, imapfolder);
04197       if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) {
04198          if (option_debug)
04199             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit);
04200          ast_play_and_wait(chan, "vm-mailboxfull");
04201          return -1;
04202       }
04203       if (option_debug > 2)
04204          ast_log(LOG_DEBUG, "Checking message number quota - mailbox has %d messages, maximum is set to %d\n",msgnum,vmu->maxmsg);
04205       if (msgnum >= vmu->maxmsg) {
04206          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04207          if (!res)
04208             res = ast_waitstream(chan, "");
04209          ast_log(LOG_WARNING, "No more messages possible\n");
04210          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04211          goto leave_vm_out;
04212       }
04213 
04214       /* Check if we have exceeded maxmsg */
04215       if (msgnum >= vmu->maxmsg) {
04216          ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg);
04217          ast_play_and_wait(chan, "vm-mailboxfull");
04218          return -1;
04219       }
04220 #else
04221       if (count_messages(vmu, dir) >= vmu->maxmsg) {
04222          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04223          if (!res)
04224             res = ast_waitstream(chan, "");
04225          ast_log(LOG_WARNING, "No more messages possible\n");
04226          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04227          goto leave_vm_out;
04228       }
04229 
04230 #endif
04231       snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
04232       txtdes = mkstemp(tmptxtfile);
04233       chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
04234       if (txtdes < 0) {
04235          res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
04236          if (!res)
04237             res = ast_waitstream(chan, "");
04238          ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
04239          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04240          goto leave_vm_out;
04241       }
04242 
04243       /* Now play the beep once we have the message number for our next message. */
04244       if (res >= 0) {
04245          /* Unless we're *really* silent, try to send the beep */
04246          res = ast_stream_and_wait(chan, "beep", chan->language, "");
04247       }
04248             
04249       /* Store information */
04250       txt = fdopen(txtdes, "w+");
04251       if (txt) {
04252          get_date(date, sizeof(date));
04253          fprintf(txt, 
04254             ";\n"
04255             "; Message Information file\n"
04256             ";\n"
04257             "[message]\n"
04258             "origmailbox=%s\n"
04259             "context=%s\n"
04260             "macrocontext=%s\n"
04261             "exten=%s\n"
04262             "priority=%d\n"
04263             "callerchan=%s\n"
04264             "callerid=%s\n"
04265             "origdate=%s\n"
04266             "origtime=%ld\n"
04267             "category=%s\n",
04268             ext,
04269             chan->context,
04270             chan->macrocontext, 
04271             chan->exten,
04272             chan->priority,
04273             chan->name,
04274             ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
04275             date, (long)time(NULL),
04276             category ? category : ""); 
04277       } else
04278          ast_log(LOG_WARNING, "Error opening text file for output\n");
04279       res = play_record_review(chan, NULL, tmptxtfile, vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain, vms);
04280 
04281       if (txt) {
04282          if (duration < vmminmessage) {
04283             fclose(txt);
04284             if (option_verbose > 2) 
04285                ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminmessage);
04286             ast_filedelete(tmptxtfile, NULL);
04287             unlink(tmptxtfile);
04288          } else {
04289             fprintf(txt, "duration=%d\n", duration);
04290             fclose(txt);
04291             if (vm_lock_path(dir)) {
04292                ast_log(LOG_ERROR, "Couldn't lock directory %s.  Voicemail will be lost.\n", dir);
04293                /* Delete files */
04294                ast_filedelete(tmptxtfile, NULL);
04295                unlink(tmptxtfile);
04296             } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
04297                if (option_debug) 
04298                   ast_log(LOG_DEBUG, "The recorded media file is gone, so we should remove the .txt file too!\n");
04299                unlink(tmptxtfile);
04300                ast_unlock_path(dir);
04301             } else {
04302                for (;;) {
04303                   make_file(fn, sizeof(fn), dir, msgnum);
04304                   if (!EXISTS(dir, msgnum, fn, NULL))
04305                      break;
04306                   msgnum++;
04307                }
04308 
04309                /* assign a variable with the name of the voicemail file */ 
04310 #ifndef IMAP_STORAGE
04311                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
04312 #else
04313                pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
04314 #endif
04315 
04316                snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
04317                ast_filerename(tmptxtfile, fn, NULL);
04318                rename(tmptxtfile, txtfile);
04319 
04320                ast_unlock_path(dir);
04321                /* We must store the file first, before copying the message, because
04322                 * ODBC storage does the entire copy with SQL.
04323                 */
04324                if (ast_fileexists(fn, NULL, NULL) > 0) {
04325                   STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms);
04326                }
04327 
04328                /* Are there to be more recipients of this message? */
04329                while (tmpptr) {
04330                   struct ast_vm_user recipu, *recip;
04331                   char *exten, *context;
04332                
04333                   exten = strsep(&tmpptr, "&");
04334                   context = strchr(exten, '@');
04335                   if (context) {
04336                      *context = '\0';
04337                      context++;
04338                   }
04339                   if ((recip = find_user(&recipu, context, exten))) {
04340                      copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir);
04341                      free_user(recip);
04342                   }
04343                }
04344                /* Notification and disposal needs to happen after the copy, though. */
04345                if (ast_fileexists(fn, NULL, NULL)) {
04346                   notify_new_message(chan, vmu, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL));
04347                   DISPOSE(dir, msgnum);
04348                }
04349             }
04350          }
04351       }
04352       if (res == '0') {
04353          goto transfer;
04354       } else if (res > 0)
04355          res = 0;
04356 
04357       if (duration < vmminmessage)
04358          /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
04359          pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
04360       else
04361          pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
04362    } else
04363       ast_log(LOG_WARNING, "No format for saving voicemail?\n");
04364 leave_vm_out:
04365    free_user(vmu);
04366    
04367    return res;
04368 }

static int load_config ( void   )  [static]

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

08255 {
08256    struct ast_vm_user *cur;
08257    struct ast_config *cfg, *ucfg;
08258    char *cat;
08259    struct ast_variable *var;
08260    const char *notifystr = NULL;
08261    const char *smdistr = NULL;
08262    const char *astattach;
08263    const char *astsearch;
08264    const char *astsaycid;
08265    const char *send_voicemail;
08266 #ifdef IMAP_STORAGE
08267    const char *imap_server;
08268    const char *imap_port;
08269    const char *imap_flags;
08270    const char *imap_folder;
08271    const char *auth_user;
08272    const char *auth_password;
08273    const char *expunge_on_hangup;
08274    const char *imap_timeout;
08275 #endif
08276    const char *astcallop;
08277    const char *astreview;
08278    const char *asttempgreetwarn;
08279    const char *astskipcmd;
08280    const char *asthearenv;
08281    const char *astsaydurationinfo;
08282    const char *astsaydurationminfo;
08283    const char *silencestr;
08284    const char *maxmsgstr;
08285    const char *astdirfwd;
08286    const char *thresholdstr;
08287    const char *fmt;
08288    const char *astemail;
08289    const char *ucontext;
08290    const char *astmailcmd = SENDMAIL;
08291    const char *astforcename;
08292    const char *astforcegreet;
08293    const char *s;
08294    char *q,*stringp, *tmp;
08295    const char *dialoutcxt = NULL;
08296    const char *callbackcxt = NULL;  
08297    const char *exitcxt = NULL;   
08298    const char *extpc;
08299    const char *emaildateformatstr;
08300    const char *volgainstr;
08301    int x;
08302    int tmpadsi[4];
08303 
08304    cfg = ast_config_load(VOICEMAIL_CONFIG);
08305 
08306    free_vm_users();
08307 
08308    AST_LIST_LOCK(&users);
08309 
08310    memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
08311 
08312    if (cfg) {
08313       /* General settings */
08314 
08315       if (!(ucontext = ast_variable_retrieve(cfg, "general", "userscontext")))
08316          ucontext = "default";
08317       ast_copy_string(userscontext, ucontext, sizeof(userscontext));
08318       /* Attach voice message to mail message ? */
08319       if (!(astattach = ast_variable_retrieve(cfg, "general", "attach"))) 
08320          astattach = "yes";
08321       ast_set2_flag((&globalflags), ast_true(astattach), VM_ATTACH); 
08322 
08323       if (!(astsearch = ast_variable_retrieve(cfg, "general", "searchcontexts")))
08324          astsearch = "no";
08325       ast_set2_flag((&globalflags), ast_true(astsearch), VM_SEARCH);
08326 
08327       volgain = 0.0;
08328       if ((volgainstr = ast_variable_retrieve(cfg, "general", "volgain")))
08329          sscanf(volgainstr, "%30lf", &volgain);
08330 
08331 #ifdef ODBC_STORAGE
08332       strcpy(odbc_database, "asterisk");
08333       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
08334          ast_copy_string(odbc_database, thresholdstr, sizeof(odbc_database));
08335       }
08336       strcpy(odbc_table, "voicemessages");
08337       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "odbctable"))) {
08338          ast_copy_string(odbc_table, thresholdstr, sizeof(odbc_table));
08339       }
08340 #endif      
08341       /* Mail command */
08342       strcpy(mailcmd, SENDMAIL);
08343       if ((astmailcmd = ast_variable_retrieve(cfg, "general", "mailcmd")))
08344          ast_copy_string(mailcmd, astmailcmd, sizeof(mailcmd)); /* User setting */
08345 
08346       maxsilence = 0;
08347       if ((silencestr = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
08348          maxsilence = atoi(silencestr);
08349          if (maxsilence > 0)
08350             maxsilence *= 1000;
08351       }
08352       
08353       if (!(maxmsgstr = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
08354          maxmsg = MAXMSG;
08355       } else {
08356          maxmsg = atoi(maxmsgstr);
08357          if (maxmsg <= 0) {
08358             ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", maxmsgstr, MAXMSG);
08359             maxmsg = MAXMSG;
08360          } else if (maxmsg > MAXMSGLIMIT) {
08361             ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, maxmsgstr);
08362             maxmsg = MAXMSGLIMIT;
08363          }
08364       }
08365 
08366       /* Load date format config for voicemail mail */
08367       if ((emaildateformatstr = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
08368          ast_copy_string(emaildateformat, emaildateformatstr, sizeof(emaildateformat));
08369       }
08370 
08371       /* External password changing command */
08372       if ((extpc = ast_variable_retrieve(cfg, "general", "externpass"))) {
08373          ast_copy_string(ext_pass_cmd,extpc,sizeof(ext_pass_cmd));
08374       }
08375 #ifdef IMAP_STORAGE
08376       /* IMAP server address */
08377       if ((imap_server = ast_variable_retrieve(cfg, "general", "imapserver"))) {
08378          ast_copy_string(imapserver, imap_server, sizeof(imapserver));
08379       } else {
08380          ast_copy_string(imapserver,"localhost", sizeof(imapserver));
08381       }
08382       /* IMAP server port */
08383       if ((imap_port = ast_variable_retrieve(cfg, "general", "imapport"))) {
08384          ast_copy_string(imapport, imap_port, sizeof(imapport));
08385       } else {
08386          ast_copy_string(imapport,"143", sizeof(imapport));
08387       }
08388       /* IMAP server flags */
08389       if ((imap_flags = ast_variable_retrieve(cfg, "general", "imapflags"))) {
08390          ast_copy_string(imapflags, imap_flags, sizeof(imapflags));
08391       }
08392       /* IMAP server master username */
08393       if ((auth_user = ast_variable_retrieve(cfg, "general", "authuser"))) {
08394          ast_copy_string(authuser, auth_user, sizeof(authuser));
08395       }
08396       /* IMAP server master password */
08397       if ((auth_password = ast_variable_retrieve(cfg, "general", "authpassword"))) {
08398          ast_copy_string(authpassword, auth_password, sizeof(authpassword));
08399       }
08400       /* Expunge on exit */
08401       if ((expunge_on_hangup = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
08402          if (ast_false(expunge_on_hangup))
08403             expungeonhangup = 0;
08404          else
08405             expungeonhangup = 1;
08406       } else {
08407          expungeonhangup = 1;
08408       }
08409       /* IMAP voicemail folder */
08410       if ((imap_folder = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
08411          ast_copy_string(imapfolder, imap_folder, sizeof(imapfolder));
08412       } else {
08413          ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
08414       }
08415 
08416       /* There is some very unorthodox casting done here. This is due
08417        * to the way c-client handles the argument passed in. It expects a 
08418        * void pointer and casts the pointer directly to a long without
08419        * first dereferencing it. */
08420 
08421       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
08422          mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(imap_timeout)));
08423       } else {
08424          mail_parameters(NIL, SET_READTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08425       }
08426 
08427       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
08428          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(imap_timeout)));
08429       } else {
08430          mail_parameters(NIL, SET_WRITETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08431       }
08432 
08433       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
08434          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(imap_timeout)));
08435       } else {
08436          mail_parameters(NIL, SET_OPENTIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08437       }
08438 
08439       if ((imap_timeout = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
08440          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(imap_timeout)));
08441       } else {
08442          mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) DEFAULT_IMAP_TCP_TIMEOUT);
08443       }
08444 
08445       /* Increment configuration version */
08446       imapversion++;
08447 #endif
08448       /* External voicemail notify application */
08449       
08450       if ((notifystr = ast_variable_retrieve(cfg, "general", "externnotify"))) {
08451          ast_copy_string(externnotify, notifystr, sizeof(externnotify));
08452          if (option_debug > 2)
08453             ast_log(LOG_DEBUG, "found externnotify: %s\n", externnotify);
08454          if (!strcasecmp(externnotify, "smdi")) {
08455             if (option_debug)
08456                ast_log(LOG_DEBUG, "Using SMDI for external voicemail notification\n");
08457             if ((smdistr = ast_variable_retrieve(cfg, "general", "smdiport"))) {
08458                smdi_iface = ast_smdi_interface_find(smdistr);
08459             } else {
08460                if (option_debug)
08461                   ast_log(LOG_DEBUG, "No SMDI interface set, trying default (/dev/ttyS0)\n");
08462                smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
08463             }
08464 
08465             if (!smdi_iface) {
08466                ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling external voicemail notification\n");
08467                externnotify[0] = '\0';
08468             }
08469          }
08470       } else {
08471          externnotify[0] = '\0';
08472       }
08473 
08474       /* Silence treshold */
08475       silencethreshold = 256;
08476       if ((thresholdstr = ast_variable_retrieve(cfg, "general", "silencethreshold")))
08477          silencethreshold = atoi(thresholdstr);
08478       
08479       if (!(astemail = ast_variable_retrieve(cfg, "general", "serveremail"))) 
08480          astemail = ASTERISK_USERNAME;
08481       ast_copy_string(serveremail, astemail, sizeof(serveremail));
08482       
08483       vmmaxmessage = 0;
08484       if ((s = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
08485          if (sscanf(s, "%30d", &x) == 1) {
08486             vmmaxmessage = x;
08487          } else {
08488             ast_log(LOG_WARNING, "Invalid max message time length\n");
08489          }
08490       }
08491 
08492       vmminmessage = 0;
08493       if ((s = ast_variable_retrieve(cfg, "general", "minmessage"))) {
08494          if (sscanf(s, "%30d", &x) == 1) {
08495             vmminmessage = x;
08496             if (maxsilence / 1000 >= vmminmessage)
08497                ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
08498          } else {
08499             ast_log(LOG_WARNING, "Invalid min message time length\n");
08500          }
08501       }
08502       fmt = ast_variable_retrieve(cfg, "general", "format");
08503       if (!fmt) {
08504          fmt = "wav";   
08505       } else {
08506          tmp = ast_strdupa(fmt);
08507          fmt = ast_format_str_reduce(tmp);
08508          if (!fmt) {
08509             ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n");
08510             fmt = "wav";
08511          }
08512       }
08513 
08514       ast_copy_string(vmfmts, fmt, sizeof(vmfmts));
08515 
08516       skipms = 3000;
08517       if ((s = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
08518          if (sscanf(s, "%30d", &x) == 1) {
08519             maxgreet = x;
08520          } else {
08521             ast_log(LOG_WARNING, "Invalid max message greeting length\n");
08522          }
08523       }
08524 
08525       if ((s = ast_variable_retrieve(cfg, "general", "skipms"))) {
08526          if (sscanf(s, "%30d", &x) == 1) {
08527             skipms = x;
08528          } else {
08529             ast_log(LOG_WARNING, "Invalid skipms value\n");
08530          }
08531       }
08532 
08533       maxlogins = 3;
08534       if ((s = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
08535          if (sscanf(s, "%30d", &x) == 1) {
08536             maxlogins = x;
08537          } else {
08538             ast_log(LOG_WARNING, "Invalid max failed login attempts\n");
08539          }
08540       }
08541 
08542       /* Force new user to record name ? */
08543       if (!(astforcename = ast_variable_retrieve(cfg, "general", "forcename"))) 
08544          astforcename = "no";
08545       ast_set2_flag((&globalflags), ast_true(astforcename), VM_FORCENAME);
08546 
08547       /* Force new user to record greetings ? */
08548       if (!(astforcegreet = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 
08549          astforcegreet = "no";
08550       ast_set2_flag((&globalflags), ast_true(astforcegreet), VM_FORCEGREET);
08551 
08552       if ((s = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))){
08553          if (option_debug > 2)
08554             ast_log(LOG_DEBUG,"VM_CID Internal context string: %s\n",s);
08555          stringp = ast_strdupa(s);
08556          for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
08557             if (!ast_strlen_zero(stringp)) {
08558                q = strsep(&stringp,",");
08559                while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
08560                   q++;
08561                ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x]));
08562                if (option_debug > 2)
08563                   ast_log(LOG_DEBUG,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
08564             } else {
08565                cidinternalcontexts[x][0] = '\0';
08566             }
08567          }
08568       }
08569       if (!(astreview = ast_variable_retrieve(cfg, "general", "review"))){
08570          if (option_debug)
08571             ast_log(LOG_DEBUG,"VM Review Option disabled globally\n");
08572          astreview = "no";
08573       }
08574       ast_set2_flag((&globalflags), ast_true(astreview), VM_REVIEW); 
08575 
08576       /*Temperary greeting reminder */
08577       if (!(asttempgreetwarn = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
08578          if (option_debug)
08579             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option disabled globally\n");
08580          asttempgreetwarn = "no";
08581       } else {
08582          if (option_debug)
08583             ast_log(LOG_DEBUG, "VM Temperary Greeting Reminder Option enabled globally\n");
08584       }
08585       ast_set2_flag((&globalflags), ast_true(asttempgreetwarn), VM_TEMPGREETWARN);
08586 
08587       if (!(astcallop = ast_variable_retrieve(cfg, "general", "operator"))){
08588          if (option_debug)
08589             ast_log(LOG_DEBUG,"VM Operator break disabled globally\n");
08590          astcallop = "no";
08591       }
08592       ast_set2_flag((&globalflags), ast_true(astcallop), VM_OPERATOR);  
08593 
08594       if (!(astsaycid = ast_variable_retrieve(cfg, "general", "saycid"))) {
08595          if (option_debug)
08596             ast_log(LOG_DEBUG,"VM CID Info before msg disabled globally\n");
08597          astsaycid = "no";
08598       } 
08599       ast_set2_flag((&globalflags), ast_true(astsaycid), VM_SAYCID); 
08600 
08601       if (!(send_voicemail = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){
08602          if (option_debug)
08603             ast_log(LOG_DEBUG,"Send Voicemail msg disabled globally\n");
08604          send_voicemail = "no";
08605       }
08606       ast_set2_flag((&globalflags), ast_true(send_voicemail), VM_SVMAIL);
08607    
08608       if (!(asthearenv = ast_variable_retrieve(cfg, "general", "envelope"))) {
08609          if (option_debug)
08610             ast_log(LOG_DEBUG,"ENVELOPE before msg enabled globally\n");
08611          asthearenv = "yes";
08612       }
08613       ast_set2_flag((&globalflags), ast_true(asthearenv), VM_ENVELOPE); 
08614 
08615       if (!(astsaydurationinfo = ast_variable_retrieve(cfg, "general", "sayduration"))) {
08616          if (option_debug)
08617             ast_log(LOG_DEBUG,"Duration info before msg enabled globally\n");
08618          astsaydurationinfo = "yes";
08619       }
08620       ast_set2_flag((&globalflags), ast_true(astsaydurationinfo), VM_SAYDURATION);  
08621 
08622       saydurationminfo = 2;
08623       if ((astsaydurationminfo = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
08624          if (sscanf(astsaydurationminfo, "%30d", &x) == 1) {
08625             saydurationminfo = x;
08626          } else {
08627             ast_log(LOG_WARNING, "Invalid min duration for say duration\n");
08628          }
08629       }
08630 
08631       if (!(astskipcmd = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
08632          if (option_debug)
08633             ast_log(LOG_DEBUG,"We are not going to skip to the next msg after save/delete\n");
08634          astskipcmd = "no";
08635       }
08636       ast_set2_flag((&globalflags), ast_true(astskipcmd), VM_SKIPAFTERCMD);
08637 
08638       if ((dialoutcxt = ast_variable_retrieve(cfg, "general", "dialout"))) {
08639          ast_copy_string(dialcontext, dialoutcxt, sizeof(dialcontext));
08640          if (option_debug)
08641             ast_log(LOG_DEBUG, "found dialout context: %s\n", dialcontext);
08642       } else {
08643          dialcontext[0] = '\0';  
08644       }
08645       
08646       if ((callbackcxt = ast_variable_retrieve(cfg, "general", "callback"))) {
08647          ast_copy_string(callcontext, callbackcxt, sizeof(callcontext));
08648          if (option_debug)
08649             ast_log(LOG_DEBUG, "found callback context: %s\n", callcontext);
08650       } else {
08651          callcontext[0] = '\0';
08652       }
08653 
08654       if ((exitcxt = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
08655          ast_copy_string(exitcontext, exitcxt, sizeof(exitcontext));
08656          if (option_debug)
08657             ast_log(LOG_DEBUG, "found operator context: %s\n", exitcontext);
08658       } else {
08659          exitcontext[0] = '\0';
08660       }
08661 
08662       if (!(astdirfwd = ast_variable_retrieve(cfg, "general", "usedirectory"))) 
08663          astdirfwd = "no";
08664       ast_set2_flag((&globalflags), ast_true(astdirfwd), VM_DIRECFORWARD); 
08665       if ((ucfg = ast_config_load("users.conf"))) {   
08666          for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
08667             if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
08668                continue;
08669             if ((cur = find_or_create(userscontext, cat))) {
08670                populate_defaults(cur);
08671                apply_options_full(cur, ast_variable_browse(ucfg, cat));
08672                ast_copy_string(cur->context, userscontext, sizeof(cur->context));
08673             }
08674          }
08675          ast_config_destroy(ucfg);
08676       }
08677       cat = ast_category_browse(cfg, NULL);
08678       while (cat) {
08679          if (strcasecmp(cat, "general")) {
08680             var = ast_variable_browse(cfg, cat);
08681             if (strcasecmp(cat, "zonemessages")) {
08682                /* Process mailboxes in this context */
08683                while (var) {
08684                   append_mailbox(cat, var->name, var->value);
08685                   var = var->next;
08686                }
08687             } else {
08688                /* Timezones in this context */
08689                while (var) {
08690                   struct vm_zone *z;
08691                   if ((z = ast_malloc(sizeof(*z)))) {
08692                      char *msg_format, *timezone;
08693                      msg_format = ast_strdupa(var->value);
08694                      timezone = strsep(&msg_format, "|");
08695                      if (msg_format) {
08696                         ast_copy_string(z->name, var->name, sizeof(z->name));
08697                         ast_copy_string(z->timezone, timezone, sizeof(z->timezone));
08698                         ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
08699                         AST_LIST_LOCK(&zones);
08700                         AST_LIST_INSERT_HEAD(&zones, z, list);
08701                         AST_LIST_UNLOCK(&zones);
08702                      } else {
08703                         ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
08704                         free(z);
08705                      }
08706                   } else {
08707                      free(z);
08708                      AST_LIST_UNLOCK(&users);
08709                      ast_config_destroy(cfg);
08710                      return -1;
08711                   }
08712                   var = var->next;
08713                }
08714             }
08715          }
08716          cat = ast_category_browse(cfg, cat);
08717       }
08718       memset(fromstring,0,sizeof(fromstring));
08719       memset(pagerfromstring,0,sizeof(pagerfromstring));
08720       memset(emailtitle,0,sizeof(emailtitle));
08721       strcpy(charset, "ISO-8859-1");
08722       if (emailbody) {
08723          free(emailbody);
08724          emailbody = NULL;
08725       }
08726       if (emailsubject) {
08727          free(emailsubject);
08728          emailsubject = NULL;
08729       }
08730       if (pagerbody) {
08731          free(pagerbody);
08732          pagerbody = NULL;
08733       }
08734       if (pagersubject) {
08735          free(pagersubject);
08736          pagersubject = NULL;
08737       }
08738       if ((s = ast_variable_retrieve(cfg, "general", "pbxskip")))
08739          ast_set2_flag((&globalflags), ast_true(s), VM_PBXSKIP);
08740       if ((s = ast_variable_retrieve(cfg, "general", "fromstring")))
08741          ast_copy_string(fromstring,s,sizeof(fromstring));
08742       if ((s = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
08743          ast_copy_string(pagerfromstring,s,sizeof(pagerfromstring));
08744       if ((s = ast_variable_retrieve(cfg, "general", "charset")))
08745          ast_copy_string(charset,s,sizeof(charset));
08746       if ((s = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
08747          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08748          for (x = 0; x < 4; x++) {
08749             memcpy(&adsifdn[x], &tmpadsi[x], 1);
08750          }
08751       }
08752       if ((s = ast_variable_retrieve(cfg, "general", "adsisec"))) {
08753          sscanf(s, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
08754          for (x = 0; x < 4; x++) {
08755             memcpy(&adsisec[x], &tmpadsi[x], 1);
08756          }
08757       }
08758       if ((s = ast_variable_retrieve(cfg, "general", "adsiver")))
08759          if (atoi(s)) {
08760             adsiver = atoi(s);
08761          }
08762       if ((s = ast_variable_retrieve(cfg, "general", "emailtitle"))) {
08763          ast_log(LOG_NOTICE, "Keyword 'emailtitle' is DEPRECATED, please use 'emailsubject' instead.\n");
08764          ast_copy_string(emailtitle,s,sizeof(emailtitle));
08765       }
08766       if ((s = ast_variable_retrieve(cfg, "general", "emailsubject")))
08767          emailsubject = ast_strdup(s);
08768       if ((s = ast_variable_retrieve(cfg, "general", "emailbody"))) {
08769          char *tmpread, *tmpwrite;
08770          emailbody = ast_strdup(s);
08771 
08772          /* substitute strings \t and \n into the appropriate characters */
08773          tmpread = tmpwrite = emailbody;
08774          while ((tmpwrite = strchr(tmpread,'\\'))) {
08775             switch (tmpwrite[1]) {
08776             case 'r':
08777                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08778                *tmpwrite = '\r';
08779                break;
08780             case 'n':
08781                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08782                *tmpwrite = '\n';
08783                break;
08784             case 't':
08785                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08786                *tmpwrite = '\t';
08787                break;
08788             default:
08789                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08790             }
08791             tmpread = tmpwrite + 1;
08792          }
08793       }
08794       if ((s = ast_variable_retrieve(cfg, "general", "tz"))) {
08795          ast_copy_string(zonetag, s, sizeof(zonetag));
08796       }
08797       if ((s = ast_variable_retrieve(cfg, "general", "pagersubject")))
08798          pagersubject = ast_strdup(s);
08799       if ((s = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
08800          char *tmpread, *tmpwrite;
08801          pagerbody = ast_strdup(s);
08802 
08803          /* substitute strings \t and \n into the appropriate characters */
08804          tmpread = tmpwrite = pagerbody;
08805          while ((tmpwrite = strchr(tmpread, '\\'))) {
08806             switch (tmpwrite[1]) {
08807             case 'r':
08808                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08809                *tmpwrite = '\r';
08810                break;
08811             case 'n':
08812                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08813                *tmpwrite = '\n';
08814                break;
08815             case 't':
08816                memmove(tmpwrite + 1, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
08817                *tmpwrite = '\t';
08818                break;
08819             default:
08820                ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
08821             }
08822             tmpread = tmpwrite + 1;
08823          }
08824       }
08825       AST_LIST_UNLOCK(&users);
08826       ast_config_destroy(cfg);
08827       return 0;
08828    } else {
08829       AST_LIST_UNLOCK(&users);
08830       ast_log(LOG_WARNING, "Failed to load configuration file.\n");
08831       return 0;
08832    }
08833 }

static int load_module ( void   )  [static]

Definition at line 8856 of file app_voicemail.c.

References 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(), load_config(), LOG_ERROR, messagecount(), vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().

08857 {
08858    int res;
08859    char *adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
08860    char *smdi_loaded = ast_module_helper("", "res_smdi", 0, 0, 0, 0);
08861    free(adsi_loaded);
08862    free(smdi_loaded);
08863 
08864    if (!adsi_loaded) {
08865       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
08866       return AST_MODULE_LOAD_DECLINE;
08867    }
08868 
08869    if (!smdi_loaded) {
08870       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_smdi.so\n");
08871       return AST_MODULE_LOAD_DECLINE;
08872    }
08873 
08874    my_umask = umask(0);
08875    umask(my_umask);
08876    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
08877    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
08878    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
08879    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
08880    if (res)
08881       return(res);
08882 
08883    if ((res=load_config())) {
08884       return(res);
08885    }
08886 
08887    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08888 
08889    /* compute the location of the voicemail spool directory */
08890    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
08891 
08892    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
08893 
08894    return res;
08895 }

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

Definition at line 926 of file app_voicemail.c.

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

00927 {
00928    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00929 }

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

Referenced by sendmail().

03174 {
03175    char date[256];
03176    char host[MAXHOSTNAMELEN] = "";
03177    char who[256];
03178    char bound[256];
03179    char fname[256];
03180    char dur[256];
03181    char tmpcmd[256];
03182    char enc_cidnum[256] = "", enc_cidname[256] = "";
03183    struct tm tm;
03184    char *passdata = NULL, *passdata2;
03185    size_t len_passdata = 0, len_passdata2, tmplen;
03186 #ifdef IMAP_STORAGE
03187 #define ENDL "\r\n"
03188 #else
03189 #define ENDL "\n"
03190 #endif
03191 
03192    /* One alloca for multiple fields */
03193    len_passdata2 = strlen(vmu->fullname);
03194    if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) {
03195       len_passdata2 = tmplen;
03196    }
03197    if ((tmplen = strlen(emailtitle)) > len_passdata2) {
03198       len_passdata2 = tmplen;
03199    }
03200    if ((tmplen = strlen(fromstring)) > len_passdata2) {
03201       len_passdata2 = tmplen;
03202    }
03203    len_passdata2 = len_passdata2 * 3 + 200;
03204    passdata2 = alloca(len_passdata2);
03205 
03206    if (cidnum) {
03207       strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum));
03208    }
03209    if (cidname) {
03210       strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
03211    }
03212    gethostname(host, sizeof(host) - 1);
03213    if (strchr(srcemail, '@'))
03214       ast_copy_string(who, srcemail, sizeof(who));
03215    else {
03216       snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03217    }
03218    snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03219    strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03220    fprintf(p, "Date: %s" ENDL, date);
03221 
03222    /* Set date format for voicemail mail */
03223    strftime(date, sizeof(date), emaildateformat, &tm);
03224 
03225    if (*fromstring) {
03226       struct ast_channel *ast;
03227       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03228          char *ptr;
03229          memset(passdata2, 0, len_passdata2);
03230          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category);
03231          pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2);
03232          len_passdata = strlen(passdata2) * 3 + 300;
03233          passdata = alloca(len_passdata);
03234          if (check_mime(passdata2)) {
03235             int first_line = 1;
03236             encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3);
03237             while ((ptr = strchr(passdata, ' '))) {
03238                *ptr = '\0';
03239                fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata);
03240                first_line = 0;
03241                passdata = ptr + 1;
03242             }
03243             fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who);
03244          } else {
03245             fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who);
03246          }
03247          ast_channel_free(ast);
03248       } else
03249          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03250    } else
03251       fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
03252 
03253    if (check_mime(vmu->fullname)) {
03254       int first_line = 1;
03255       char *ptr;
03256       encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3);
03257       while ((ptr = strchr(passdata2, ' '))) {
03258          *ptr = '\0';
03259          fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2);
03260          first_line = 0;
03261          passdata2 = ptr + 1;
03262       }
03263       fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email);
03264    } else {
03265       fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email);
03266    }
03267    if (emailsubject) {
03268       struct ast_channel *ast;
03269       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03270          int vmlen = strlen(emailsubject) * 3 + 200;
03271          /* Only allocate more space if the previous was not large enough */
03272          if (vmlen > len_passdata) {
03273             passdata = alloca(vmlen);
03274             len_passdata = vmlen;
03275          }
03276 
03277          memset(passdata, 0, len_passdata);
03278          prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category);
03279          pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata);
03280          if (check_mime(passdata)) {
03281             int first_line = 1;
03282             char *ptr;
03283             encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0);
03284             while ((ptr = strchr(passdata2, ' '))) {
03285                *ptr = '\0';
03286                fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03287                first_line = 0;
03288                passdata2 = ptr + 1;
03289             }
03290             fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2);
03291          } else {
03292             fprintf(p, "Subject: %s" ENDL, passdata);
03293          }
03294          ast_channel_free(ast);
03295       } else {
03296          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03297       }
03298    } else   if (*emailtitle) {
03299       fprintf(p, emailtitle, msgnum + 1, mailbox) ;
03300       fprintf(p, ENDL) ;
03301    } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
03302       fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03303    } else {
03304       fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
03305    }
03306    fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host);
03307    if (imap) {
03308       /* additional information needed for IMAP searching */
03309       fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
03310       /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
03311       fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
03312       fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
03313 #ifdef IMAP_STORAGE
03314       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
03315 #else
03316       fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
03317 #endif
03318       fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
03319       fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
03320       fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
03321       fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
03322       fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
03323       if (!ast_strlen_zero(category)) {
03324          fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
03325       }
03326       fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
03327       fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL));
03328    }
03329    if (!ast_strlen_zero(cidnum)) {
03330       fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
03331    }
03332    if (!ast_strlen_zero(cidname)) {
03333       fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
03334    }
03335    fprintf(p, "MIME-Version: 1.0" ENDL);
03336    if (attach_user_voicemail) {
03337       /* Something unique. */
03338       snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random());
03339 
03340       fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
03341       fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
03342       fprintf(p, "--%s" ENDL, bound);
03343    }
03344    fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
03345    if (emailbody) {
03346       struct ast_channel *ast;
03347       if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03348          char *passdata;
03349          int vmlen = strlen(emailbody)*3 + 200;
03350          if ((passdata = alloca(vmlen))) {
03351             memset(passdata, 0, vmlen);
03352             prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03353             pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen);
03354             fprintf(p, "%s" ENDL, passdata);
03355          } else
03356             ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03357          ast_channel_free(ast);
03358       } else
03359          ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03360    } else {
03361       if (strcmp(vmu->mailbox, mailbox)) {
03362          /* Forwarded type */
03363          struct ast_config *msg_cfg;
03364          const char *v;
03365          int inttime;
03366          char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = "";
03367          /* Retrieve info from VM attribute file */
03368          make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03369          make_file(fromfile, sizeof(fromfile), fromdir, msgnum);
03370          if (strlen(fromfile) < sizeof(fromfile) - 5) {
03371             strcat(fromfile, ".txt");
03372          }
03373          if ((msg_cfg = ast_config_load(fromfile))) {
03374             if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03375                ast_copy_string(origcallerid, v, sizeof(origcallerid));
03376             }
03377 
03378             /* You might be tempted to do origdate, except that a) it's in the wrong
03379              * format, and b) it's missing for IMAP recordings. */
03380             if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) {
03381                time_t ttime = inttime;
03382                struct tm tm;
03383                ast_localtime(&ttime, &tm, NULL);
03384                strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03385             }
03386             fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded"
03387                " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL
03388                "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a"
03389                " chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur,
03390                msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")),
03391                date, origcallerid, origdate);
03392             ast_config_destroy(msg_cfg);
03393          } else {
03394             goto plain_message;
03395          }
03396       } else {
03397 plain_message:
03398          fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a "
03399             "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL
03400             "want to check it when you get a chance.  Thanks!" ENDL ENDL "\t\t\t\t--Asterisk"
03401             ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox,
03402             (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
03403       }
03404    }
03405    if (attach_user_voicemail) {
03406       /* Eww. We want formats to tell us their own MIME type */
03407       char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
03408       char tmpdir[256], newtmp[256];
03409       int tmpfd = -1;
03410    
03411       if (vmu->volgain < -.001 || vmu->volgain > .001) {
03412          create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
03413          snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
03414          tmpfd = mkstemp(newtmp);
03415          chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
03416          if (option_debug > 2)
03417             ast_log(LOG_DEBUG, "newtmp: %s\n", newtmp);
03418          if (tmpfd > -1) {
03419             int soxstatus;
03420             snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
03421             if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
03422                attach = newtmp;
03423                if (option_debug > 2) {
03424                   ast_log(LOG_DEBUG, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
03425                }
03426             } else {
03427                ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
03428                   soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
03429                ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
03430             }
03431          }
03432       }
03433       fprintf(p, "--%s" ENDL, bound);
03434       fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format);
03435       fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
03436       fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
03437       fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format);
03438       snprintf(fname, sizeof(fname), "%s.%s", attach, format);
03439       base_encode(fname, p);
03440       fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound);
03441       if (tmpfd > -1) {
03442          unlink(fname);
03443          close(tmpfd);
03444          unlink(newtmp);
03445       }
03446    }
03447 #undef ENDL
03448 }

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

Definition at line 931 of file app_voicemail.c.

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

00932 {
00933    return snprintf(dest, len, "%s/msg%04d", dir, num);
00934 }

static char* mbox ( int  id  )  [static]

Definition at line 988 of file app_voicemail.c.

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

00989 {
00990    static char *msgs[] = {
00991       "INBOX",
00992       "Old",
00993       "Work",
00994       "Family",
00995       "Friends",
00996       "Cust1",
00997       "Cust2",
00998       "Cust3",
00999       "Cust4",
01000       "Cust5",
01001    };
01002    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
01003 }

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

Definition at line 3837 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

03838 {
03839    return __has_voicemail(context, mailbox, folder, 0);
03840 }

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

05102 {
05103    char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
05104    int newmsgs = 0, oldmsgs = 0;
05105    const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY");
05106 
05107    make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX");
05108    make_file(fn, sizeof(fn), todir, msgnum);
05109    snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
05110 
05111    if (!ast_strlen_zero(vmu->attachfmt)) {
05112       if (strstr(fmt, vmu->attachfmt)) {
05113          fmt = vmu->attachfmt;
05114       } else {
05115          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);
05116       }
05117    }
05118 
05119    /* Attach only the first format */
05120    fmt = ast_strdupa(fmt);
05121    stringp = fmt;
05122    strsep(&stringp, "|");
05123 
05124    if (!ast_strlen_zero(vmu->email)) {
05125       int attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH);
05126       char *myserveremail = serveremail;
05127       attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
05128       if (!ast_strlen_zero(vmu->serveremail))
05129          myserveremail = vmu->serveremail;
05130       
05131       if (attach_user_voicemail)
05132          RETRIEVE(todir, msgnum, vmu);
05133 
05134       /*XXX possible imap issue, should category be NULL XXX*/
05135       sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category);
05136 
05137       if (attach_user_voicemail)
05138          DISPOSE(todir, msgnum);
05139    }
05140 
05141    if (!ast_strlen_zero(vmu->pager)) {
05142       char *myserveremail = serveremail;
05143       if (!ast_strlen_zero(vmu->serveremail))
05144          myserveremail = vmu->serveremail;
05145       sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category);
05146    }
05147 
05148    if (ast_test_flag(vmu, VM_DELETE)) {
05149       DELETE(todir, msgnum, fn, vmu);
05150    }
05151 
05152    /* Leave voicemail for someone */
05153    if (ast_app_has_voicemail(ext_context, NULL)) {
05154       ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs);
05155    }
05156    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);
05157    run_externnotify(vmu->context, vmu->mailbox);
05158    return 0;
05159 }

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

Definition at line 2928 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

02929 {
02930    if (bio->linelength>=BASELINELEN) {
02931       if (fputs(eol,so)==EOF)
02932          return -1;
02933 
02934       bio->linelength= 0;
02935    }
02936 
02937    if (putc(((unsigned char)c),so)==EOF)
02938       return -1;
02939 
02940    bio->linelength++;
02941 
02942    return 1;
02943 }

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

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

Referenced by vm_execmain().

05738 {
05739    int res = 0;
05740    int count_msg, last_msg;
05741 
05742    ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox));
05743    
05744    /* Rename the member vmbox HERE so that we don't try to return before
05745     * we know what's going on.
05746     */
05747    snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
05748    
05749    /* Faster to make the directory than to check if it exists. */
05750    create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
05751 
05752    count_msg = count_messages(vmu, vms->curdir);
05753    if (count_msg < 0)
05754       return count_msg;
05755    else
05756       vms->lastmsg = count_msg - 1;
05757 
05758    /*
05759    The following test is needed in case sequencing gets messed up.
05760    There appears to be more than one way to mess up sequence, so
05761    we will not try to find all of the root causes--just fix it when
05762    detected.
05763    */
05764 
05765    last_msg = last_message_index(vmu, vms->curdir);
05766    if (last_msg < 0)
05767       return last_msg;
05768    else if (vms->lastmsg != last_msg)
05769    {
05770       ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir);
05771       res = resequence_mailbox(vmu, vms->curdir);
05772       if (res)
05773          return res;
05774    }
05775 
05776    return 0;
05777 }

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

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

03576 {
03577    int res = -2;
03578 
03579 #ifdef ODBC_STORAGE
03580    int success = 
03581 #endif
03582    RETRIEVE(filename, -1, vmu);
03583    if (ast_fileexists(filename, NULL, NULL) > 0) {
03584       res = ast_streamfile(chan, filename, chan->language);
03585       if (res > -1) 
03586          res = ast_waitstream(chan, ecodes);
03587 #ifdef ODBC_STORAGE
03588       if (success == -1) {
03589          /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
03590          if (option_debug)
03591             ast_log(LOG_DEBUG, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
03592          store_file(filename, vmu->mailbox, vmu->context, -1);
03593       }
03594 #endif
03595    }
03596    DISPOSE(filename, -1);
03597 
03598    return res;
03599 }

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

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

05604 {
05605    int res = 0;
05606    char filename[256], *cid;
05607    const char *origtime, *context, *category, *duration;
05608    struct ast_config *msg_cfg;
05609 
05610    vms->starting = 0; 
05611    make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05612    adsi_message(chan, vms);
05613    
05614    if (!strncasecmp(chan->language, "he", 2)) {        /* HEBREW FORMAT */
05615       /*
05616        * The syntax in hebrew for counting the number of message is up side down
05617        * in comparison to english.
05618        */
05619       if (!vms->curmsg) {
05620          res = wait_file2(chan, vms, "vm-message");
05621          res = wait_file2(chan, vms, "vm-first");    /* "First" */
05622       } else if (vms->curmsg == vms->lastmsg) {
05623          res = wait_file2(chan, vms, "vm-message");
05624          res = wait_file2(chan, vms, "vm-last");     /* "last" */
05625       } else {
05626          res = wait_file2(chan, vms, "vm-message");  /* "message" */
05627          if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05628             ast_log(LOG_DEBUG, "curmsg: %d\n", vms->curmsg);
05629             ast_log(LOG_DEBUG, "lagmsg: %d\n", vms->lastmsg);
05630             if (!res) {
05631                res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
05632             }
05633          }
05634       }
05635 
05636    } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH FORMAT */
05637       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05638          int ten, one;
05639          char nextmsg[256];
05640          ten = (vms->curmsg + 1) / 10;
05641          one = (vms->curmsg + 1) % 10;
05642 
05643          if (vms->curmsg < 20) {
05644             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
05645             res = wait_file2(chan, vms, nextmsg);
05646          } else {
05647             snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
05648             res = wait_file2(chan, vms, nextmsg);
05649             if (one > 0) {
05650                if (!res) {
05651                   snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
05652                   res = wait_file2(chan, vms, nextmsg);
05653                }
05654             }
05655          }
05656       }
05657       if (!res)
05658          res = wait_file2(chan, vms, "vm-message");         
05659 
05660    } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH FORMAT */
05661       if (!vms->curmsg)
05662          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05663       else if (vms->curmsg == vms->lastmsg)
05664          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
05665       res = wait_file2(chan, vms, "vm-meddelandet");  /* "message" */
05666       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05667          if (!res)
05668             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05669       }
05670       /* We know that the difference between English and Swedish
05671        * is very small, however, we differ the two for standartization
05672        * purposes, and possible changes to either of these in the 
05673        * future
05674        */
05675    } else {
05676       if (!vms->curmsg)                      /* Default syntax */
05677          res = wait_file2(chan, vms, "vm-first");  /* "First" */
05678       else if (vms->curmsg == vms->lastmsg)
05679          res = wait_file2(chan, vms, "vm-last");      /* "last" */      
05680       res = wait_file2(chan, vms, "vm-message");
05681       if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
05682          if (!res)
05683             res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
05684       }
05685    }
05686 
05687    /* Retrieve info from VM attribute file */
05688    make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg);
05689    snprintf(filename, sizeof(filename), "%s.txt", vms->fn2);
05690    RETRIEVE(vms->curdir, vms->curmsg, vmu);
05691    msg_cfg = ast_config_load(filename);
05692    if (!msg_cfg) {
05693       ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
05694       return 0;
05695    }
05696 
05697    if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
05698       ast_log(LOG_WARNING, "No origtime?!\n");
05699       DISPOSE(vms->curdir, vms->curmsg);
05700       ast_config_destroy(msg_cfg);
05701       return 0;
05702    }
05703 
05704    cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
05705    duration = ast_variable_retrieve(msg_cfg, "message", "duration");
05706    category = ast_variable_retrieve(msg_cfg, "message", "category");
05707 
05708    context = ast_variable_retrieve(msg_cfg, "message", "context");
05709    if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */
05710       context = ast_variable_retrieve(msg_cfg, "message","macrocontext");
05711    if (!res)
05712       res = play_message_category(chan, category);
05713    if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE)))
05714       res = play_message_datetime(chan, vmu, origtime, filename);
05715    if ((!res) && (ast_test_flag(vmu, VM_SAYCID)))
05716       res = play_message_callerid(chan, vms, cid, context, 0);
05717    if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION)))
05718       res = play_message_duration(chan, vms, duration, vmu->saydurationm);
05719    /* Allow pressing '1' to skip envelope / callerid */
05720    if (res == '1')
05721       res = 0;
05722    ast_config_destroy(msg_cfg);
05723 
05724    if (!res) {
05725       make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
05726       vms->heard[vms->curmsg] = 1;
05727       if ((res = wait_file(chan, vms, vms->fn)) < 0) {
05728          ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn);
05729          res = 0;
05730       }
05731    }
05732    DISPOSE(vms->curdir, vms->curmsg);
05733    return res;
05734 }

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

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

05486 {
05487    int res = 0;
05488    int i;
05489    char *callerid, *name;
05490    char prefile[PATH_MAX] = "";
05491    
05492 
05493    /* If voicemail cid is not enabled, or we didn't get cid or context from the attribute file, leave now. */
05494    /* 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 */
05495    if ((cid == NULL)||(context == NULL))
05496       return res;
05497 
05498    /* Strip off caller ID number from name */
05499    if (option_debug > 2)
05500       ast_log(LOG_DEBUG, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
05501    ast_callerid_parse(cid, &name, &callerid);
05502    if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
05503       /* Check for internal contexts and only */
05504       /* say extension when the call didn't come from an internal context in the list */
05505       for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
05506          if (option_debug > 2)
05507             ast_log(LOG_DEBUG, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
05508          if ((strcmp(cidinternalcontexts[i], context) == 0))
05509             break;
05510       }
05511       if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
05512          if (!res) {
05513             snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
05514             if (!ast_strlen_zero(prefile)) {
05515             /* See if we can find a recorded name for this person instead of their extension number */
05516                if (ast_fileexists(prefile, NULL, NULL) > 0) {
05517                   if (option_verbose > 2)
05518                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
05519                   if (!callback)
05520                      res = wait_file2(chan, vms, "vm-from");
05521                   res = ast_stream_and_wait(chan, prefile, chan->language, "");
05522                } else {
05523                   if (option_verbose > 2)
05524                      ast_verbose(VERBOSE_PREFIX_3 "Playing envelope info: message from '%s'\n", callerid);
05525                   /* BB: Say "from extension" as one saying to sound smoother */
05526                   if (!callback)
05527                      res = wait_file2(chan, vms, "vm-from-extension");
05528                   res = ast_say_digit_str(chan, callerid, "", chan->language);
05529                }
05530             }
05531          }
05532       }
05533 
05534       else if (!res){
05535          if (option_debug > 2)
05536             ast_log(LOG_DEBUG, "VM-CID: Numeric caller id: (%s)\n",callerid);
05537          /* BB: Since this is all nicely figured out, why not say "from phone number" in this case" */
05538          if (!callback)
05539             res = wait_file2(chan, vms, "vm-from-phonenumber");
05540          res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
05541       }
05542    } else {
05543       /* Number unknown */
05544       if (option_debug)
05545          ast_log(LOG_DEBUG, "VM-CID: From an unknown number\n");
05546       /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
05547       res = wait_file2(chan, vms, "vm-unknown-caller");
05548    }
05549    return res;
05550 }

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

Definition at line 5397 of file app_voicemail.c.

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

Referenced by play_message().

05398 {
05399    int res = 0;
05400 
05401    if (!ast_strlen_zero(category))
05402       res = ast_play_and_wait(chan, category);
05403 
05404    if (res) {
05405       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05406       res = 0;
05407    }
05408 
05409    return res;
05410 }

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

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

05413 {
05414    int res = 0;
05415    struct vm_zone *the_zone = NULL;
05416    time_t t;
05417 
05418    if (ast_get_time_t(origtime, &t, 0, NULL)) {
05419       ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename);
05420       return 0;
05421    }
05422 
05423    /* Does this user have a timezone specified? */
05424    if (!ast_strlen_zero(vmu->zonetag)) {
05425       /* Find the zone in the list */
05426       struct vm_zone *z;
05427       AST_LIST_LOCK(&zones);
05428       AST_LIST_TRAVERSE(&zones, z, list) {
05429          if (!strcmp(z->name, vmu->zonetag)) {
05430             the_zone = z;
05431             break;
05432          }
05433       }
05434       AST_LIST_UNLOCK(&zones);
05435    }
05436 
05437 /* No internal variable parsing for now, so we'll comment it out for the time being */
05438 #if 0
05439    /* Set the DIFF_* variables */
05440    ast_localtime(&t, &time_now, NULL);
05441    tv_now = ast_tvnow();
05442    tnow = tv_now.tv_sec;
05443    ast_localtime(&tnow, &time_then, NULL);
05444 
05445    /* Day difference */
05446    if (time_now.tm_year == time_then.tm_year)
05447       snprintf(temp,sizeof(temp),"%d",time_now.tm_yday);
05448    else
05449       snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
05450    pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
05451 
05452    /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
05453 #endif
05454    if (the_zone) {
05455       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
05456    } else if (!strncasecmp(chan->language, "de", 2)) {    /* GERMAN syntax */
05457       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05458    } else if (!strncasecmp(chan->language, "gr", 2)) {    /* GREEK syntax */
05459       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q  H 'digits/kai' M ", NULL);
05460    } else if (!strncasecmp(chan->language, "he", 2)) {    /* HEBREW syntax */
05461       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'at2' kM", NULL);
05462    } else if (!strncasecmp(chan->language, "it", 2)) {    /* ITALIAN syntax */
05463       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);
05464    } else if (!strncasecmp(chan->language, "nl", 2)) {    /* DUTCH syntax */
05465       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
05466    } else if (!strncasecmp(chan->language, "no", 2)) {    /* NORWEGIAN syntax */
05467       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
05468    } else if (!strncasecmp(chan->language, "pl", 2)) {    /* POLISH syntax */
05469       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
05470    } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* PORTUGUESE syntax */
05471       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);
05472    } else if (!strncasecmp(chan->language, "se", 2)) {    /* SWEDISH syntax */
05473       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
05474    } else {
05475       res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
05476    }
05477 #if 0
05478    pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
05479 #endif
05480    return res;
05481 }

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

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

05553 {
05554    int res = 0;
05555    int durationm;
05556    int durations;
05557    /* Verify that we have a duration for the message */
05558    if (duration == NULL)
05559       return res;
05560 
05561    /* Convert from seconds to minutes */
05562    durations=atoi(duration);
05563    durationm=(durations / 60);
05564 
05565    if (option_debug > 2)
05566       ast_log(LOG_DEBUG, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
05567 
05568    if ((!res) && (durationm >= minduration)) {
05569       res = wait_file2(chan, vms, "vm-duration");
05570 
05571       /* POLISH syntax */
05572       if (!strncasecmp(chan->language, "pl", 2)) {
05573          div_t num = div(durationm, 10);
05574 
05575          if (durationm == 1) {
05576             res = ast_play_and_wait(chan, "digits/1z");
05577             res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
05578          } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
05579             if (num.rem == 2) {
05580                if (!num.quot) {
05581                   res = ast_play_and_wait(chan, "digits/2-ie");
05582                } else {
05583                   res = say_and_wait(chan, durationm - 2 , chan->language);
05584                   res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
05585                }
05586             } else {
05587                res = say_and_wait(chan, durationm, chan->language);
05588             }
05589             res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
05590          } else {
05591             res = say_and_wait(chan, durationm, chan->language);
05592             res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
05593          }
05594       /* DEFAULT syntax */
05595       } else {
05596          res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
05597          res = wait_file2(chan, vms, "vm-minutes");
05598       }
05599    }
05600    return res;
05601 }

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

09152 {
09153    /* Record message & let caller review or re-record it, or set options if applicable */
09154    int res = 0;
09155    int cmd = 0;
09156    int max_attempts = 3;
09157    int attempts = 0;
09158    int recorded = 0;
09159    int message_exists = 0;
09160    signed char zero_gain = 0;
09161    char tempfile[PATH_MAX];
09162    char *acceptdtmf = "#";
09163    char *canceldtmf = "";
09164 
09165    /* Note that urgent and private are for flagging messages as such in the future */
09166 
09167    /* barf if no pointer passed to store duration in */
09168    if (duration == NULL) {
09169       ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
09170       return -1;
09171    }
09172 
09173    if (!outsidecaller)
09174       snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
09175    else
09176       ast_copy_string(tempfile, recordfile, sizeof(tempfile));
09177 
09178    cmd = '3';  /* Want to start by recording */
09179 
09180    while ((cmd >= 0) && (cmd != 't')) {
09181       switch (cmd) {
09182       case '1':
09183          if (!message_exists) {
09184             /* In this case, 1 is to record a message */
09185             cmd = '3';
09186             break;
09187          } else {
09188             /* Otherwise 1 is to save the existing message */
09189             if (option_verbose > 2)
09190                ast_verbose(VERBOSE_PREFIX_3 "Saving message as is\n");
09191             if (!outsidecaller)
09192                ast_filerename(tempfile, recordfile, NULL);
09193             ast_stream_and_wait(chan, "vm-msgsaved", chan->language, "");
09194             if (!outsidecaller) {
09195                STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms);
09196                DISPOSE(recordfile, -1);
09197             }
09198             cmd = 't';
09199             return res;
09200          }
09201       case '2':
09202          /* Review */
09203          if (option_verbose > 2)
09204             ast_verbose(VERBOSE_PREFIX_3 "Reviewing the message\n");
09205          cmd = ast_stream_and_wait(chan, tempfile, chan->language, AST_DIGIT_ANY);
09206          break;
09207       case '3':
09208          message_exists = 0;
09209          /* Record */
09210          if (recorded == 1) {
09211             if (option_verbose > 2)
09212                ast_verbose(VERBOSE_PREFIX_3 "Re-recording the message\n");
09213          } else { 
09214             if (option_verbose > 2)
09215                ast_verbose(VERBOSE_PREFIX_3 "Recording the message\n");
09216          }
09217          if (recorded && outsidecaller) {
09218             cmd = ast_play_and_wait(chan, INTRO);
09219             cmd = ast_play_and_wait(chan, "beep");
09220          }
09221          recorded = 1;
09222          /* 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 */
09223          if (record_gain)
09224             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
09225          if (ast_test_flag(vmu, VM_OPERATOR))
09226             canceldtmf = "0";
09227          cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
09228          if (record_gain)
09229             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
09230          if (cmd == -1) {
09231             /* User has hung up, no options to give */
09232             if (!outsidecaller) {
09233                /* user was recording a greeting and they hung up, so let's delete the recording. */
09234                ast_filedelete(tempfile, NULL);
09235             }
09236             return cmd;
09237          }
09238          if (cmd == '0') {
09239             break;
09240          } else if (cmd == '*') {
09241             break;
09242          } 
09243 #if 0       
09244          else if (vmu->review && (*duration < 5)) {
09245             /* Message is too short */
09246             if (option_verbose > 2)
09247                ast_verbose(VERBOSE_PREFIX_3 "Message too short\n");
09248             cmd = ast_play_and_wait(chan, "vm-tooshort");
09249             cmd = ast_filedelete(tempfile, NULL);
09250             break;
09251          }
09252          else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) {
09253             /* Message is all silence */
09254             if (option_verbose > 2)
09255                ast_verbose(VERBOSE_PREFIX_3 "Nothing recorded\n");
09256             cmd = ast_filedelete(tempfile, NULL);
09257             cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
09258             if (!cmd)
09259                cmd = ast_play_and_wait(chan, "vm-speakup");
09260             break;
09261          }
09262 #endif
09263          else {
09264             /* If all is well, a message exists */
09265             message_exists = 1;
09266             cmd = 0;
09267          }
09268          break;
09269       case '4':
09270       case '5':
09271       case '6':
09272       case '7':
09273       case '8':
09274       case '9':
09275       case '*':
09276       case '#':
09277          cmd = ast_play_and_wait(chan, "vm-sorry");
09278          break;
09279 #if 0 
09280 /*  XXX Commented out for the moment because of the dangers of deleting
09281     a message while recording (can put the message numbers out of sync) */
09282       case '*':
09283          /* Cancel recording, delete message, offer to take another message*/
09284          cmd = ast_play_and_wait(chan, "vm-deleted");
09285          cmd = ast_filedelete(tempfile, NULL);
09286          if (outsidecaller) {
09287             res = vm_exec(chan, NULL);
09288             return res;
09289          }
09290          else
09291             return 1;
09292 #endif
09293       case '0':
09294          if (!ast_test_flag(vmu, VM_OPERATOR)) {
09295             cmd = ast_play_and_wait(chan, "vm-sorry");
09296             break;
09297          }
09298          if (message_exists || recorded) {
09299             cmd = ast_play_and_wait(chan, "vm-saveoper");
09300             if (!cmd)
09301                cmd = ast_waitfordigit(chan, 3000);
09302             if (cmd == '1') {
09303                ast_play_and_wait(chan, "vm-msgsaved");
09304                cmd = '0';
09305             } else {
09306                ast_play_and_wait(chan, "vm-deleted");
09307                DELETE(recordfile, -1, recordfile, vmu);
09308                cmd = '0';
09309             }
09310          }
09311          return cmd;
09312       default:
09313          /* If the caller is an ouside caller, and the review option is enabled,
09314             allow them to review the message, but let the owner of the box review
09315             their OGM's */
09316          if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
09317             return cmd;
09318          if (message_exists) {
09319             cmd = ast_play_and_wait(chan, "vm-review");
09320          }
09321          else {
09322             cmd = ast_play_and_wait(chan, "vm-torerecord");
09323             if (!cmd)
09324                cmd = ast_waitfordigit(chan, 600);
09325          }
09326          
09327          if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
09328             cmd = ast_play_and_wait(chan, "vm-reachoper");
09329             if (!cmd)
09330                cmd = ast_waitfordigit(chan, 600);
09331          }
09332 #if 0
09333          if (!cmd)
09334             cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
09335 #endif
09336          if (!cmd)
09337             cmd = ast_waitfordigit(chan, 6000);
09338          if (!cmd) {
09339             attempts++;
09340          }
09341          if (attempts > max_attempts) {
09342             cmd = 't';
09343          }
09344       }
09345    }
09346    if (outsidecaller)
09347       ast_play_and_wait(chan, "vm-goodbye");
09348    if (cmd == 't')
09349       cmd = 0;
09350    return cmd;
09351 }

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

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

00608 {
00609    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00610    if (saydurationminfo)
00611       vmu->saydurationm = saydurationminfo;
00612    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00613    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00614    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00615    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00616    if (maxmsg)
00617       vmu->maxmsg = maxmsg;
00618    vmu->volgain = volgain;
00619 }

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

03018 {
03019    char callerid[256];
03020    char fromdir[256], fromfile[256];
03021    struct ast_config *msg_cfg;
03022    const char *origcallerid, *origtime;
03023    char origcidname[80], origcidnum[80], origdate[80];
03024    int inttime;
03025 
03026    /* Prepare variables for substition in email body and subject */
03027    pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
03028    pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
03029    snprintf(passdata, passdatasize, "%d", msgnum);
03030    pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata);
03031    pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
03032    pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
03033    pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
03034       ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
03035    pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
03036    pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
03037    pbx_builtin_setvar_helper(ast, "VM_DATE", date);
03038    pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
03039 
03040    /* Retrieve info from VM attribute file */
03041    make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
03042    make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
03043    if (strlen(fromfile) < sizeof(fromfile) - 5) {
03044       strcat(fromfile, ".txt");
03045    }
03046    if (!(msg_cfg = ast_config_load(fromfile))) {
03047       if (option_debug > 0) {
03048          ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
03049       }
03050       return;
03051    }
03052 
03053    if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
03054       pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
03055       ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
03056       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
03057       pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
03058    }
03059 
03060    if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) {
03061       time_t ttime = inttime;
03062       struct tm tm;
03063       ast_localtime(&ttime, &tm, NULL);
03064       strftime(origdate, sizeof(origdate), emaildateformat, &tm);
03065       pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
03066    }
03067    ast_config_destroy(msg_cfg);
03068 }

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

Definition at line 3070 of file app_voicemail.c.

03071 {
03072    char *ptr = to;
03073    *ptr++ = '"';
03074    for (; ptr < to + len - 1; from++) {
03075       if (*from == '"')
03076          *ptr++ = '\\';
03077       else if (*from == '\0')
03078          break;
03079       *ptr++ = *from;
03080    }
03081    if (ptr < to + len - 1)
03082       *ptr++ = '"';
03083    *ptr = '\0';
03084    return to;
03085 }

static int reload ( void   )  [static]

Definition at line 8835 of file app_voicemail.c.

References load_config().

08836 {
08837    return(load_config());
08838 }

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

Definition at line 2762 of file app_voicemail.c.

References ast_filerename().

02763 {
02764    char stxt[PATH_MAX];
02765    char dtxt[PATH_MAX];
02766    ast_filerename(sfn,dfn,NULL);
02767    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02768    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02769    rename(stxt, dtxt);
02770 }

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

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

04372 {
04373    /* we know max messages, so stop process when number is hit */
04374 
04375    int x,dest;
04376    char sfn[PATH_MAX];
04377    char dfn[PATH_MAX];
04378 
04379    if (vm_lock_path(dir))
04380       return ERROR_LOCK_PATH;
04381 
04382    for (x = 0, dest = 0; x < vmu->maxmsg; x++) {
04383       make_file(sfn, sizeof(sfn), dir, x);
04384       if (EXISTS(dir, x, sfn, NULL)) {
04385          
04386          if (x != dest) {
04387             make_file(dfn, sizeof(dfn), dir, dest);
04388             RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
04389          }
04390          
04391          dest++;
04392       }
04393    }
04394    ast_unlock_path(dir);
04395 
04396    return 0;
04397 }

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

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

00822 {
00823    /* This function could be made to generate one from a database, too */
00824    struct ast_vm_user *cur;
00825    int res = -1;
00826    AST_LIST_LOCK(&users);
00827    AST_LIST_TRAVERSE(&users, cur, list) {
00828       if ((!context || !strcasecmp(context, cur->context)) &&
00829          (!strcasecmp(mailbox, cur->mailbox)))
00830             break;
00831    }
00832    if (cur) {
00833       ast_copy_string(cur->password, newpass, sizeof(cur->password));
00834       res = 0;
00835    }
00836    AST_LIST_UNLOCK(&users);
00837    return res;
00838 }

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

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

03939 {
03940    char arguments[255];
03941    char ext_context[256] = "";
03942    int newvoicemails = 0, oldvoicemails = 0;
03943    struct ast_smdi_mwi_message *mwi_msg;
03944 
03945    if (!ast_strlen_zero(context))
03946       snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
03947    else
03948       ast_copy_string(ext_context, extension, sizeof(ext_context));
03949 
03950    if (!strcasecmp(externnotify, "smdi")) {
03951       if (ast_app_has_voicemail(ext_context, NULL)) 
03952          ast_smdi_mwi_set(smdi_iface, extension);
03953       else
03954          ast_smdi_mwi_unset(smdi_iface, extension);
03955 
03956       if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) {
03957          ast_log(LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
03958          if (!strncmp(mwi_msg->cause, "INV", 3))
03959             ast_log(LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
03960          else if (!strncmp(mwi_msg->cause, "BLK", 3))
03961             ast_log(LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
03962          ast_log(LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
03963          ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy);
03964       } else {
03965          if (option_debug)
03966             ast_log(LOG_DEBUG, "Successfully executed SMDI MWI change for %s\n", extension);
03967       }
03968    } else if (!ast_strlen_zero(externnotify)) {
03969       if (inboxcount(ext_context, &newvoicemails, &oldvoicemails)) {
03970          ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
03971       } else {
03972          snprintf(arguments, sizeof(arguments), "%s %s %s %d&", externnotify, context, extension, newvoicemails);
03973          if (option_debug)
03974             ast_log(LOG_DEBUG, "Executing %s\n", arguments);
03975          ast_safe_system(arguments);
03976       }
03977    }
03978 }

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

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

04408 {
04409 #ifdef IMAP_STORAGE
04410    /* we must use mbox(x) folder names, and copy the message there */
04411    /* simple. huh? */
04412    char sequence[10];
04413    /* get the real IMAP message number for this message */
04414    snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
04415    if (option_debug > 2)
04416       ast_log(LOG_DEBUG, "Copying sequence %s to mailbox %s\n",sequence,(char *) mbox(box));
04417    ast_mutex_lock(&vms->lock);
04418    if (box == 1) {
04419       mail_setflag(vms->mailstream, sequence, "\\Seen");
04420    } else if (box == 0) {
04421       mail_clearflag(vms->mailstream, sequence, "\\Seen");
04422    }
04423    if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
04424       ast_mutex_unlock(&vms->lock);
04425       return 0;
04426    } else {
04427       int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
04428       ast_mutex_unlock(&vms->lock);
04429       return res;
04430    }
04431 #else
04432    char *dir = vms->curdir;
04433    char *username = vms->username;
04434    char *context = vmu->context;
04435    char sfn[PATH_MAX];
04436    char dfn[PATH_MAX];
04437    char ddir[PATH_MAX];
04438    const char *dbox = mbox(box);
04439    int x;
04440    make_file(sfn, sizeof(sfn), dir, msg);
04441    create_dirpath(ddir, sizeof(ddir), context, username, dbox);
04442 
04443    if (vm_lock_path(ddir))
04444       return ERROR_LOCK_PATH;
04445 
04446    for (x = 0; x < vmu->maxmsg; x++) {
04447       make_file(dfn, sizeof(dfn), ddir, x);
04448       if (!EXISTS(ddir, x, dfn, NULL))
04449          break;
04450    }
04451    if (x >= vmu->maxmsg) {
04452       ast_unlock_path(ddir);
04453       return ERROR_MAILBOX_FULL;
04454    }
04455    if (strcmp(sfn, dfn)) {
04456       COPY(dir, msg, ddir, x, username, context, sfn, dfn);
04457    }
04458    ast_unlock_path(ddir);
04459 #endif
04460    return 0;
04461 }

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

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

04401 {
04402    int d;
04403    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04404    return d;
04405 }

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

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

Referenced by forward_message(), and notify_new_message().

03450 {
03451    FILE *p=NULL;
03452    char tmp[80] = "/tmp/astmail-XXXXXX";
03453    char tmp2[256];
03454 
03455    if (vmu && ast_strlen_zero(vmu->email)) {
03456       ast_log(LOG_WARNING, "E-mail address missing for mailbox [%s].  E-mail will not be sent.\n", vmu->mailbox);
03457       return(0);
03458    }
03459    if (!strcmp(format, "wav49"))
03460       format = "WAV";
03461    if (option_debug > 2)
03462       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));
03463    /* Make a temporary file instead of piping directly to sendmail, in case the mail
03464       command hangs */
03465    if ((p = vm_mkftemp(tmp)) == NULL) {
03466       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03467       return -1;
03468    } else {
03469       make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, format, duration, attach_user_voicemail, chan, category, 0);
03470       fclose(p);
03471       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03472       ast_safe_system(tmp2);
03473       if (option_debug > 2)
03474          ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
03475    }
03476    return 0;
03477 }

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

03480 {
03481    char date[256];
03482    char host[MAXHOSTNAMELEN] = "";
03483    char who[256];
03484    char dur[PATH_MAX];
03485    char tmp[80] = "/tmp/astmail-XXXXXX";
03486    char tmp2[PATH_MAX];
03487    struct tm tm;
03488    FILE *p;
03489 
03490    if ((p = vm_mkftemp(tmp)) == NULL) {
03491       ast_log(LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
03492       return -1;
03493    } else {
03494       gethostname(host, sizeof(host)-1);
03495       if (strchr(srcemail, '@'))
03496          ast_copy_string(who, srcemail, sizeof(who));
03497       else {
03498          snprintf(who, sizeof(who), "%s@%s", srcemail, host);
03499       }
03500       snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
03501       strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
03502       fprintf(p, "Date: %s\n", date);
03503 
03504       if (*pagerfromstring) {
03505          struct ast_channel *ast;
03506          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03507             char *passdata;
03508             int vmlen = strlen(fromstring)*3 + 200;
03509             if ((passdata = alloca(vmlen))) {
03510                memset(passdata, 0, vmlen);
03511                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03512                pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen);
03513                fprintf(p, "From: %s <%s>\n", passdata, who);
03514             } else 
03515                ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03516             ast_channel_free(ast);
03517          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03518       } else
03519          fprintf(p, "From: Asterisk PBX <%s>\n", who);
03520       fprintf(p, "To: %s\n", pager);
03521       if (pagersubject) {
03522          struct ast_channel *ast;
03523          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03524             char *passdata;
03525             int vmlen = strlen(pagersubject) * 3 + 200;
03526             if ((passdata = alloca(vmlen))) {
03527                memset(passdata, 0, vmlen);
03528                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03529                pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen);
03530                fprintf(p, "Subject: %s\n\n", passdata);
03531             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03532             ast_channel_free(ast);
03533          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03534       } else
03535          fprintf(p, "Subject: New VM\n\n");
03536       strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm);
03537       if (pagerbody) {
03538          struct ast_channel *ast;
03539          if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) {
03540             char *passdata;
03541             int vmlen = strlen(pagerbody)*3 + 200;
03542             if ((passdata = alloca(vmlen))) {
03543                memset(passdata, 0, vmlen);
03544                prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category);
03545                pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen);
03546                fprintf(p, "%s\n", passdata);
03547             } else ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
03548          ast_channel_free(ast);
03549          } else ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
03550       } else {
03551          fprintf(p, "New %s long msg in box %s\n"
03552                "from %s, on %s", dur, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
03553       }
03554       fclose(p);
03555       snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
03556       ast_safe_system(tmp2);
03557       if (option_debug > 2)
03558          ast_log(LOG_DEBUG, "Sent page to %s with command '%s'\n", pager, mailcmd);
03559    }
03560    return 0;
03561 }

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

Referenced by make_email_file().

00592 {
00593    char *bufptr = buf;
00594    for (; *input; input++) {
00595       if (*input < 32) {
00596          continue;
00597       }
00598       *bufptr++ = *input;
00599       if (bufptr == buf + buflen - 1) {
00600          break;
00601       }
00602    }
00603    *bufptr = '\0';
00604    return buf;
00605 }

static int unload_module ( void   )  [static]

Definition at line 8840 of file app_voicemail.c.

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

08841 {
08842    int res;
08843    
08844    res = ast_unregister_application(app);
08845    res |= ast_unregister_application(app2);
08846    res |= ast_unregister_application(app3);
08847    res |= ast_unregister_application(app4);
08848    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08849    ast_uninstall_vm_functions();
08850    
08851    ast_module_user_hangup_all();
08852 
08853    return res;
08854 }

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

07197 {
07198    int useadsi=0, valid=0, logretries=0;
07199    char password[AST_MAX_EXTENSION]="", *passptr;
07200    struct ast_vm_user vmus, *vmu = NULL;
07201 
07202    /* If ADSI is supported, setup login screen */
07203    adsi_begin(chan, &useadsi);
07204    if (!skipuser && useadsi)
07205       adsi_login(chan);
07206    if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
07207       ast_log(LOG_WARNING, "Couldn't stream login file\n");
07208       return -1;
07209    }
07210    
07211    /* Authenticate them and get their mailbox/password */
07212    
07213    while (!valid && (logretries < maxlogins)) {
07214       /* Prompt for, and read in the username */
07215       if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
07216          ast_log(LOG_WARNING, "Couldn't read username\n");
07217          return -1;
07218       }
07219       if (ast_strlen_zero(mailbox)) {
07220          if (chan->cid.cid_num) {
07221             ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size);
07222          } else {
07223             if (option_verbose > 2)
07224                ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");  
07225             return -1;
07226          }
07227       }
07228       if (useadsi)
07229          adsi_password(chan);
07230 
07231       if (!ast_strlen_zero(prefix)) {
07232          char fullusername[80] = "";
07233          ast_copy_string(fullusername, prefix, sizeof(fullusername));
07234          strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
07235          ast_copy_string(mailbox, fullusername, mailbox_size);
07236       }
07237 
07238       if (option_debug)
07239          ast_log(LOG_DEBUG, "Before find user for mailbox %s\n",mailbox);
07240       vmu = find_user(&vmus, context, mailbox);
07241       if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
07242          /* saved password is blank, so don't bother asking */
07243          password[0] = '\0';
07244       } else {
07245          if (ast_streamfile(chan, "vm-password", chan->language)) {
07246             ast_log(LOG_WARNING, "Unable to stream password file\n");
07247             return -1;
07248          }
07249          if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
07250             ast_log(LOG_WARNING, "Unable to read password\n");
07251             return -1;
07252          }
07253       }
07254 
07255       if (vmu) {
07256          passptr = vmu->password;
07257          if (passptr[0] == '-') passptr++;
07258       }
07259       if (vmu && !strcmp(passptr, password))
07260          valid++;
07261       else {
07262          if (option_verbose > 2)
07263             ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
07264          if (!ast_strlen_zero(prefix))
07265             mailbox[0] = '\0';
07266       }
07267       logretries++;
07268       if (!valid) {
07269          if (skipuser || logretries >= maxlogins) {
07270             if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
07271                ast_log(LOG_WARNING, "Unable to stream incorrect message\n");
07272                return -1;
07273             }
07274          } else {
07275             if (useadsi)
07276                adsi_login(chan);
07277             if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
07278                ast_log(LOG_WARNING, "Unable to stream incorrect mailbox message\n");
07279                return -1;
07280             }
07281          }
07282          if (ast_waitstream(chan, "")) /* Channel is hung up */
07283             return -1;
07284       }
07285    }
07286    if (!valid && (logretries >= maxlogins)) {
07287       ast_stopstream(chan);
07288       ast_play_and_wait(chan, "vm-goodbye");
07289       return -1;
07290    }
07291    if (vmu && !skipuser) {
07292       memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
07293    }
07294    return 0;
07295 }

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

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

08031 {
08032    struct ast_module_user *u;
08033    struct ast_vm_user svm;
08034    char *context, *box;
08035    int priority_jump = 0;
08036    AST_DECLARE_APP_ARGS(args,
08037       AST_APP_ARG(mbox);
08038       AST_APP_ARG(options);
08039    );
08040 
08041    if (ast_strlen_zero(data)) {
08042       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
08043       return -1;
08044    }
08045 
08046    u = ast_module_user_add(chan);
08047 
08048    box = ast_strdupa(data);
08049 
08050    AST_STANDARD_APP_ARGS(args, box);
08051 
08052    if (args.options) {
08053       if (strchr(args.options, 'j'))
08054          priority_jump = 1;
08055    }
08056 
08057    if ((context = strchr(args.mbox, '@'))) {
08058       *context = '\0';
08059       context++;
08060    }
08061 
08062    if (find_user(&svm, context, args.mbox)) {
08063       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
08064       if (priority_jump || ast_opt_priority_jumping)
08065          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
08066             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);
08067    } else
08068       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
08069    ast_module_user_remove(u);
08070    return 0;
08071 }

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

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

07179 {
07180    if (!strncasecmp(chan->language, "es", 2) ||
07181          !strncasecmp(chan->language, "it", 2) ||
07182          !strncasecmp(chan->language, "pt", 2) ||
07183          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
07184       return vm_browse_messages_latin(chan, vms, vmu);
07185    } else if (!strncasecmp(chan->language, "gr", 2)) {  /* GREEK */
07186       return vm_browse_messages_gr(chan, vms, vmu);
07187    } else if (!strncasecmp(chan->language, "he", 2)) {  /* HEBREW */
07188       return vm_browse_messages_he(chan, vms, vmu);
07189    } else {                                             /* Default to English syntax */
07190       return vm_browse_messages_en(chan, vms, vmu);
07191    }
07192 }

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

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

07114 {
07115    int cmd=0;
07116 
07117    if (vms->lastmsg > -1) {
07118       cmd = play_message(chan, vmu, vms);
07119    } else {
07120       cmd = ast_play_and_wait(chan, "vm-youhave");
07121       if (!cmd) 
07122          cmd = ast_play_and_wait(chan, "vm-no");
07123       if (!cmd) {
07124          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07125          cmd = ast_play_and_wait(chan, vms->fn);
07126       }
07127       if (!cmd)
07128          cmd = ast_play_and_wait(chan, "vm-messages");
07129    }
07130    return cmd;
07131 }

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

Definition at line 7134 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07135 {
07136    int cmd = 0;
07137 
07138    if (vms->lastmsg > -1) {
07139       cmd = play_message(chan, vmu, vms);
07140    } else {
07141       if (!strcasecmp(vms->fn, "INBOX")) {
07142          cmd = ast_play_and_wait(chan, "vm-nonewmessages");
07143       } else {
07144          cmd = ast_play_and_wait(chan, "vm-nomessages");
07145       }
07146    }
07147    return cmd;
07148 }

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

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

07152 {
07153    int cmd=0;
07154 
07155    if (vms->lastmsg > -1) {
07156       cmd = play_message(chan, vmu, vms);
07157    } else {
07158       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07159       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
07160          if (!cmd) {
07161             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07162             cmd = ast_play_and_wait(chan, vms->fn);
07163          }
07164          if (!cmd)
07165             cmd = ast_play_and_wait(chan, "vm-messages");
07166       } else {
07167          if (!cmd)
07168             cmd = ast_play_and_wait(chan, "vm-messages");
07169          if (!cmd) {
07170             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07171             cmd = ast_play_and_wait(chan, vms->fn);
07172          }
07173       }
07174    }
07175    return cmd;
07176 }

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

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

00841 {
00842    struct ast_config   *cfg=NULL;
00843    struct ast_variable *var=NULL;
00844    struct ast_category *cat=NULL;
00845    char *category=NULL, *value=NULL, *new=NULL;
00846    const char *tmp=NULL;
00847                
00848    if (!change_password_realtime(vmu, newpassword))
00849       return;
00850 
00851    /* check voicemail.conf */
00852    if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
00853       while ((category = ast_category_browse(cfg, category))) {
00854          if (!strcasecmp(category, vmu->context)) {
00855             tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
00856             if (!tmp) {
00857                ast_log(LOG_WARNING, "We could not find the mailbox.\n");
00858                break;
00859             }
00860             value = strstr(tmp,",");
00861             if (!value) {
00862                ast_log(LOG_WARNING, "variable has bad format.\n");
00863                break;
00864             }
00865             new = alloca((strlen(value)+strlen(newpassword)+1));
00866             sprintf(new,"%s%s", newpassword, value);
00867             if (!(cat = ast_category_get(cfg, category))) {
00868                ast_log(LOG_WARNING, "Failed to get category structure.\n");
00869                break;
00870             }
00871             ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
00872          }
00873       }
00874       /* save the results */
00875       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00876       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00877       config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
00878    }
00879    category = NULL;
00880    var = NULL;
00881    /* check users.conf and update the password stored for the mailbox*/
00882    /* if no vmsecret entry exists create one. */
00883    if ((cfg = ast_config_load_with_comments("users.conf"))) {
00884       if (option_debug > 3)
00885          ast_log(LOG_DEBUG, "we are looking for %s\n", vmu->mailbox);
00886       while ((category = ast_category_browse(cfg, category))) {
00887          if (option_debug > 3)
00888             ast_log(LOG_DEBUG, "users.conf: %s\n", category);
00889          if (!strcasecmp(category, vmu->mailbox)) {
00890             if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
00891                if (option_debug > 3)
00892                   ast_log(LOG_DEBUG, "looks like we need to make vmsecret!\n");
00893                var = ast_variable_new("vmsecret", newpassword);
00894             } 
00895             new = alloca(strlen(newpassword)+1);
00896             sprintf(new, "%s", newpassword);
00897             if (!(cat = ast_category_get(cfg, category))) {
00898                if (option_debug > 3)
00899                   ast_log(LOG_DEBUG, "failed to get category!\n");
00900                break;
00901             }
00902             if (!var)      
00903                ast_variable_update(cat, "vmsecret", new, NULL, 0);
00904             else
00905                ast_variable_append(cat, var);
00906          }
00907       }
00908       /* save the results and clean things up */
00909       reset_user_pw(vmu->context, vmu->mailbox, newpassword);  
00910       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00911       config_text_file_save("users.conf", cfg, "AppVoicemail");
00912    }
00913 }

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

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

00916 {
00917    char buf[255];
00918    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00919    if (!ast_safe_system(buf)) {
00920       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00921       /* Reset the password in memory, too */
00922       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00923    }
00924 }

static int vm_delete ( char *  file  )  [static]

Definition at line 2882 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message(), and forward_message().

02883 {
02884    char *txt;
02885    int txtsize = 0;
02886 
02887    txtsize = (strlen(file) + 5)*sizeof(char);
02888    txt = alloca(txtsize);
02889    /* Sprintf here would safe because we alloca'd exactly the right length,
02890     * but trying to eliminate all sprintf's anyhow
02891     */
02892    snprintf(txt, txtsize, "%s.txt", file);
02893    unlink(txt);
02894    return ast_filedelete(file, NULL);
02895 }

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

Definition at line 7875 of file app_voicemail.c.

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

Referenced by load_module(), and play_record_review().

07876 {
07877    int res = 0;
07878    struct ast_module_user *u;
07879    char *tmp;
07880    struct leave_vm_options leave_options;
07881    struct ast_flags flags = { 0 };
07882    static int deprecate_warning = 0;
07883    char *opts[OPT_ARG_ARRAY_SIZE];
07884    AST_DECLARE_APP_ARGS(args,
07885       AST_APP_ARG(argv0);
07886       AST_APP_ARG(argv1);
07887    );
07888 
07889    u = ast_module_user_add(chan);
07890    
07891    memset(&leave_options, 0, sizeof(leave_options));
07892 
07893    if (chan->_state != AST_STATE_UP)
07894       ast_answer(chan);
07895 
07896    if (!ast_strlen_zero(data)) {
07897       tmp = ast_strdupa(data);
07898       AST_STANDARD_APP_ARGS(args, tmp);
07899       if (args.argc == 2) {
07900          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07901             ast_module_user_remove(u);
07902             return -1;
07903          }
07904          ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_PRIORITY_JUMP);
07905          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07906             int gain;
07907 
07908             if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
07909                ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07910                ast_module_user_remove(u);
07911                return -1;
07912             } else {
07913                leave_options.record_gain = (signed char) gain;
07914             }
07915          }
07916       } else {
07917          /* old style options parsing */
07918          int old = 0;
07919          char *orig_argv0 = args.argv0;
07920          while (*(args.argv0)) {
07921             if (*(args.argv0) == 's') {
07922                old = 1;
07923                ast_set_flag(&leave_options, OPT_SILENT);
07924             } else if (*(args.argv0) == 'b') {
07925                old = 1;
07926                ast_set_flag(&leave_options, OPT_BUSY_GREETING);
07927             } else if (*(args.argv0) == 'u') {
07928                old = 1;
07929                ast_set_flag(&leave_options, OPT_UNAVAIL_GREETING);
07930             } else if (*(args.argv0) == 'j') {
07931                old = 1;
07932                ast_set_flag(&leave_options, OPT_PRIORITY_JUMP);
07933             } else
07934                break;
07935             (args.argv0)++;
07936          }
07937          if (!deprecate_warning && old) {
07938             deprecate_warning = 1;
07939             ast_log(LOG_WARNING, "Prefixing the mailbox with an option is deprecated ('%s').\n", orig_argv0);
07940             ast_log(LOG_WARNING, "Please move all leading options to the second argument.\n");
07941          }
07942       }
07943    } else {
07944       char tmp[256];
07945       res = ast_app_getdata(chan, "vm-whichbox", tmp, sizeof(tmp) - 1, 0);
07946       if (res < 0) {
07947          ast_module_user_remove(u);
07948          return res;
07949       }
07950       if (ast_strlen_zero(tmp)) {
07951          ast_module_user_remove(u);
07952          return 0;
07953       }
07954       args.argv0 = ast_strdupa(tmp);
07955    }
07956 
07957    res = leave_voicemail(chan, args.argv0, &leave_options);
07958 
07959    if (res == ERROR_LOCK_PATH) {
07960       ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
07961       /*Send the call to n+101 priority, where n is the current priority*/
07962       if (ast_test_flag(&leave_options, OPT_PRIORITY_JUMP) || ast_opt_priority_jumping)
07963          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
07964             ast_log(LOG_WARNING, "Extension %s, priority %d doesn't exist.\n", chan->exten, chan->priority + 101);
07965       pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
07966       res = 0;
07967    }
07968    
07969    ast_module_user_remove(u);
07970 
07971    return res;
07972 }

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

Definition at line 7297 of file app_voicemail.c.

References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_parse_options(), ast_calloc, ast_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(), 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().

07298 {
07299    /* XXX This is, admittedly, some pretty horrendus code.  For some
07300       reason it just seemed a lot easier to do with GOTO's.  I feel
07301       like I'm back in my GWBASIC days. XXX */
07302    int res=-1;
07303    int cmd=0;
07304    int valid = 0;
07305    struct ast_module_user *u;
07306    char prefixstr[80] ="";
07307    char ext_context[256]="";
07308    int box;
07309    int useadsi = 0;
07310    int skipuser = 0;
07311    struct vm_state vms;
07312    struct ast_vm_user *vmu = NULL, vmus;
07313    char *context=NULL;
07314    int silentexit = 0;
07315    struct ast_flags flags = { 0 };
07316    signed char record_gain = 0;
07317    int play_auto = 0;
07318    int play_folder = 0;
07319 #ifdef IMAP_STORAGE
07320    int deleted = 0;
07321 #endif
07322    u = ast_module_user_add(chan);
07323 
07324    /* Add the vm_state to the active list and keep it active */
07325    memset(&vms, 0, sizeof(vms));
07326    vms.lastmsg = -1;
07327 
07328    memset(&vmus, 0, sizeof(vmus));
07329 
07330    if (chan->_state != AST_STATE_UP) {
07331       if (option_debug)
07332          ast_log(LOG_DEBUG, "Before ast_answer\n");
07333       ast_answer(chan);
07334    }
07335 
07336    if (!ast_strlen_zero(data)) {
07337       char *opts[OPT_ARG_ARRAY_SIZE];
07338       char *parse;
07339       AST_DECLARE_APP_ARGS(args,
07340          AST_APP_ARG(argv0);
07341          AST_APP_ARG(argv1);
07342       );
07343 
07344       parse = ast_strdupa(data);
07345 
07346       AST_STANDARD_APP_ARGS(args, parse);
07347 
07348       if (args.argc == 2) {
07349          if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) {
07350             ast_module_user_remove(u);
07351             return -1;
07352          }
07353          if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
07354             int gain;
07355             if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
07356                if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
07357                   ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
07358                   ast_module_user_remove(u);
07359                   return -1;
07360                } else {
07361                   record_gain = (signed char) gain;
07362                }
07363             } else {
07364                ast_log(LOG_WARNING, "Invalid Gain level set with option g\n");
07365             }
07366          }
07367          if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
07368             play_auto = 1;
07369             if (opts[OPT_ARG_PLAYFOLDER]) {
07370                if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) {
07371                   ast_log(LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]);
07372                }
07373             } else {
07374                ast_log(LOG_WARNING, "Invalid folder set with option a\n");
07375             }  
07376             if ( play_folder > 9 || play_folder < 0) {
07377                ast_log(LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder);
07378                play_folder = 0;
07379             }
07380          }
07381       } else {
07382          /* old style options parsing */
07383          while (*(args.argv0)) {
07384             if (*(args.argv0) == 's')
07385                ast_set_flag(&flags, OPT_SILENT);
07386             else if (*(args.argv0) == 'p')
07387                ast_set_flag(&flags, OPT_PREPEND_MAILBOX);
07388             else 
07389                break;
07390             (args.argv0)++;
07391          }
07392 
07393       }
07394 
07395       valid = ast_test_flag(&flags, OPT_SILENT);
07396 
07397       if ((context = strchr(args.argv0, '@')))
07398          *context++ = '\0';
07399 
07400       if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
07401          ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
07402       else
07403          ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
07404 
07405       if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
07406          skipuser++;
07407       else
07408          valid = 0;
07409    }
07410 
07411    if (!valid)
07412       res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
07413 
07414    if (option_debug)
07415       ast_log(LOG_DEBUG, "After vm_authenticate\n");
07416    if (!res) {
07417       valid = 1;
07418       if (!skipuser)
07419          vmu = &vmus;
07420    } else {
07421       res = 0;
07422    }
07423 
07424    /* If ADSI is supported, setup login screen */
07425    adsi_begin(chan, &useadsi);
07426 
07427    if (!valid) {
07428       goto out;
07429    }
07430 
07431 #ifdef IMAP_STORAGE
07432    pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
07433    pthread_setspecific(ts_vmstate.key, &vms);
07434 
07435    vms.interactive = 1;
07436    vms.updated = 1;
07437    if (vmu)
07438       ast_copy_string(vms.context, vmu->context, sizeof(vms.context));
07439    vmstate_insert(&vms);
07440    init_vm_state(&vms);
07441 #endif
07442    if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07443       /* TODO: Handle memory allocation failure */
07444    }
07445    if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) {
07446       /* TODO: Handle memory allocation failure */
07447    }
07448    
07449    /* Set language from config to override channel language */
07450    if (!ast_strlen_zero(vmu->language))
07451       ast_string_field_set(chan, language, vmu->language);
07452    create_dirpath(vms.curdir, sizeof(vms.curdir), vmu->context, vms.username, "");
07453    /* Retrieve old and new message counts */
07454    if (option_debug)
07455       ast_log(LOG_DEBUG, "Before open_mailbox\n");
07456    res = open_mailbox(&vms, vmu, 1);
07457    if (res == ERROR_LOCK_PATH)
07458       goto out;
07459    vms.oldmessages = vms.lastmsg + 1;
07460    if (option_debug > 2)
07461       ast_log(LOG_DEBUG, "Number of old messages: %d\n",vms.oldmessages);
07462    /* Start in INBOX */
07463    res = open_mailbox(&vms, vmu, 0);
07464    if (res == ERROR_LOCK_PATH)
07465       goto out;
07466    vms.newmessages = vms.lastmsg + 1;
07467    if (option_debug > 2)
07468       ast_log(LOG_DEBUG, "Number of new messages: %d\n",vms.newmessages);
07469       
07470    /* Select proper mailbox FIRST!! */
07471    if (play_auto) {
07472       res = open_mailbox(&vms, vmu, play_folder);
07473       if (res == ERROR_LOCK_PATH)
07474          goto out;
07475 
07476       /* If there are no new messages, inform the user and hangup */
07477       if (vms.lastmsg == -1) {
07478          cmd = vm_browse_messages(chan, &vms, vmu);
07479          res = 0;
07480          goto out;
07481       }
07482    } else {
07483       if (!vms.newmessages && vms.oldmessages) {
07484          /* If we only have old messages start here */
07485          res = open_mailbox(&vms, vmu, 1);
07486          play_folder = 1;
07487          if (res == ERROR_LOCK_PATH)
07488             goto out;
07489       }
07490    }
07491 
07492    if (useadsi)
07493       adsi_status(chan, &vms);
07494    res = 0;
07495 
07496    /* Check to see if this is a new user */
07497    if (!strcasecmp(vmu->mailbox, vmu->password) && 
07498       (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) {
07499       if (ast_play_and_wait(chan, "vm-newuser") == -1)
07500          ast_log(LOG_WARNING, "Couldn't stream new user file\n");
07501       cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
07502       if ((cmd == 't') || (cmd == '#')) {
07503          /* Timeout */
07504          res = 0;
07505          goto out;
07506       } else if (cmd < 0) {
07507          /* Hangup */
07508          res = -1;
07509          goto out;
07510       }
07511    }
07512 #ifdef IMAP_STORAGE
07513       if (option_debug > 2)
07514          ast_log(LOG_DEBUG, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit);
07515       if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
07516          if (option_debug)
07517             ast_log(LOG_DEBUG, "*** QUOTA EXCEEDED!!\n");
07518          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07519       }
07520       if (option_debug > 2)
07521          ast_log(LOG_DEBUG, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07522       if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
07523          ast_log(LOG_WARNING, "No more messages possible.  User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg);
07524          cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07525       }
07526 #endif
07527    if (play_auto) {
07528       cmd = '1';
07529    } else {
07530       cmd = vm_intro(chan, vmu, &vms);
07531    }
07532 
07533    vms.repeats = 0;
07534    vms.starting = 1;
07535    while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07536       /* Run main menu */
07537       switch (cmd) {
07538       case '1':
07539          vms.curmsg = 0;
07540          /* Fall through */
07541       case '5':
07542          cmd = vm_browse_messages(chan, &vms, vmu);
07543          break;
07544       case '2': /* Change folders */
07545          if (useadsi)
07546             adsi_folders(chan, 0, "Change to folder...");
07547          cmd = get_folder2(chan, "vm-changeto", 0);
07548          if (cmd == '#') {
07549             cmd = 0;
07550          } else if (cmd > 0) {
07551             cmd = cmd - '0';
07552             res = close_mailbox(&vms, vmu);
07553             if (res == ERROR_LOCK_PATH)
07554                goto out;
07555             res = open_mailbox(&vms, vmu, cmd);
07556             if (res == ERROR_LOCK_PATH)
07557                goto out;
07558             play_folder = cmd;
07559             cmd = 0;
07560          }
07561          if (useadsi)
07562             adsi_status2(chan, &vms);
07563             
07564          if (!cmd)
07565             cmd = vm_play_folder_name(chan, vms.vmbox);
07566 
07567          vms.starting = 1;
07568          break;
07569       case '3': /* Advanced options */
07570          cmd = 0;
07571          vms.repeats = 0;
07572          while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
07573             switch (cmd) {
07574             case '1': /* Reply */
07575                if (vms.lastmsg > -1 && !vms.starting) {
07576                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
07577                   if (cmd == ERROR_LOCK_PATH) {
07578                      res = cmd;
07579                      goto out;
07580                   }
07581                } else
07582                   cmd = ast_play_and_wait(chan, "vm-sorry");
07583                cmd = 't';
07584                break;
07585             case '2': /* Callback */
07586                if (option_verbose > 2 && !vms.starting)
07587                   ast_verbose( VERBOSE_PREFIX_3 "Callback Requested\n");
07588                if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
07589                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
07590                   if (cmd == 9) {
07591                      silentexit = 1;
07592                      goto out;
07593                   } else if (cmd == ERROR_LOCK_PATH) {
07594                      res = cmd;
07595                      goto out;
07596                   }
07597                }
07598                else 
07599                   cmd = ast_play_and_wait(chan, "vm-sorry");
07600                cmd = 't';
07601                break;
07602             case '3': /* Envelope */
07603                if (vms.lastmsg > -1 && !vms.starting) {
07604                   cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
07605                   if (cmd == ERROR_LOCK_PATH) {
07606                      res = cmd;
07607                      goto out;
07608                   }
07609                } else
07610                   cmd = ast_play_and_wait(chan, "vm-sorry");
07611                cmd = 't';
07612                break;
07613             case '4': /* Dialout */
07614                if (!ast_strlen_zero(vmu->dialout)) {
07615                   cmd = dialout(chan, vmu, NULL, vmu->dialout);
07616                   if (cmd == 9) {
07617                      silentexit = 1;
07618                      goto out;
07619                   }
07620                }
07621                else 
07622                   cmd = ast_play_and_wait(chan, "vm-sorry");
07623                cmd = 't';
07624                break;
07625 
07626             case '5': /* Leave VoiceMail */
07627                if (ast_test_flag(vmu, VM_SVMAIL)) {
07628                   cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
07629                   if (cmd == ERROR_LOCK_PATH) {
07630                      res = cmd;
07631                      ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
07632                      goto out;
07633                   }
07634                } else
07635                   cmd = ast_play_and_wait(chan,"vm-sorry");
07636                cmd='t';
07637                break;
07638                
07639             case '*': /* Return to main menu */
07640                cmd = 't';
07641                break;
07642 
07643             default:
07644                cmd = 0;
07645                if (!vms.starting) {
07646                   cmd = ast_play_and_wait(chan, "vm-toreply");
07647                }
07648                if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
07649                   cmd = ast_play_and_wait(chan, "vm-tocallback");
07650                }
07651                if (!cmd && !vms.starting) {
07652                   cmd = ast_play_and_wait(chan, "vm-tohearenv");
07653                }
07654                if (!ast_strlen_zero(vmu->dialout) && !cmd) {
07655                   cmd = ast_play_and_wait(chan, "vm-tomakecall");
07656                }
07657                if (ast_test_flag(vmu, VM_SVMAIL) && !cmd)
07658                   cmd=ast_play_and_wait(chan, "vm-leavemsg");
07659                if (!cmd)
07660                   cmd = ast_play_and_wait(chan, "vm-starmain");
07661                if (!cmd)
07662                   cmd = ast_waitfordigit(chan,6000);
07663                if (!cmd)
07664                   vms.repeats++;
07665                if (vms.repeats > 3)
07666                   cmd = 't';
07667             }
07668          }
07669          if (cmd == 't') {
07670             cmd = 0;
07671             vms.repeats = 0;
07672          }
07673          break;
07674       case '4':
07675          if (vms.curmsg > 0) {
07676             vms.curmsg--;
07677             cmd = play_message(chan, vmu, &vms);
07678          } else {
07679             cmd = ast_play_and_wait(chan, "vm-nomore");
07680          }
07681          break;
07682       case '6':
07683          if (vms.curmsg < vms.lastmsg) {
07684             vms.curmsg++;
07685             cmd = play_message(chan, vmu, &vms);
07686          } else {
07687             cmd = ast_play_and_wait(chan, "vm-nomore");
07688          }
07689          break;
07690       case '7':
07691          if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
07692             vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
07693             if (useadsi)
07694                adsi_delete(chan, &vms);
07695             if (vms.deleted[vms.curmsg]) {
07696                if (play_folder == 0)
07697                   vms.newmessages--;
07698                else if (play_folder == 1)
07699                   vms.oldmessages--;
07700                cmd = ast_play_and_wait(chan, "vm-deleted");
07701             }
07702             else {
07703                if (play_folder == 0)
07704                   vms.newmessages++;
07705                else if (play_folder == 1)
07706                   vms.oldmessages++;
07707                cmd = ast_play_and_wait(chan, "vm-undeleted");
07708             }
07709             if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07710                if (vms.curmsg < vms.lastmsg) {
07711                   vms.curmsg++;
07712                   cmd = play_message(chan, vmu, &vms);
07713                } else {
07714                   cmd = ast_play_and_wait(chan, "vm-nomore");
07715                }
07716             }
07717          } else /* Delete not valid if we haven't selected a message */
07718             cmd = 0;
07719 #ifdef IMAP_STORAGE
07720          deleted = 1;
07721 #endif
07722          break;
07723    
07724       case '8':
07725          if (vms.lastmsg > -1) {
07726             cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain);
07727             if (cmd == ERROR_LOCK_PATH) {
07728                res = cmd;
07729                goto out;
07730             }
07731          } else
07732             cmd = ast_play_and_wait(chan, "vm-nomore");
07733          break;
07734       case '9':
07735          if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
07736             /* No message selected */
07737             cmd = 0;
07738             break;
07739          }
07740          if (useadsi)
07741             adsi_folders(chan, 1, "Save to folder...");
07742          cmd = get_folder2(chan, "vm-savefolder", 1);
07743          box = 0; /* Shut up compiler */
07744          if (cmd == '#') {
07745             cmd = 0;
07746             break;
07747          } else if (cmd > 0) {
07748             box = cmd = cmd - '0';
07749             cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
07750             if (cmd == ERROR_LOCK_PATH) {
07751                res = cmd;
07752                goto out;
07753 #ifndef IMAP_STORAGE
07754             } else if (!cmd) {
07755                vms.deleted[vms.curmsg] = 1;
07756 #endif
07757             } else {
07758                vms.deleted[vms.curmsg] = 0;
07759                vms.heard[vms.curmsg] = 0;
07760             }
07761          }
07762          make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
07763          if (useadsi)
07764             adsi_message(chan, &vms);
07765          snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box));
07766          if (!cmd) {
07767             cmd = ast_play_and_wait(chan, "vm-message");
07768             if (!cmd)
07769                cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
07770             if (!cmd)
07771                cmd = ast_play_and_wait(chan, "vm-savedto");
07772             if (!cmd)
07773                cmd = vm_play_folder_name(chan, vms.fn);
07774          } else {
07775             cmd = ast_play_and_wait(chan, "vm-mailboxfull");
07776          }
07777          if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
07778             if (vms.curmsg < vms.lastmsg) {
07779                vms.curmsg++;
07780                cmd = play_message(chan, vmu, &vms);
07781             } else {
07782                cmd = ast_play_and_wait(chan, "vm-nomore");
07783             }
07784          }
07785          break;
07786       case '*':
07787          if (!vms.starting) {
07788             cmd = ast_play_and_wait(chan, "vm-onefor");
07789             if (!strncasecmp(chan->language, "he", 2)) {
07790                cmd = ast_play_and_wait(chan, "vm-for");
07791             }
07792             if (!cmd)
07793                cmd = vm_play_folder_name(chan, vms.vmbox);
07794             if (!cmd)
07795                cmd = ast_play_and_wait(chan, "vm-opts");
07796             if (!cmd)
07797                cmd = vm_instructions(chan, &vms, 1);
07798          } else
07799             cmd = 0;
07800          break;
07801       case '0':
07802          cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
07803          if (useadsi)
07804             adsi_status(chan, &vms);
07805          break;
07806       default: /* Nothing */
07807          cmd = vm_instructions(chan, &vms, 0);
07808          break;
07809       }
07810    }
07811    if ((cmd == 't') || (cmd == '#')) {
07812       /* Timeout */
07813       res = 0;
07814    } else {
07815       /* Hangup */
07816       res = -1;
07817    }
07818 
07819 out:
07820    if (res > -1) {
07821       ast_stopstream(chan);
07822       adsi_goodbye(chan);
07823       if (valid) {
07824          if (silentexit)
07825             res = ast_play_and_wait(chan, "vm-dialout");
07826          else 
07827             res = ast_play_and_wait(chan, "vm-goodbye");
07828          if (res > 0)
07829             res = 0;
07830       }
07831       if (useadsi)
07832          ast_adsi_unload_session(chan);
07833    }
07834    if (vmu)
07835       close_mailbox(&vms, vmu);
07836    if (valid) {
07837       snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
07838       manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
07839       run_externnotify(vmu->context, vmu->mailbox);
07840    }
07841 #ifdef IMAP_STORAGE
07842    /* expunge message - use UID Expunge if supported on IMAP server*/
07843    if (option_debug > 2)
07844       ast_log(LOG_DEBUG, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup);
07845    if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) {
07846       ast_mutex_lock(&vms.lock);
07847 #ifdef HAVE_IMAP_TK2006
07848       if (LEVELUIDPLUS (vms.mailstream)) {
07849          mail_expunge_full(vms.mailstream,NIL,EX_UID);
07850       } else 
07851 #endif
07852          mail_expunge(vms.mailstream);
07853       ast_mutex_unlock(&vms.lock);
07854    }
07855    /*  before we delete the state, we should copy pertinent info
07856     *  back to the persistent model */
07857    if (vmu) {
07858       vmstate_delete(&vms);
07859    }
07860 #endif
07861    if (vmu)
07862       free_user(vmu);
07863    if (vms.deleted)
07864       free(vms.deleted);
07865    if (vms.heard)
07866       free(vms.heard);
07867 
07868 #ifdef IMAP_STORAGE
07869    pthread_setspecific(ts_vmstate.key, NULL);
07870 #endif
07871    ast_module_user_remove(u);
07872    return res;
07873 }

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

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

Referenced by forward_message().

05001 {
05002    int cmd = 0;
05003    int retries = 0, prepend_duration = 0, already_recorded = 0;
05004    signed char zero_gain = 0;
05005    struct ast_config *msg_cfg;
05006    const char *duration_str;
05007    char msgfile[PATH_MAX], backup[PATH_MAX];
05008    char textfile[PATH_MAX];
05009 
05010    /* Must always populate duration correctly */
05011    make_file(msgfile, sizeof(msgfile), curdir, curmsg);
05012    strcpy(textfile, msgfile);
05013    strcpy(backup, msgfile);
05014    strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
05015    strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
05016 
05017    if (!(msg_cfg = ast_config_load(textfile))) {
05018       return -1;
05019    }
05020 
05021    *duration = 0;
05022    if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
05023       *duration = atoi(duration_str);
05024 
05025    while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
05026       if (cmd)
05027          retries = 0;
05028       switch (cmd) {
05029       case '1': 
05030          /* prepend a message to the current message, update the metadata and return */
05031       {
05032          prepend_duration = 0;
05033 
05034          /* if we can't read the message metadata, stop now */
05035          if (!msg_cfg) {
05036             cmd = 0;
05037             break;
05038          }
05039 
05040          /* Back up the original file, so we can retry the prepend */
05041          if (already_recorded)
05042             ast_filecopy(backup, msgfile, NULL);
05043          else
05044             ast_filecopy(msgfile, backup, NULL);
05045          already_recorded = 1;
05046 
05047          if (record_gain)
05048             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
05049 
05050          cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vmfmts, &prepend_duration, 1, silencethreshold, maxsilence);
05051          if (record_gain)
05052             ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
05053 
05054          if (prepend_duration) {
05055             struct ast_category *msg_cat;
05056             /* need enough space for a maximum-length message duration */
05057             char duration_str[12];
05058 
05059             prepend_duration += *duration;
05060             msg_cat = ast_category_get(msg_cfg, "message");
05061             snprintf(duration_str, 11, "%d", prepend_duration);
05062             if (!ast_variable_update(msg_cat, "duration", duration_str, NULL, 0)) {
05063                config_text_file_save(textfile, msg_cfg, "app_voicemail");
05064             }
05065          }
05066 
05067          break;
05068       }
05069       case '2': 
05070          cmd = 't';
05071          break;
05072       case '*':
05073          cmd = '*';
05074          break;
05075       default: 
05076          cmd = ast_play_and_wait(chan,"vm-forwardoptions");
05077             /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
05078          if (!cmd)
05079             cmd = ast_play_and_wait(chan,"vm-starmain");
05080             /* "press star to return to the main menu" */
05081          if (!cmd)
05082             cmd = ast_waitfordigit(chan,6000);
05083          if (!cmd)
05084             retries++;
05085          if (retries > 3)
05086             cmd = 't';
05087       }
05088    }
05089 
05090    ast_config_destroy(msg_cfg);
05091    if (already_recorded)
05092       ast_filedelete(backup, NULL);
05093    if (prepend_duration)
05094       *duration = prepend_duration;
05095 
05096    if (cmd == 't' || cmd == 'S')
05097       cmd = 0;
05098    return cmd;
05099 }

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

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

06802 {
06803    int res = 0;
06804    /* Play instructions and wait for new command */
06805    while (!res) {
06806       if (vms->starting) {
06807          if (vms->lastmsg > -1) {
06808             res = ast_play_and_wait(chan, "vm-onefor");
06809             if (!strncasecmp(chan->language, "he", 2)) {
06810                res = ast_play_and_wait(chan, "vm-for");
06811             }
06812             if (!res)
06813                res = vm_play_folder_name(chan, vms->vmbox);
06814          }
06815          if (!res)
06816             res = ast_play_and_wait(chan, "vm-opts");
06817       } else {
06818          if (vms->curmsg)
06819             res = ast_play_and_wait(chan, "vm-prev");
06820          if (!res && !skipadvanced)
06821             res = ast_play_and_wait(chan, "vm-advopts");
06822          if (!res)
06823             res = ast_play_and_wait(chan, "vm-repeat");
06824          if (!res && (vms->curmsg != vms->lastmsg))
06825             res = ast_play_and_wait(chan, "vm-next");
06826          if (!res) {
06827             if (!vms->deleted[vms->curmsg])
06828                res = ast_play_and_wait(chan, "vm-delete");
06829             else
06830                res = ast_play_and_wait(chan, "vm-undelete");
06831             if (!res)
06832                res = ast_play_and_wait(chan, "vm-toforward");
06833             if (!res)
06834                res = ast_play_and_wait(chan, "vm-savemessage");
06835          }
06836       }
06837       if (!res)
06838          res = ast_play_and_wait(chan, "vm-helpexit");
06839       if (!res)
06840          res = ast_waitfordigit(chan, 6000);
06841       if (!res) {
06842          vms->repeats++;
06843          if (vms->repeats > 2) {
06844             res = 't';
06845          }
06846       }
06847    }
06848    return res;
06849 }

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

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

06746 {
06747    char prefile[256];
06748    
06749    /* Notify the user that the temp greeting is set and give them the option to remove it */
06750    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06751    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
06752       RETRIEVE(prefile, -1, vmu);
06753       if (ast_fileexists(prefile, NULL, NULL) > 0)
06754          ast_play_and_wait(chan, "vm-tempgreetactive");
06755       DISPOSE(prefile, -1);
06756    }
06757 
06758    /* Play voicemail intro - syntax is different for different languages */
06759    if (0) {
06760    } else if (!strncasecmp(chan->language, "cs", 2)) {  /* CZECH syntax */
06761       return vm_intro_cs(chan, vms);
06762    } else if (!strncasecmp(chan->language, "cz", 2)) {  /* deprecated CZECH syntax */
06763       static int deprecation_warning = 0;
06764       if (deprecation_warning++ % 10 == 0) {
06765          ast_log(LOG_WARNING, "cz is not a standard language code.  Please switch to using cs instead.\n");
06766       }
06767       return vm_intro_cs(chan, vms);
06768    } else if (!strncasecmp(chan->language, "de", 2)) {  /* GERMAN syntax */
06769       return vm_intro_de(chan, vms);
06770    } else if (!strncasecmp(chan->language, "es", 2)) {  /* SPANISH syntax */
06771       return vm_intro_es(chan, vms);
06772    } else if (!strncasecmp(chan->language, "fr", 2)) {  /* FRENCH syntax */
06773       return vm_intro_fr(chan, vms);
06774    } else if (!strncasecmp(chan->language, "gr", 2)) {  /* GREEK syntax */
06775       return vm_intro_gr(chan, vms);
06776    } else if (!strncasecmp(chan->language, "he", 2)) {  /* HEBREW syntax */
06777       return vm_intro_he(chan, vms);
06778    } else if (!strncasecmp(chan->language, "it", 2)) {  /* ITALIAN syntax */
06779       return vm_intro_it(chan, vms);
06780    } else if (!strncasecmp(chan->language, "nl", 2)) {  /* DUTCH syntax */
06781       return vm_intro_nl(chan, vms);
06782    } else if (!strncasecmp(chan->language, "no", 2)) {  /* NORWEGIAN syntax */
06783       return vm_intro_no(chan, vms);
06784    } else if (!strncasecmp(chan->language, "pl", 2)) {  /* POLISH syntax */
06785       return vm_intro_pl(chan, vms);
06786    } else if (!strncasecmp(chan->language, "pt_BR", 5)) {  /* BRAZILIAN PORTUGUESE syntax */
06787       return vm_intro_pt_BR(chan, vms);
06788    } else if (!strncasecmp(chan->language, "pt", 2)) {  /* PORTUGUESE syntax */
06789       return vm_intro_pt(chan, vms);
06790    } else if (!strncasecmp(chan->language, "ru", 2)) {  /* RUSSIAN syntax */
06791       return vm_intro_multilang(chan, vms, "n");
06792    } else if (!strncasecmp(chan->language, "se", 2)) {  /* SWEDISH syntax */
06793       return vm_intro_se(chan, vms);
06794    } else if (!strncasecmp(chan->language, "ua", 2)) {  /* UKRAINIAN syntax */
06795       return vm_intro_multilang(chan, vms, "n");
06796    } else {                                             /* Default to ENGLISH */
06797       return vm_intro_en(chan, vms);
06798    }
06799 }

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

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

06686 {
06687    int res;
06688    res = ast_play_and_wait(chan, "vm-youhave");
06689    if (!res) {
06690       if (vms->newmessages) {
06691          if (vms->newmessages == 1) {
06692             res = ast_play_and_wait(chan, "digits/jednu");
06693          } else {
06694             res = say_and_wait(chan, vms->newmessages, chan->language);
06695          }
06696          if (!res) {
06697             if ((vms->newmessages == 1))
06698                res = ast_play_and_wait(chan, "vm-novou");
06699             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06700                res = ast_play_and_wait(chan, "vm-nove");
06701             if (vms->newmessages > 4)
06702                res = ast_play_and_wait(chan, "vm-novych");
06703          }
06704          if (vms->oldmessages && !res)
06705             res = ast_play_and_wait(chan, "vm-and");
06706          else if (!res) {
06707             if ((vms->newmessages == 1))
06708                res = ast_play_and_wait(chan, "vm-zpravu");
06709             if ((vms->newmessages) > 1 && (vms->newmessages < 5))
06710                res = ast_play_and_wait(chan, "vm-zpravy");
06711             if (vms->newmessages > 4)
06712                res = ast_play_and_wait(chan, "vm-zprav");
06713          }
06714       }
06715       if (!res && vms->oldmessages) {
06716          res = say_and_wait(chan, vms->oldmessages, chan->language);
06717          if (!res) {
06718             if ((vms->oldmessages == 1))
06719                res = ast_play_and_wait(chan, "vm-starou");
06720             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06721                res = ast_play_and_wait(chan, "vm-stare");
06722             if (vms->oldmessages > 4)
06723                res = ast_play_and_wait(chan, "vm-starych");
06724          }
06725          if (!res) {
06726             if ((vms->oldmessages == 1))
06727                res = ast_play_and_wait(chan, "vm-zpravu");
06728             if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
06729                res = ast_play_and_wait(chan, "vm-zpravy");
06730             if (vms->oldmessages > 4)
06731                res = ast_play_and_wait(chan, "vm-zprav");
06732          }
06733       }
06734       if (!res) {
06735          if (!vms->oldmessages && !vms->newmessages) {
06736             res = ast_play_and_wait(chan, "vm-no");
06737             if (!res)
06738                res = ast_play_and_wait(chan, "vm-zpravy");
06739          }
06740       }
06741    }
06742    return res;
06743 }

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

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

06379 {
06380    /* Introduce messages they have */
06381    int res;
06382    res = ast_play_and_wait(chan, "vm-youhave");
06383    if (!res) {
06384       if (vms->newmessages) {
06385          if ((vms->newmessages == 1))
06386             res = ast_play_and_wait(chan, "digits/1F");
06387          else
06388             res = say_and_wait(chan, vms->newmessages, chan->language);
06389          if (!res)
06390             res = ast_play_and_wait(chan, "vm-INBOX");
06391          if (vms->oldmessages && !res)
06392             res = ast_play_and_wait(chan, "vm-and");
06393          else if (!res) {
06394             if ((vms->newmessages == 1))
06395                res = ast_play_and_wait(chan, "vm-message");
06396             else
06397                res = ast_play_and_wait(chan, "vm-messages");
06398          }
06399             
06400       }
06401       if (!res && vms->oldmessages) {
06402          if (vms->oldmessages == 1)
06403             res = ast_play_and_wait(chan, "digits/1F");
06404          else
06405             res = say_and_wait(chan, vms->oldmessages, chan->language);
06406          if (!res)
06407             res = ast_play_and_wait(chan, "vm-Old");
06408          if (!res) {
06409             if (vms->oldmessages == 1)
06410                res = ast_play_and_wait(chan, "vm-message");
06411             else
06412                res = ast_play_and_wait(chan, "vm-messages");
06413          }
06414       }
06415       if (!res) {
06416          if (!vms->oldmessages && !vms->newmessages) {
06417             res = ast_play_and_wait(chan, "vm-no");
06418             if (!res)
06419                res = ast_play_and_wait(chan, "vm-messages");
06420          }
06421       }
06422    }
06423    return res;
06424 }

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

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

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

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

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

06428 {
06429    /* Introduce messages they have */
06430    int res;
06431    if (!vms->oldmessages && !vms->newmessages) {
06432       res = ast_play_and_wait(chan, "vm-youhaveno");
06433       if (!res)
06434          res = ast_play_and_wait(chan, "vm-messages");
06435    } else {
06436       res = ast_play_and_wait(chan, "vm-youhave");
06437    }
06438    if (!res) {
06439       if (vms->newmessages) {
06440          if (!res) {
06441             if ((vms->newmessages == 1)) {
06442                res = ast_play_and_wait(chan, "digits/1");
06443                if (!res)
06444                   res = ast_play_and_wait(chan, "vm-message");
06445                if (!res)
06446                   res = ast_play_and_wait(chan, "vm-INBOXs");
06447             } else {
06448                res = say_and_wait(chan, vms->newmessages, chan->language);
06449                if (!res)
06450                   res = ast_play_and_wait(chan, "vm-messages");
06451                if (!res)
06452                   res = ast_play_and_wait(chan, "vm-INBOX");
06453             }
06454          }
06455          if (vms->oldmessages && !res)
06456             res = ast_play_and_wait(chan, "vm-and");
06457       }
06458       if (vms->oldmessages) {
06459          if (!res) {
06460             if (vms->oldmessages == 1) {
06461                res = ast_play_and_wait(chan, "digits/1");
06462                if (!res)
06463                   res = ast_play_and_wait(chan, "vm-message");
06464                if (!res)
06465                   res = ast_play_and_wait(chan, "vm-Olds");
06466             } else {
06467                res = say_and_wait(chan, vms->oldmessages, chan->language);
06468                if (!res)
06469                   res = ast_play_and_wait(chan, "vm-messages");
06470                if (!res)
06471                   res = ast_play_and_wait(chan, "vm-Old");
06472             }
06473          }
06474       }
06475    }
06476 return res;
06477 }

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

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

06529 {
06530    /* Introduce messages they have */
06531    int res;
06532    res = ast_play_and_wait(chan, "vm-youhave");
06533    if (!res) {
06534       if (vms->newmessages) {
06535          res = say_and_wait(chan, vms->newmessages, chan->language);
06536          if (!res)
06537             res = ast_play_and_wait(chan, "vm-INBOX");
06538          if (vms->oldmessages && !res)
06539             res = ast_play_and_wait(chan, "vm-and");
06540          else if (!res) {
06541             if ((vms->newmessages == 1))
06542                res = ast_play_and_wait(chan, "vm-message");
06543             else
06544                res = ast_play_and_wait(chan, "vm-messages");
06545          }
06546             
06547       }
06548       if (!res && vms->oldmessages) {
06549          res = say_and_wait(chan, vms->oldmessages, chan->language);
06550          if (!res)
06551             res = ast_play_and_wait(chan, "vm-Old");
06552          if (!res) {
06553             if (vms->oldmessages == 1)
06554                res = ast_play_and_wait(chan, "vm-message");
06555             else
06556                res = ast_play_and_wait(chan, "vm-messages");
06557          }
06558       }
06559       if (!res) {
06560          if (!vms->oldmessages && !vms->newmessages) {
06561             res = ast_play_and_wait(chan, "vm-no");
06562             if (!res)
06563                res = ast_play_and_wait(chan, "vm-messages");
06564          }
06565       }
06566    }
06567    return res;
06568 }

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

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

05939 {
05940    int res = 0;
05941 
05942    if (vms->newmessages) {
05943       res = ast_play_and_wait(chan, "vm-youhave");
05944       if (!res) 
05945          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05946       if (!res) {
05947          if ((vms->newmessages == 1)) {
05948             res = ast_play_and_wait(chan, "vm-INBOX");
05949             if (!res)
05950                res = ast_play_and_wait(chan, "vm-message");
05951          } else {
05952             res = ast_play_and_wait(chan, "vm-INBOXs");
05953             if (!res)
05954                res = ast_play_and_wait(chan, "vm-messages");
05955          }
05956       }
05957    } else if (vms->oldmessages){
05958       res = ast_play_and_wait(chan, "vm-youhave");
05959       if (!res)
05960          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05961       if ((vms->oldmessages == 1)){
05962          res = ast_play_and_wait(chan, "vm-Old");
05963          if (!res)
05964             res = ast_play_and_wait(chan, "vm-message");
05965       } else {
05966          res = ast_play_and_wait(chan, "vm-Olds");
05967          if (!res)
05968             res = ast_play_and_wait(chan, "vm-messages");
05969       }
05970    } else if (!vms->oldmessages && !vms->newmessages) 
05971       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05972    return res;
05973 }

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

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

06117 {
06118    int res=0;
06119 
06120    /* Introduce messages they have */
06121    if (!res) {
06122       if ((vms->newmessages) || (vms->oldmessages)) {
06123          res = ast_play_and_wait(chan, "vm-youhave");
06124       }
06125       /*
06126        * The word "shtei" refers to the number 2 in hebrew when performing a count
06127        * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
06128        * an element, this is one of them.
06129        */
06130       if (vms->newmessages) {
06131          if (!res) {
06132             if (vms->newmessages == 1) {
06133                res = ast_play_and_wait(chan, "vm-INBOX1");
06134             } else {
06135                if (vms->newmessages == 2) {
06136                   res = ast_play_and_wait(chan, "vm-shtei");
06137                } else {
06138                   res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06139                }
06140                res = ast_play_and_wait(chan, "vm-INBOX");
06141             }
06142          }
06143          if (vms->oldmessages && !res) {
06144             res = ast_play_and_wait(chan, "vm-and");
06145             if (vms->oldmessages == 1) {
06146                res = ast_play_and_wait(chan, "vm-Old1");
06147             } else {
06148                if (vms->oldmessages == 2) {
06149                   res = ast_play_and_wait(chan, "vm-shtei");
06150                } else {
06151                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06152                }
06153                res = ast_play_and_wait(chan, "vm-Old");
06154             }
06155          }
06156       }
06157       if (!res && vms->oldmessages && !vms->newmessages) {
06158          if (!res) {
06159             if (vms->oldmessages == 1) {
06160                res = ast_play_and_wait(chan, "vm-Old1");
06161             } else {
06162                if (vms->oldmessages == 2) {
06163                   res = ast_play_and_wait(chan, "vm-shtei");
06164                } else {
06165                   res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");            
06166                }
06167                res = ast_play_and_wait(chan, "vm-Old");
06168             }
06169          }
06170       }
06171       if (!res) {
06172          if (!vms->oldmessages && !vms->newmessages) {
06173             if (!res) {
06174                res = ast_play_and_wait(chan, "vm-nomessages");
06175             }
06176          }
06177       }
06178    }
06179    return res;
06180 }

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

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

06185 {
06186    /* Introduce messages they have */
06187    int res;
06188    if (!vms->oldmessages && !vms->newmessages)
06189       res = ast_play_and_wait(chan, "vm-no") ||
06190          ast_play_and_wait(chan, "vm-message");
06191    else
06192       res = ast_play_and_wait(chan, "vm-youhave");
06193    if (!res && vms->newmessages) {
06194       res = (vms->newmessages == 1) ?
06195          ast_play_and_wait(chan, "digits/un") ||
06196          ast_play_and_wait(chan, "vm-nuovo") ||
06197          ast_play_and_wait(chan, "vm-message") :
06198          /* 2 or more new messages */
06199          say_and_wait(chan, vms->newmessages, chan->language) ||
06200          ast_play_and_wait(chan, "vm-nuovi") ||
06201          ast_play_and_wait(chan, "vm-messages");
06202       if (!res && vms->oldmessages)
06203          res = ast_play_and_wait(chan, "vm-and");
06204    }
06205    if (!res && vms->oldmessages) {
06206       res = (vms->oldmessages == 1) ?
06207          ast_play_and_wait(chan, "digits/un") ||
06208          ast_play_and_wait(chan, "vm-vecchio") ||
06209          ast_play_and_wait(chan, "vm-message") :
06210          /* 2 or more old messages */
06211          say_and_wait(chan, vms->oldmessages, chan->language) ||
06212          ast_play_and_wait(chan, "vm-vecchi") ||
06213          ast_play_and_wait(chan, "vm-messages");
06214    }
06215    return res;
06216 }

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

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

06077 {
06078    int res;
06079    int lastnum = 0;
06080 
06081    res = ast_play_and_wait(chan, "vm-youhave");
06082 
06083    if (!res && vms->newmessages) {
06084       lastnum = vms->newmessages;
06085 
06086       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06087          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
06088       }
06089 
06090       if (!res && vms->oldmessages) {
06091          res = ast_play_and_wait(chan, "vm-and");
06092       }
06093    }
06094 
06095    if (!res && vms->oldmessages) {
06096       lastnum = vms->oldmessages;
06097 
06098       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06099          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
06100       }
06101    }
06102 
06103    if (!res) {
06104       if (lastnum == 0) {
06105          res = ast_play_and_wait(chan, "vm-no");
06106       }
06107       if (!res) {
06108          res = ast_say_counted_noun(chan, lastnum, "vm-message");
06109       }
06110    }
06111 
06112    return res;
06113 }

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

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

06572 {
06573    /* Introduce messages they have */
06574    int res;
06575    res = ast_play_and_wait(chan, "vm-youhave");
06576    if (!res) {
06577       if (vms->newmessages) {
06578          res = say_and_wait(chan, vms->newmessages, chan->language);
06579          if (!res) {
06580             if (vms->newmessages == 1)
06581                res = ast_play_and_wait(chan, "vm-INBOXs");
06582             else
06583                res = ast_play_and_wait(chan, "vm-INBOX");
06584          }
06585          if (vms->oldmessages && !res)
06586             res = ast_play_and_wait(chan, "vm-and");
06587          else if (!res) {
06588             if ((vms->newmessages == 1))
06589                res = ast_play_and_wait(chan, "vm-message");
06590             else
06591                res = ast_play_and_wait(chan, "vm-messages");
06592          }
06593             
06594       }
06595       if (!res && vms->oldmessages) {
06596          res = say_and_wait(chan, vms->oldmessages, chan->language);
06597          if (!res) {
06598             if (vms->oldmessages == 1)
06599                res = ast_play_and_wait(chan, "vm-Olds");
06600             else
06601                res = ast_play_and_wait(chan, "vm-Old");
06602          }
06603          if (!res) {
06604             if (vms->oldmessages == 1)
06605                res = ast_play_and_wait(chan, "vm-message");
06606             else
06607                res = ast_play_and_wait(chan, "vm-messages");
06608          }
06609       }
06610       if (!res) {
06611          if (!vms->oldmessages && !vms->newmessages) {
06612             res = ast_play_and_wait(chan, "vm-no");
06613             if (!res)
06614                res = ast_play_and_wait(chan, "vm-messages");
06615          }
06616       }
06617    }
06618    return res;
06619 }

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

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

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

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

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

06220 {
06221    /* Introduce messages they have */
06222    int res;
06223    div_t num;
06224 
06225    if (!vms->oldmessages && !vms->newmessages) {
06226       res = ast_play_and_wait(chan, "vm-no");
06227       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06228       return res;
06229    } else {
06230       res = ast_play_and_wait(chan, "vm-youhave");
06231    }
06232 
06233    if (vms->newmessages) {
06234       num = div(vms->newmessages, 10);
06235       if (vms->newmessages == 1) {
06236          res = ast_play_and_wait(chan, "digits/1-a");
06237          res = res ? res : ast_play_and_wait(chan, "vm-new-a");
06238          res = res ? res : ast_play_and_wait(chan, "vm-message");
06239       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06240          if (num.rem == 2) {
06241             if (!num.quot) {
06242                res = ast_play_and_wait(chan, "digits/2-ie");
06243             } else {
06244                res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
06245                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06246             }
06247          } else {
06248             res = say_and_wait(chan, vms->newmessages, chan->language);
06249          }
06250          res = res ? res : ast_play_and_wait(chan, "vm-new-e");
06251          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06252       } else {
06253          res = say_and_wait(chan, vms->newmessages, chan->language);
06254          res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
06255          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06256       }
06257       if (!res && vms->oldmessages)
06258          res = ast_play_and_wait(chan, "vm-and");
06259    }
06260    if (!res && vms->oldmessages) {
06261       num = div(vms->oldmessages, 10);
06262       if (vms->oldmessages == 1) {
06263          res = ast_play_and_wait(chan, "digits/1-a");
06264          res = res ? res : ast_play_and_wait(chan, "vm-old-a");
06265          res = res ? res : ast_play_and_wait(chan, "vm-message");
06266       } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
06267          if (num.rem == 2) {
06268             if (!num.quot) {
06269                res = ast_play_and_wait(chan, "digits/2-ie");
06270             } else {
06271                res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
06272                res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
06273             }
06274          } else {
06275             res = say_and_wait(chan, vms->oldmessages, chan->language);
06276          }
06277          res = res ? res : ast_play_and_wait(chan, "vm-old-e");
06278          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06279       } else {
06280          res = say_and_wait(chan, vms->oldmessages, chan->language);
06281          res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
06282          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06283       }
06284    }
06285 
06286    return res;
06287 }

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

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

06623 {
06624    /* Introduce messages they have */
06625    int res;
06626    res = ast_play_and_wait(chan, "vm-youhave");
06627    if (!res) {
06628       if (vms->newmessages) {
06629          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06630          if (!res) {
06631             if ((vms->newmessages == 1)) {
06632                res = ast_play_and_wait(chan, "vm-message");
06633                if (!res)
06634                   res = ast_play_and_wait(chan, "vm-INBOXs");
06635             } else {
06636                res = ast_play_and_wait(chan, "vm-messages");
06637                if (!res)
06638                   res = ast_play_and_wait(chan, "vm-INBOX");
06639             }
06640          }
06641          if (vms->oldmessages && !res)
06642             res = ast_play_and_wait(chan, "vm-and");
06643       }
06644       if (!res && vms->oldmessages) {
06645          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06646          if (!res) {
06647             if (vms->oldmessages == 1) {
06648                res = ast_play_and_wait(chan, "vm-message");
06649                if (!res)
06650                   res = ast_play_and_wait(chan, "vm-Olds");
06651             } else {
06652                res = ast_play_and_wait(chan, "vm-messages");
06653                if (!res)
06654                   res = ast_play_and_wait(chan, "vm-Old");
06655             }
06656          }
06657       }
06658       if (!res) {
06659          if (!vms->oldmessages && !vms->newmessages) {
06660             res = ast_play_and_wait(chan, "vm-no");
06661             if (!res)
06662                res = ast_play_and_wait(chan, "vm-messages");
06663          }
06664       }
06665    }
06666    return res;
06667 }

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

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

06480                                                                          {
06481    /* Introduce messages they have */
06482    int res;
06483    if (!vms->oldmessages && !vms->newmessages) {
06484       res = ast_play_and_wait(chan, "vm-nomessages");
06485       return res;
06486    }
06487    else {
06488       res = ast_play_and_wait(chan, "vm-youhave");
06489    }
06490    if (vms->newmessages) {
06491       if (!res)
06492          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
06493       if ((vms->newmessages == 1)) {
06494          if (!res)
06495             res = ast_play_and_wait(chan, "vm-message");
06496          if (!res)
06497             res = ast_play_and_wait(chan, "vm-INBOXs");
06498       }
06499       else {
06500          if (!res)
06501             res = ast_play_and_wait(chan, "vm-messages");
06502          if (!res)
06503             res = ast_play_and_wait(chan, "vm-INBOX");
06504       }
06505       if (vms->oldmessages && !res)
06506          res = ast_play_and_wait(chan, "vm-and");
06507    }
06508    if (vms->oldmessages) {
06509       if (!res)
06510          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
06511       if (vms->oldmessages == 1) {
06512          if (!res)
06513             res = ast_play_and_wait(chan, "vm-message");
06514          if (!res)
06515             res = ast_play_and_wait(chan, "vm-Olds");
06516       }
06517       else {
06518          if (!res)
06519       res = ast_play_and_wait(chan, "vm-messages");
06520          if (!res)
06521             res = ast_play_and_wait(chan, "vm-Old");
06522       }
06523    }
06524    return res;
06525 }

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

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

06291 {
06292    /* Introduce messages they have */
06293    int res;
06294 
06295    res = ast_play_and_wait(chan, "vm-youhave");
06296    if (res)
06297       return res;
06298 
06299    if (!vms->oldmessages && !vms->newmessages) {
06300       res = ast_play_and_wait(chan, "vm-no");
06301       res = res ? res : ast_play_and_wait(chan, "vm-messages");
06302       return res;
06303    }
06304 
06305    if (vms->newmessages) {
06306       if ((vms->newmessages == 1)) {
06307          res = ast_play_and_wait(chan, "digits/ett");
06308          res = res ? res : ast_play_and_wait(chan, "vm-nytt");
06309          res = res ? res : ast_play_and_wait(chan, "vm-message");
06310       } else {
06311          res = say_and_wait(chan, vms->newmessages, chan->language);
06312          res = res ? res : ast_play_and_wait(chan, "vm-nya");
06313          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06314       }
06315       if (!res && vms->oldmessages)
06316          res = ast_play_and_wait(chan, "vm-and");
06317    }
06318    if (!res && vms->oldmessages) {
06319       if (vms->oldmessages == 1) {
06320          res = ast_play_and_wait(chan, "digits/ett");
06321          res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
06322          res = res ? res : ast_play_and_wait(chan, "vm-message");
06323       } else {
06324          res = say_and_wait(chan, vms->oldmessages, chan->language);
06325          res = res ? res : ast_play_and_wait(chan, "vm-gamla");
06326          res = res ? res : ast_play_and_wait(chan, "vm-messages");
06327       }
06328    }
06329 
06330    return res;
06331 }

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

Definition at line 2213 of file app_voicemail.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

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

02214 {
02215    switch (ast_lock_path(path)) {
02216    case AST_LOCK_TIMEOUT:
02217       return -1;
02218    default:
02219       return 0;
02220    }
02221 }

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

Definition at line 937 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

00938 {
00939    FILE *p = NULL;
00940    int pfd = mkstemp(template);
00941    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
00942    if (pfd > -1) {
00943       p = fdopen(pfd, "w+");
00944       if (!p) {
00945          close(pfd);
00946          pfd = -1;
00947       }
00948    }
00949    return p;
00950 }

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

06852 {
06853    int cmd = 0;
06854    int duration = 0;
06855    int tries = 0;
06856    char newpassword[80] = "";
06857    char newpassword2[80] = "";
06858    char prefile[PATH_MAX] = "";
06859    unsigned char buf[256];
06860    int bytes=0;
06861 
06862    if (ast_adsi_available(chan)) {
06863       bytes += adsi_logo(buf + bytes);
06864       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
06865       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06866       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06867       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06868       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06869    }
06870 
06871    /* First, have the user change their password 
06872       so they won't get here again */
06873    for (;;) {
06874       newpassword[1] = '\0';
06875       newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06876       if (cmd == '#')
06877          newpassword[0] = '\0';
06878       if (cmd < 0 || cmd == 't' || cmd == '#')
06879          return cmd;
06880       cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#");
06881       if (cmd < 0 || cmd == 't' || cmd == '#')
06882          return cmd;
06883       newpassword2[1] = '\0';
06884       newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06885       if (cmd == '#')
06886          newpassword2[0] = '\0';
06887       if (cmd < 0 || cmd == 't' || cmd == '#')
06888          return cmd;
06889       cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#");
06890       if (cmd < 0 || cmd == 't' || cmd == '#')
06891          return cmd;
06892       if (!strcmp(newpassword, newpassword2))
06893          break;
06894       ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
06895       cmd = ast_play_and_wait(chan, "vm-mismatch");
06896       if (++tries == 3)
06897          return -1;
06898       if (cmd == 0) {
06899          cmd = ast_play_and_wait(chan, "vm-pls-try-again");
06900       }
06901    }
06902    if (ast_strlen_zero(ext_pass_cmd)) 
06903       vm_change_password(vmu,newpassword);
06904    else 
06905       vm_change_password_shell(vmu,newpassword);
06906    if (option_debug > 2)
06907       ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
06908    cmd = ast_play_and_wait(chan,"vm-passchanged");
06909 
06910    /* If forcename is set, have the user record their name */  
06911    if (ast_test_flag(vmu, VM_FORCENAME)) {
06912       snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06913       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06914          cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06915          if (cmd < 0 || cmd == 't' || cmd == '#')
06916             return cmd;
06917       }
06918    }
06919 
06920    /* If forcegreetings is set, have the user record their greetings */
06921    if (ast_test_flag(vmu, VM_FORCEGREET)) {
06922       snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06923       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06924          cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06925          if (cmd < 0 || cmd == 't' || cmd == '#')
06926             return cmd;
06927       }
06928 
06929       snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06930       if (ast_fileexists(prefile, NULL, NULL) < 1) {
06931          cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06932          if (cmd < 0 || cmd == 't' || cmd == '#')
06933             return cmd;
06934       }
06935    }
06936 
06937    return cmd;
06938 }

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

06941 {
06942    int cmd = 0;
06943    int retries = 0;
06944    int duration = 0;
06945    char newpassword[80] = "";
06946    char newpassword2[80] = "";
06947    char prefile[PATH_MAX] = "";
06948    unsigned char buf[256];
06949    int bytes=0;
06950 
06951    if (ast_adsi_available(chan))
06952    {
06953       bytes += adsi_logo(buf + bytes);
06954       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
06955       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
06956       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
06957       bytes += ast_adsi_voice_mode(buf + bytes, 0);
06958       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
06959    }
06960    while ((cmd >= 0) && (cmd != 't')) {
06961       if (cmd)
06962          retries = 0;
06963       switch (cmd) {
06964       case '1':
06965          snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
06966          cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06967          break;
06968       case '2': 
06969          snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
06970          cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06971          break;
06972       case '3': 
06973          snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
06974          cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
06975          break;
06976       case '4': 
06977          cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
06978          break;
06979       case '5':
06980          if (vmu->password[0] == '-') {
06981             cmd = ast_play_and_wait(chan, "vm-no");
06982             break;
06983          }
06984          newpassword[1] = '\0';
06985          newpassword[0] = cmd = ast_play_and_wait(chan,"vm-newpassword");
06986          if (cmd == '#')
06987             newpassword[0] = '\0';
06988          else {
06989             if (cmd < 0)
06990                break;
06991             if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) {
06992                break;
06993             }
06994          }
06995          newpassword2[1] = '\0';
06996          newpassword2[0] = cmd = ast_play_and_wait(chan,"vm-reenterpassword");
06997          if (cmd == '#')
06998             newpassword2[0] = '\0';
06999          else {
07000             if (cmd < 0)
07001                break;
07002 
07003             if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) {
07004                break;
07005             }
07006          }
07007          if (strcmp(newpassword, newpassword2)) {
07008             ast_log(LOG_NOTICE,"Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
07009             cmd = ast_play_and_wait(chan, "vm-mismatch");
07010             if (!cmd) {
07011                cmd = ast_play_and_wait(chan, "vm-pls-try-again");
07012             }
07013             break;
07014          }
07015          if (ast_strlen_zero(ext_pass_cmd)) 
07016             vm_change_password(vmu,newpassword);
07017          else 
07018             vm_change_password_shell(vmu,newpassword);
07019          if (option_debug > 2)
07020             ast_log(LOG_DEBUG,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword));
07021          cmd = ast_play_and_wait(chan,"vm-passchanged");
07022          break;
07023       case '*': 
07024          cmd = 't';
07025          break;
07026       default: 
07027          cmd = 0;
07028          snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07029          RETRIEVE(prefile, -1, vmu);
07030          if (ast_fileexists(prefile, NULL, NULL))
07031             cmd = ast_play_and_wait(chan, "vm-tmpexists");
07032          DISPOSE(prefile, -1);
07033          if (!cmd)
07034             cmd = ast_play_and_wait(chan, "vm-options");
07035          if (!cmd)
07036             cmd = ast_waitfordigit(chan,6000);
07037          if (!cmd)
07038             retries++;
07039          if (retries > 3)
07040             cmd = 't';
07041       }
07042    }
07043    if (cmd == 't')
07044       cmd = 0;
07045    return cmd;
07046 }

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

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

05903 {
05904    int cmd;
05905 
05906    if (  !strncasecmp(chan->language, "it", 2) ||
05907         !strncasecmp(chan->language, "es", 2) ||
05908         !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */
05909       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05910       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05911    } else if (!strncasecmp(chan->language, "gr", 2)) {
05912       return vm_play_folder_name_gr(chan, mbox);
05913    } else if (!strncasecmp(chan->language, "pl", 2)) {
05914       return vm_play_folder_name_pl(chan, mbox);
05915    } else if (!strncasecmp(chan->language, "ua", 2)) {  /* Ukrainian syntax */
05916       return vm_play_folder_name_ua(chan, mbox);
05917    } else if (!strncasecmp(chan->language, "he", 2)) {  /* Hebrew syntax */
05918       cmd = ast_play_and_wait(chan, mbox);
05919       return cmd;
05920    } else {  /* Default English */
05921       cmd = ast_play_and_wait(chan, mbox);
05922       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05923    }
05924 }

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

Definition at line 5855 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05856 {
05857    int cmd;
05858    char *buf;
05859 
05860    buf = alloca(strlen(mbox)+2); 
05861    strcpy(buf, mbox);
05862    strcat(buf,"s");
05863 
05864    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")){
05865       cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
05866       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05867    } else {
05868       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
05869       return cmd ? cmd : ast_play_and_wait(chan, mbox); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
05870    }
05871 }

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

Definition at line 5873 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05874 {
05875    int cmd;
05876 
05877    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05878       if (!strcasecmp(mbox, "vm-INBOX"))
05879          cmd = ast_play_and_wait(chan, "vm-new-e");
05880       else
05881          cmd = ast_play_and_wait(chan, "vm-old-e");
05882       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05883    } else {
05884       cmd = ast_play_and_wait(chan, "vm-messages");
05885       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05886    }
05887 }

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

Definition at line 5889 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05890 {
05891    int cmd;
05892 
05893    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05894       cmd = ast_play_and_wait(chan, "vm-messages");
05895       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05896    } else {
05897       cmd = ast_play_and_wait(chan, mbox);
05898       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05899    }
05900 }

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

07049 {
07050    int res;
07051    int cmd = 0;
07052    int retries = 0;
07053    int duration = 0;
07054    char prefile[PATH_MAX] = "";
07055    unsigned char buf[256];
07056    char dest[PATH_MAX];
07057    int bytes = 0;
07058 
07059    if (ast_adsi_available(chan)) {
07060       bytes += adsi_logo(buf + bytes);
07061       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
07062       bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
07063       bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
07064       bytes += ast_adsi_voice_mode(buf + bytes, 0);
07065       ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
07066    }
07067 
07068    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
07069    if ((res = create_dirpath(dest, sizeof(dest), vmu->context, vms->username, "temp"))) {
07070       ast_log(LOG_WARNING, "Failed to create directory (%s).\n", prefile);
07071       return -1;
07072    }
07073    while ((cmd >= 0) && (cmd != 't')) {
07074       if (cmd)
07075          retries = 0;
07076       RETRIEVE(prefile, -1, vmu);
07077       if (ast_fileexists(prefile, NULL, NULL) <= 0) {
07078          play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07079          cmd = 't';  
07080       } else {
07081          switch (cmd) {
07082          case '1':
07083             cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms);
07084             break;
07085          case '2':
07086             DELETE(prefile, -1, prefile, vmu);
07087             ast_play_and_wait(chan, "vm-tempremoved");
07088             cmd = 't';  
07089             break;
07090          case '*': 
07091             cmd = 't';
07092             break;
07093          default:
07094             cmd = ast_play_and_wait(chan,
07095                ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
07096                   "vm-tempgreeting2" : "vm-tempgreeting");
07097             if (!cmd)
07098                cmd = ast_waitfordigit(chan,6000);
07099             if (!cmd)
07100                retries++;
07101             if (retries > 3)
07102                cmd = 't';
07103          }
07104       }
07105       DISPOSE(prefile, -1);
07106    }
07107    if (cmd == 't')
07108       cmd = 0;
07109    return cmd;
07110 }

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

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

08074 {
08075    struct ast_module_user *u;
08076    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
08077    struct ast_vm_user vmus;
08078    char *options = NULL;
08079    int silent = 0, skipuser = 0;
08080    int res = -1;
08081 
08082    u = ast_module_user_add(chan);
08083    
08084    if (s) {
08085       s = ast_strdupa(s);
08086       user = strsep(&s, "|");
08087       options = strsep(&s, "|");
08088       if (user) {
08089          s = user;
08090          user = strsep(&s, "@");
08091          context = strsep(&s, "");
08092          if (!ast_strlen_zero(user))
08093             skipuser++;
08094          ast_copy_string(mailbox, user, sizeof(mailbox));
08095       }
08096    }
08097 
08098    if (options) {
08099       silent = (strchr(options, 's')) != NULL;
08100    }
08101 
08102    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
08103       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
08104       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
08105       ast_play_and_wait(chan, "auth-thankyou");
08106       res = 0;
08107    }
08108 
08109    ast_module_user_remove(u);
08110    return res;
08111 }

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

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

03091 {
03092    const struct vm_zone *z = NULL;
03093    time_t t = time(NULL);
03094 
03095    /* Does this user have a timezone specified? */
03096    if (!ast_strlen_zero(vmu->zonetag)) {
03097       /* Find the zone in the list */
03098       AST_LIST_LOCK(&zones);
03099       AST_LIST_TRAVERSE(&zones, z, list) {
03100          if (!strcmp(z->name, vmu->zonetag))
03101             break;
03102       }
03103       AST_LIST_UNLOCK(&zones);
03104    }
03105    ast_localtime(&t, tm, z ? z->timezone : NULL);
03106    return tm;
03107 }

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

Definition at line 5392 of file app_voicemail.c.

References ast_control_streamfile().

05393 {
05394    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05395 }

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

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

05385 {
05386    int res;
05387    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05388       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05389    return res;
05390 }


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

char* addesc = "Comedian Mail" [static]

Definition at line 457 of file app_voicemail.c.

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

Definition at line 579 of file app_voicemail.c.

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

Definition at line 580 of file app_voicemail.c.

int adsiver = 1 [static]

Definition at line 581 of file app_voicemail.c.

char* app = "VoiceMail" [static]

Definition at line 533 of file app_voicemail.c.

char* app2 = "VoiceMailMain" [static]

Definition at line 536 of file app_voicemail.c.

char* app3 = "MailboxExists" [static]

Definition at line 538 of file app_voicemail.c.

char* app4 = "VMAuthenticate" [static]

Definition at line 539 of file app_voicemail.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 9361 of file app_voicemail.c.

char callcontext[AST_MAX_CONTEXT] [static]

Definition at line 564 of file app_voicemail.c.

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

Definition at line 577 of file app_voicemail.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static]

Definition at line 567 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 8215 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 8220 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 8225 of file app_voicemail.c.

Referenced by load_module(), and unload_module().

char* descrip_vm [static]

Definition at line 462 of file app_voicemail.c.

char* descrip_vm_box_exists [static]

Definition at line 508 of file app_voicemail.c.

char* descrip_vmain [static]

Definition at line 490 of file app_voicemail.c.

char* descrip_vmauthenticate [static]

Definition at line 522 of file app_voicemail.c.

char dialcontext[AST_MAX_CONTEXT] [static]

Definition at line 563 of file app_voicemail.c.

Referenced by directory_exec().

char* emailbody = NULL [static]

Definition at line 570 of file app_voicemail.c.

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

Definition at line 582 of file app_voicemail.c.

char* emailsubject = NULL [static]

Definition at line 571 of file app_voicemail.c.

char emailtitle[100] [static]

Definition at line 576 of file app_voicemail.c.

char exitcontext[AST_MAX_CONTEXT] [static]

Definition at line 565 of file app_voicemail.c.

Referenced by conf_run().

char ext_pass_cmd[128] [static]

Definition at line 443 of file app_voicemail.c.

char externnotify[160] [static]

Definition at line 549 of file app_voicemail.c.

char fromstring[100] [static]

Definition at line 574 of file app_voicemail.c.

struct ast_flags globalflags = {0} [static]

Definition at line 559 of file app_voicemail.c.

char mailcmd[160] [static]

Definition at line 548 of file app_voicemail.c.

int maxgreet [static]

Definition at line 555 of file app_voicemail.c.

int maxlogins [static]

Definition at line 557 of file app_voicemail.c.

int maxmsg [static]

Definition at line 545 of file app_voicemail.c.

int maxsilence [static]

Definition at line 544 of file app_voicemail.c.

Referenced by ast_record_review().

int my_umask [static]

Definition at line 445 of file app_voicemail.c.

char* pagerbody = NULL [static]

Definition at line 572 of file app_voicemail.c.

char pagerfromstring[100] [static]

Definition at line 575 of file app_voicemail.c.

char* pagersubject = NULL [static]

Definition at line 573 of file app_voicemail.c.

int saydurationminfo [static]

Definition at line 561 of file app_voicemail.c.

char serveremail[80] [static]

Definition at line 547 of file app_voicemail.c.

int silencethreshold = 128 [static]

Definition at line 546 of file app_voicemail.c.

int skipms [static]

Definition at line 556 of file app_voicemail.c.

Referenced by controlplayback_exec(), and handle_controlstreamfile().

struct ast_smdi_interface* smdi_iface = NULL [static]

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

char* synopsis_vm_box_exists [static]

Initial value:

"Check to see if Voicemail mailbox exists"

Definition at line 505 of file app_voicemail.c.

char* synopsis_vmain [static]

Initial value:

"Check Voicemail messages"

Definition at line 487 of file app_voicemail.c.

char* synopsis_vmauthenticate [static]

Initial value:

"Authenticate with Voicemail passwords"

Definition at line 519 of file app_voicemail.c.

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

Definition at line 455 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 237 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 441 of file app_voicemail.c.

char vmfmts[80] [static]

Definition at line 551 of file app_voicemail.c.

int vmmaxmessage [static]

Definition at line 554 of file app_voicemail.c.

int vmminmessage [static]

Definition at line 553 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 8113 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 8117 of file app_voicemail.c.

double volgain [static]

Definition at line 552 of file app_voicemail.c.

char zonetag[80] [static]

Definition at line 543 of file app_voicemail.c.

Referenced by build_peer().


Generated on Fri Feb 19 17:12:53 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7