Thu Dec 17 23:51:29 2009

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 (const char *input, char *buf, size_t buflen)
static int unload_module (void)
static int vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins, int silent)
static int vm_box_exists (struct ast_channel *chan, void *data)
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_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_cz (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_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 = "6989f2ec67f8497e38c12890500c525b" , .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 3837 of file app_voicemail.c.

References ast_strlen_zero().

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

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

static void __reg_module ( void   )  [static]

Definition at line 9333 of file app_voicemail.c.

static void __unreg_module ( void   )  [static]

Definition at line 9333 of file app_voicemail.c.

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

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

04597 {
04598    int x;
04599    if (!ast_adsi_available(chan))
04600       return;
04601    x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
04602    if (x < 0)
04603       return;
04604    if (!x) {
04605       if (adsi_load_vmail(chan, useadsi)) {
04606          ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n");
04607          return;
04608       }
04609    } else
04610       *useadsi = 1;
04611 }

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

Definition at line 4785 of file app_voicemail.c.

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

Referenced by vm_execmain().

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

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

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

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

static void adsi_goodbye ( struct ast_channel chan  )  [static]

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

04934 {
04935    unsigned char buf[256];
04936    int bytes=0;
04937 
04938    if (!ast_adsi_available(chan))
04939       return;
04940    bytes += adsi_logo(buf + bytes);
04941    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
04942    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
04943    bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
04944    bytes += ast_adsi_voice_mode(buf + bytes, 0);
04945 
04946    ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
04947 }

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

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

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

static void adsi_login ( struct ast_channel chan  )  [static]

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

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

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

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

04458 {
04459    int bytes = 0;
04460    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
04461    bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
04462    return bytes;
04463 }

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

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

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

static void adsi_password ( struct ast_channel chan  )  [static]

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

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

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

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

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

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

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

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

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

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

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

Definition at line 7983 of file app_voicemail.c.

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

Referenced by load_config().

07984 {
07985    /* Assumes lock is already held */
07986    char *tmp;
07987    char *stringp;
07988    char *s;
07989    struct ast_vm_user *vmu;
07990 
07991    tmp = ast_strdupa(data);
07992 
07993    if ((vmu = find_or_create(context, mbox))) {
07994       populate_defaults(vmu);
07995 
07996       stringp = tmp;
07997       if ((s = strsep(&stringp, ","))) 
07998          ast_copy_string(vmu->password, s, sizeof(vmu->password));
07999       if (stringp && (s = strsep(&stringp, ","))) 
08000          ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
08001       if (stringp && (s = strsep(&stringp, ","))) 
08002          ast_copy_string(vmu->email, s, sizeof(vmu->email));
08003       if (stringp && (s = strsep(&stringp, ","))) 
08004          ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
08005       if (stringp && (s = strsep(&stringp, ","))) 
08006          apply_options(vmu, s);
08007    }
08008    return 0;
08009 }

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

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

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

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

Definition at line 702 of file app_voicemail.c.

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

Referenced by append_mailbox(), and apply_option().

00703 {  /* Destructively Parse options and apply */
00704    char *stringp;
00705    char *s;
00706    char *var, *value;
00707    stringp = ast_strdupa(options);
00708    while ((s = strsep(&stringp, "|"))) {
00709       value = s;
00710       if ((var = strsep(&value, "=")) && value) {
00711          apply_option(vmu, var, value);
00712       }
00713    }  
00714 }

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

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

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

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

Definition at line 2939 of file app_voicemail.c.

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

Referenced by make_email_file().

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

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

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

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

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

Referenced by make_email_file().

03108 {
03109    for (; *str; str++) {
03110       if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
03111          return 1;
03112       }
03113    }
03114    return 0;
03115 }

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

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

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

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

Definition at line 8172 of file app_voicemail.c.

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

08173 {
08174    int which = 0;
08175    int wordlen;
08176    struct ast_vm_user *vmu;
08177    const char *context = "";
08178 
08179    /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
08180    if (pos > 4)
08181       return NULL;
08182    if (pos == 3)
08183       return (state == 0) ? ast_strdup("for") : NULL;
08184    wordlen = strlen(word);
08185    AST_LIST_TRAVERSE(&users, vmu, list) {
08186       if (!strncasecmp(word, vmu->context, wordlen)) {
08187          if (context && strcmp(context, vmu->context) && ++which > state)
08188             return ast_strdup(vmu->context);
08189          /* ignore repeated contexts ? */
08190          context = vmu->context;
08191       }
08192    }
08193    return NULL;
08194 }

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

Definition at line 2817 of file app_voicemail.c.

References ast_log(), errno, and VOICEMAIL_FILE_MODE.

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

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

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

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

Definition at line 2867 of file app_voicemail.c.

References ast_filecopy(), and copy().

Referenced by copy_message(), and forward_message().

02868 {
02869    char frompath2[PATH_MAX], topath2[PATH_MAX];
02870    ast_filecopy(frompath, topath, NULL);
02871    snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
02872    snprintf(topath2, sizeof(topath2), "%s.txt", topath);
02873    copy(frompath2, topath2);
02874 }

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

Definition at line 2733 of file app_voicemail.c.

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

Referenced by leave_voicemail(), and open_mailbox().

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

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

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

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

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

08870 {
08871    int cmd = 0;
08872    char destination[80] = "";
08873    int retries = 0;
08874 
08875    if (!num) {
08876       if (option_verbose > 2)
08877          ast_verbose( VERBOSE_PREFIX_3 "Destination number will be entered manually\n");
08878       while (retries < 3 && cmd != 't') {
08879          destination[1] = '\0';
08880          destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call");
08881          if (!cmd)
08882             destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
08883          if (!cmd)
08884             destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
08885          if (!cmd) {
08886             cmd = ast_waitfordigit(chan, 6000);
08887             if (cmd)
08888                destination[0] = cmd;
08889          }
08890          if (!cmd) {
08891             retries++;
08892          } else {
08893 
08894             if (cmd < 0)
08895                return 0;
08896             if (cmd == '*') {
08897                if (option_verbose > 2)
08898                   ast_verbose( VERBOSE_PREFIX_3 "User hit '*' to cancel outgoing call\n");
08899                return 0;
08900             }
08901             if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 
08902                retries++;
08903             else
08904                cmd = 't';
08905          }
08906       }
08907       if (retries >= 3) {
08908          return 0;
08909       }
08910       
08911    } else {
08912       if (option_verbose > 2)
08913          ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
08914       ast_copy_string(destination, num, sizeof(destination));
08915    }
08916 
08917    if (!ast_strlen_zero(destination)) {
08918       if (destination[strlen(destination) -1 ] == '*')
08919          return 0; 
08920       if (option_verbose > 2)
08921          ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
08922       ast_copy_string(chan->exten, destination, sizeof(chan->exten));
08923       ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
08924       chan->priority = 0;
08925       return 9;
08926    }
08927    return 0;
08928 }

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

Referenced by make_email_file().

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

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

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

07956 {
07957    struct ast_vm_user *vmu;
07958    AST_LIST_TRAVERSE(&users, vmu, list) {
07959       if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) {
07960          if (strcasecmp(vmu->context, context)) {
07961             ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
07962                   \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
07963                   \n\tconfiguration creates an ambiguity that you likely do not want. Please\
07964                   \n\tamend your voicemail.conf file to avoid this situation.\n", mbox);
07965          }
07966          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox);
07967          return NULL;
07968       }
07969       if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) {
07970          ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context);
07971          return NULL;
07972       }
07973    }
07974    
07975    if ((vmu = ast_calloc(1, sizeof(*vmu)))) {
07976       ast_copy_string(vmu->context, context, sizeof(vmu->context));
07977       ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox));
07978       AST_LIST_INSERT_TAIL(&users, vmu, list);
07979    }
07980    return vmu;
07981 }

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

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

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

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

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

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

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

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

static void free_user ( struct ast_vm_user vmu  )  [static]

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

01000 {
01001    if (ast_test_flag(vmu, VM_ALLOCED))
01002       free(vmu);
01003 }

static void free_vm_users ( void   )  [static]

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

08217 {
08218    struct ast_vm_user *cur;
08219    struct vm_zone *zcur;
08220 
08221    AST_LIST_LOCK(&users);
08222    while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) {
08223       ast_set_flag(cur, VM_ALLOCED);
08224       free_user(cur);
08225    }
08226    AST_LIST_UNLOCK(&users);
08227 
08228    AST_LIST_LOCK(&zones);
08229    while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) {
08230       free_zone(zcur);
08231    }
08232    AST_LIST_UNLOCK(&zones);
08233 }

static void free_zone ( struct vm_zone z  )  [static]

Definition at line 3624 of file app_voicemail.c.

References free.

03625 {
03626    free(z);
03627 }

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

Definition at line 3557 of file app_voicemail.c.

References ast_localtime().

Referenced by leave_voicemail(), and tds_log().

03558 {
03559    struct tm tm;
03560    time_t t;
03561 
03562    time(&t);
03563 
03564    ast_localtime(&t, &tm, NULL);
03565 
03566    return strftime(s, len, "%a %b %e %r %Z %Y", &tm);
03567 }

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

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

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

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

Definition at line 4982 of file app_voicemail.c.

References ast_play_and_wait(), and get_folder().

Referenced by vm_execmain().

04983 {
04984    int res = 0;
04985    res = ast_play_and_wait(chan, fn);  /* Folder name */
04986    while (((res < '0') || (res > '9')) &&
04987          (res != '#') && (res >= 0)) {
04988       res = get_folder(chan, 0);
04989    }
04990    return res;
04991 }

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

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

08103 {
08104    struct ast_vm_user *vmu;
08105    char *output_format = "%-10s %-5s %-25s %-10s %6s\n";
08106 
08107    if ((argc < 3) || (argc > 5) || (argc == 4)) return RESULT_SHOWUSAGE;
08108    else if ((argc == 5) && strcmp(argv[3],"for")) return RESULT_SHOWUSAGE;
08109 
08110    AST_LIST_LOCK(&users);
08111    if (!AST_LIST_EMPTY(&users)) {
08112       if (argc == 3)
08113          ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08114       else {
08115          int count = 0;
08116          AST_LIST_TRAVERSE(&users, vmu, list) {
08117             if (!strcmp(argv[4],vmu->context))
08118                count++;
08119          }
08120          if (count) {
08121             ast_cli(fd, output_format, "Context", "Mbox", "User", "Zone", "NewMsg");
08122          } else {
08123             ast_cli(fd, "No such voicemail context \"%s\"\n", argv[4]);
08124             AST_LIST_UNLOCK(&users);
08125             return RESULT_FAILURE;
08126          }
08127       }
08128       AST_LIST_TRAVERSE(&users, vmu, list) {
08129          int newmsgs = 0, oldmsgs = 0;
08130          char count[12], tmp[256] = "";
08131 
08132          if ((argc == 3) || ((argc == 5) && !strcmp(argv[4],vmu->context))) {
08133             snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
08134             inboxcount(tmp, &newmsgs, &oldmsgs);
08135             snprintf(count,sizeof(count),"%d",newmsgs);
08136             ast_cli(fd, output_format, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
08137          }
08138       }
08139    } else {
08140       ast_cli(fd, "There are no voicemail users currently defined\n");
08141       AST_LIST_UNLOCK(&users);
08142       return RESULT_FAILURE;
08143    }
08144    AST_LIST_UNLOCK(&users);
08145    return RESULT_SUCCESS;
08146 }

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

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

08149 {
08150    struct vm_zone *zone;
08151    char *output_format = "%-15s %-20s %-45s\n";
08152    int res = RESULT_SUCCESS;
08153 
08154    if (argc != 3)
08155       return RESULT_SHOWUSAGE;
08156 
08157    AST_LIST_LOCK(&zones);
08158    if (!AST_LIST_EMPTY(&zones)) {
08159       ast_cli(fd, output_format, "Zone", "Timezone", "Message Format");
08160       AST_LIST_TRAVERSE(&zones, zone, list) {
08161          ast_cli(fd, output_format, zone->name, zone->timezone, zone->msg_format);
08162       }
08163    } else {
08164       ast_cli(fd, "There are no voicemail zones currently defined\n");
08165       res = RESULT_FAILURE;
08166    }
08167    AST_LIST_UNLOCK(&zones);
08168 
08169    return res;
08170 }

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

Definition at line 3868 of file app_voicemail.c.

References __has_voicemail(), and ast_copy_string().

03869 {
03870    char tmp[256], *tmp2 = tmp, *mbox, *context;
03871    ast_copy_string(tmp, mailbox, sizeof(tmp));
03872    while ((mbox = strsep(&tmp2, ","))) {
03873       if ((context = strchr(mbox, '@')))
03874          *context++ = '\0';
03875       else
03876          context = "default";
03877       if (__has_voicemail(context, mbox, folder, 1))
03878          return 1;
03879    }
03880    return 0;
03881 }

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

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

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

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

Definition at line 2891 of file app_voicemail.c.

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

Referenced by inchar(), and sip_addheader().

02892 {
02893    int l;
02894 
02895    if (bio->ateof)
02896       return 0;
02897 
02898    if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) {
02899       if (ferror(fi))
02900          return -1;
02901 
02902       bio->ateof = 1;
02903       return 0;
02904    }
02905 
02906    bio->iolen= l;
02907    bio->iocp= 0;
02908 
02909    return 1;
02910 }

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

Definition at line 2912 of file app_voicemail.c.

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

Referenced by base_encode().

02913 {
02914    if (bio->iocp>=bio->iolen) {
02915       if (!inbuf(bio, fi))
02916          return EOF;
02917    }
02918 
02919    return bio->iobuf[bio->iocp++];
02920 }

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

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

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

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

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

02772 {
02773    int x;
02774    char fn[PATH_MAX];
02775 
02776    if (vm_lock_path(dir))
02777       return ERROR_LOCK_PATH;
02778 
02779    for (x = 0; x < vmu->maxmsg; x++) {
02780       make_file(fn, sizeof(fn), dir, x);
02781       if (ast_fileexists(fn, NULL, NULL) < 1)
02782          break;
02783    }
02784    ast_unlock_path(dir);
02785 
02786    return x - 1;
02787 }

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

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

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

static int load_config ( void   )  [static]

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

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

static int load_module ( void   )  [static]

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

08829 {
08830    int res;
08831    char *adsi_loaded = ast_module_helper("", "res_adsi", 0, 0, 0, 0);
08832    char *smdi_loaded = ast_module_helper("", "res_smdi", 0, 0, 0, 0);
08833    free(adsi_loaded);
08834    free(smdi_loaded);
08835 
08836    if (!adsi_loaded) {
08837       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_adsi.so\n");
08838       return AST_MODULE_LOAD_DECLINE;
08839    }
08840 
08841    if (!smdi_loaded) {
08842       ast_log(LOG_ERROR, "app_voicemail.so depends upon res_smdi.so\n");
08843       return AST_MODULE_LOAD_DECLINE;
08844    }
08845 
08846    my_umask = umask(0);
08847    umask(my_umask);
08848    res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
08849    res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
08850    res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
08851    res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
08852    if (res)
08853       return(res);
08854 
08855    if ((res=load_config())) {
08856       return(res);
08857    }
08858 
08859    ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08860 
08861    /* compute the location of the voicemail spool directory */
08862    snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
08863 
08864    ast_install_vm_functions(has_voicemail, inboxcount, messagecount);
08865 
08866    return res;
08867 }

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

Definition at line 920 of file app_voicemail.c.

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

00921 {
00922    return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
00923 }

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

Referenced by sendmail().

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

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

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

00926 {
00927    return snprintf(dest, len, "%s/msg%04d", dir, num);
00928 }

static char* mbox ( int  id  )  [static]

Definition at line 982 of file app_voicemail.c.

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

00983 {
00984    static char *msgs[] = {
00985       "INBOX",
00986       "Old",
00987       "Work",
00988       "Family",
00989       "Friends",
00990       "Cust1",
00991       "Cust2",
00992       "Cust3",
00993       "Cust4",
00994       "Cust5",
00995    };
00996    return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "tmp";
00997 }

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

Definition at line 3831 of file app_voicemail.c.

References __has_voicemail().

Referenced by load_module().

03832 {
03833    return __has_voicemail(context, mailbox, folder, 0);
03834 }

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

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

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

Definition at line 2922 of file app_voicemail.c.

References BASELINELEN, eol, and baseio::linelength.

Referenced by base_encode().

02923 {
02924    if (bio->linelength>=BASELINELEN) {
02925       if (fputs(eol,so)==EOF)
02926          return -1;
02927 
02928       bio->linelength= 0;
02929    }
02930 
02931    if (putc(((unsigned char)c),so)==EOF)
02932       return -1;
02933 
02934    bio->linelength++;
02935 
02936    return 1;
02937 }

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 5391 of file app_voicemail.c.

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

Referenced by play_message().

05392 {
05393    int res = 0;
05394 
05395    if (!ast_strlen_zero(category))
05396       res = ast_play_and_wait(chan, category);
05397 
05398    if (res) {
05399       ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category);
05400       res = 0;
05401    }
05402 
05403    return res;
05404 }

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

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

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

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

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

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

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

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

static void populate_defaults ( struct ast_vm_user vmu  )  [static]

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

00602 {
00603    ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);   
00604    if (saydurationminfo)
00605       vmu->saydurationm = saydurationminfo;
00606    ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
00607    ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
00608    ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
00609    ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
00610    if (maxmsg)
00611       vmu->maxmsg = maxmsg;
00612    vmu->volgain = volgain;
00613 }

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

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

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

Definition at line 3064 of file app_voicemail.c.

03065 {
03066    char *ptr = to;
03067    *ptr++ = '"';
03068    for (; ptr < to + len - 1; from++) {
03069       if (*from == '"')
03070          *ptr++ = '\\';
03071       else if (*from == '\0')
03072          break;
03073       *ptr++ = *from;
03074    }
03075    if (ptr < to + len - 1)
03076       *ptr++ = '"';
03077    *ptr = '\0';
03078    return to;
03079 }

static int reload ( void   )  [static]

Definition at line 8807 of file app_voicemail.c.

References load_config().

08808 {
08809    return(load_config());
08810 }

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

Definition at line 2756 of file app_voicemail.c.

References ast_filerename().

02757 {
02758    char stxt[PATH_MAX];
02759    char dtxt[PATH_MAX];
02760    ast_filerename(sfn,dfn,NULL);
02761    snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
02762    snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
02763    rename(stxt, dtxt);
02764 }

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 4394 of file app_voicemail.c.

References AST_DIGIT_ANY, and ast_say_number().

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

04395 {
04396    int d;
04397    d = ast_say_number(chan, num, AST_DIGIT_ANY, language, (char *) NULL);
04398    return d;
04399 }

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

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

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

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

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

Definition at line 585 of file app_voicemail.c.

Referenced by make_email_file().

00586 {
00587    char *bufptr = buf;
00588    for (; *input; input++) {
00589       if (*input < 32) {
00590          continue;
00591       }
00592       *bufptr++ = *input;
00593       if (bufptr == buf + buflen - 1) {
00594          break;
00595       }
00596    }
00597    *bufptr = '\0';
00598    return buf;
00599 }

static int unload_module ( void   )  [static]

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

08813 {
08814    int res;
08815    
08816    res = ast_unregister_application(app);
08817    res |= ast_unregister_application(app2);
08818    res |= ast_unregister_application(app3);
08819    res |= ast_unregister_application(app4);
08820    ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
08821    ast_uninstall_vm_functions();
08822    
08823    ast_module_user_hangup_all();
08824 
08825    return res;
08826 }

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

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

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

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

08012 {
08013    struct ast_module_user *u;
08014    struct ast_vm_user svm;
08015    char *context, *box;
08016    int priority_jump = 0;
08017    AST_DECLARE_APP_ARGS(args,
08018       AST_APP_ARG(mbox);
08019       AST_APP_ARG(options);
08020    );
08021 
08022    if (ast_strlen_zero(data)) {
08023       ast_log(LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
08024       return -1;
08025    }
08026 
08027    u = ast_module_user_add(chan);
08028 
08029    box = ast_strdupa(data);
08030 
08031    AST_STANDARD_APP_ARGS(args, box);
08032 
08033    if (args.options) {
08034       if (strchr(args.options, 'j'))
08035          priority_jump = 1;
08036    }
08037 
08038    if ((context = strchr(args.mbox, '@'))) {
08039       *context = '\0';
08040       context++;
08041    }
08042 
08043    if (find_user(&svm, context, args.mbox)) {
08044       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
08045       if (priority_jump || ast_opt_priority_jumping)
08046          if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) 
08047             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);
08048    } else
08049       pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
08050    ast_module_user_remove(u);
08051    return 0;
08052 }

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

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

07163 {
07164    if (!strncasecmp(chan->language, "es", 2) ||
07165          !strncasecmp(chan->language, "it", 2) ||
07166          !strncasecmp(chan->language, "pt", 2) ||
07167          !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
07168       return vm_browse_messages_latin(chan, vms, vmu);
07169    } else if (!strcasecmp(chan->language, "he")) {
07170       return vm_browse_messages_he(chan, vms, vmu); /* HEBREW */ 
07171    } else { /* Default to English syntax */
07172       return vm_browse_messages_en(chan, vms, vmu);
07173    }
07174 }

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

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

07097 {
07098    int cmd=0;
07099 
07100    if (vms->lastmsg > -1) {
07101       cmd = play_message(chan, vmu, vms);
07102    } else {
07103       cmd = ast_play_and_wait(chan, "vm-youhave");
07104       if (!cmd) 
07105          cmd = ast_play_and_wait(chan, "vm-no");
07106       if (!cmd) {
07107          snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07108          cmd = ast_play_and_wait(chan, vms->fn);
07109       }
07110       if (!cmd)
07111          cmd = ast_play_and_wait(chan, "vm-messages");
07112    }
07113    return cmd;
07114 }

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

Definition at line 7117 of file app_voicemail.c.

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

Referenced by vm_browse_messages().

07118 {
07119    int cmd = 0;
07120 
07121    if (vms->lastmsg > -1) {
07122       cmd = play_message(chan, vmu, vms);
07123    } else {
07124       if (!strcasecmp(vms->fn, "INBOX")) {
07125          cmd = ast_play_and_wait(chan, "vm-nonewmessages");
07126       } else {
07127          cmd = ast_play_and_wait(chan, "vm-nomessages");
07128       }
07129    }
07130    return cmd;
07131 }

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

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

07136 {
07137    int cmd=0;
07138 
07139    if (vms->lastmsg > -1) {
07140       cmd = play_message(chan, vmu, vms);
07141    } else {
07142       cmd = ast_play_and_wait(chan, "vm-youhaveno");
07143       if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
07144          if (!cmd) {
07145             snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
07146             cmd = ast_play_and_wait(chan, vms->fn);
07147          }
07148          if (!cmd)
07149             cmd = ast_play_and_wait(chan, "vm-messages");
07150       } else {
07151          if (!cmd)
07152             cmd = ast_play_and_wait(chan, "vm-messages");
07153          if (!cmd) {
07154             snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
07155             cmd = ast_play_and_wait(chan, vms->fn);
07156          }
07157       }
07158    }
07159    return cmd;
07160 }

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

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

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

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

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

00910 {
00911    char buf[255];
00912    snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword);
00913    if (!ast_safe_system(buf)) {
00914       ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
00915       /* Reset the password in memory, too */
00916       reset_user_pw(vmu->context, vmu->mailbox, newpassword);
00917    }
00918 }

static int vm_delete ( char *  file  )  [static]

Definition at line 2876 of file app_voicemail.c.

References ast_filedelete().

Referenced by copy_message(), and forward_message().

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

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

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

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

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

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

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

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

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

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

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

06786 {
06787    int res = 0;
06788    /* Play instructions and wait for new command */
06789    while (!res) {
06790       if (vms->starting) {
06791          if (vms->lastmsg > -1) {
06792             res = ast_play_and_wait(chan, "vm-onefor");
06793             if (!strcasecmp(chan->language, "he")) 
06794                res = ast_play_and_wait(chan, "vm-for");
06795             if (!res)
06796                res = vm_play_folder_name(chan, vms->vmbox);
06797          }
06798          if (!res)
06799             res = ast_play_and_wait(chan, "vm-opts");
06800       } else {
06801          if (vms->curmsg)
06802             res = ast_play_and_wait(chan, "vm-prev");
06803          if (!res && !skipadvanced)
06804             res = ast_play_and_wait(chan, "vm-advopts");
06805          if (!res)
06806             res = ast_play_and_wait(chan, "vm-repeat");
06807          if (!res && (vms->curmsg != vms->lastmsg))
06808             res = ast_play_and_wait(chan, "vm-next");
06809          if (!res) {
06810             if (!vms->deleted[vms->curmsg])
06811                res = ast_play_and_wait(chan, "vm-delete");
06812             else
06813                res = ast_play_and_wait(chan, "vm-undelete");
06814             if (!res)
06815                res = ast_play_and_wait(chan, "vm-toforward");
06816             if (!res)
06817                res = ast_play_and_wait(chan, "vm-savemessage");
06818          }
06819       }
06820       if (!res)
06821          res = ast_play_and_wait(chan, "vm-helpexit");
06822       if (!res)
06823          res = ast_waitfordigit(chan, 6000);
06824       if (!res) {
06825          vms->repeats++;
06826          if (vms->repeats > 2) {
06827             res = 't';
06828          }
06829       }
06830    }
06831    return res;
06832 }

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

Definition at line 6736 of file app_voicemail.c.

References ast_fileexists(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, RETRIEVE, vm_state::username, vm_intro_cz(), 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().

06737 {
06738    char prefile[256];
06739    
06740    /* Notify the user that the temp greeting is set and give them the option to remove it */
06741    snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
06742    if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
06743       RETRIEVE(prefile, -1, vmu);
06744       if (ast_fileexists(prefile, NULL, NULL) > 0)
06745          ast_play_and_wait(chan, "vm-tempgreetactive");
06746       DISPOSE(prefile, -1);
06747    }
06748 
06749    /* Play voicemail intro - syntax is different for different languages */
06750    if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
06751       return vm_intro_de(chan, vms);
06752    } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */
06753       return vm_intro_es(chan, vms);
06754    } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
06755       return vm_intro_it(chan, vms);
06756    } else if (!strncasecmp(chan->language, "fr", 2)) {   /* FRENCH syntax */
06757       return vm_intro_fr(chan, vms);
06758    } else if (!strncasecmp(chan->language, "nl", 2)) {   /* DUTCH syntax */
06759       return vm_intro_nl(chan, vms);
06760    } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */
06761       return vm_intro_pt_BR(chan, vms);      
06762    } else if (!strncasecmp(chan->language, "pt", 2)) {   /* PORTUGUESE syntax */
06763       return vm_intro_pt(chan, vms);
06764    } else if (!strncasecmp(chan->language, "cz", 2)) {   /* CZECH syntax */
06765       return vm_intro_cz(chan, vms);
06766    } else if (!strncasecmp(chan->language, "gr", 2)) {   /* GREEK syntax */
06767       return vm_intro_gr(chan, vms);
06768    } else if (!strncasecmp(chan->language, "pl", 2)) {   /* POLISH syntax */
06769       return vm_intro_pl(chan, vms);
06770    } else if (!strncasecmp(chan->language, "se", 2)) {   /* SWEDISH syntax */
06771       return vm_intro_se(chan, vms);
06772    } else if (!strncasecmp(chan->language, "no", 2)) {   /* NORWEGIAN syntax */
06773       return vm_intro_no(chan, vms);
06774    } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */
06775       return vm_intro_multilang(chan, vms, "n");
06776    } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */
06777       return vm_intro_multilang(chan, vms, "n");
06778    } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */
06779       return vm_intro_he(chan, vms);
06780    } else {             /* Default to ENGLISH */
06781       return vm_intro_en(chan, vms);
06782    }
06783 }

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

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

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

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

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

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

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

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

05968 {
05969    int res;
05970 
05971    /* Introduce messages they have */
05972    res = ast_play_and_wait(chan, "vm-youhave");
05973    if (!res) {
05974       if (vms->newmessages) {
05975          res = say_and_wait(chan, vms->newmessages, chan->language);
05976          if (!res)
05977             res = ast_play_and_wait(chan, "vm-INBOX");
05978          if (vms->oldmessages && !res)
05979             res = ast_play_and_wait(chan, "vm-and");
05980          else if (!res) {
05981             if ((vms->newmessages == 1))
05982                res = ast_play_and_wait(chan, "vm-message");
05983             else
05984                res = ast_play_and_wait(chan, "vm-messages");
05985          }
05986             
05987       }
05988       if (!res && vms->oldmessages) {
05989          res = say_and_wait(chan, vms->oldmessages, chan->language);
05990          if (!res)
05991             res = ast_play_and_wait(chan, "vm-Old");
05992          if (!res) {
05993             if (vms->oldmessages == 1)
05994                res = ast_play_and_wait(chan, "vm-message");
05995             else
05996                res = ast_play_and_wait(chan, "vm-messages");
05997          }
05998       }
05999       if (!res) {
06000          if (!vms->oldmessages && !vms->newmessages) {
06001             res = ast_play_and_wait(chan, "vm-no");
06002             if (!res)
06003                res = ast_play_and_wait(chan, "vm-messages");
06004          }
06005       }
06006    }
06007    return res;
06008 }

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

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

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

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

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

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

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

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

05930 {
05931    int res = 0;
05932 
05933    if (vms->newmessages) {
05934       res = ast_play_and_wait(chan, "vm-youhave");
05935       if (!res) 
05936          res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
05937       if (!res) {
05938          if ((vms->newmessages == 1)) {
05939             res = ast_play_and_wait(chan, "vm-INBOX");
05940             if (!res)
05941                res = ast_play_and_wait(chan, "vm-message");
05942          } else {
05943             res = ast_play_and_wait(chan, "vm-INBOXs");
05944             if (!res)
05945                res = ast_play_and_wait(chan, "vm-messages");
05946          }
05947       }
05948    } else if (vms->oldmessages){
05949       res = ast_play_and_wait(chan, "vm-youhave");
05950       if (!res)
05951          res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
05952       if ((vms->oldmessages == 1)){
05953          res = ast_play_and_wait(chan, "vm-Old");
05954          if (!res)
05955             res = ast_play_and_wait(chan, "vm-message");
05956       } else {
05957          res = ast_play_and_wait(chan, "vm-Olds");
05958          if (!res)
05959             res = ast_play_and_wait(chan, "vm-messages");
05960       }
05961    } else if (!vms->oldmessages && !vms->newmessages) 
05962       res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 
05963    return res;
05964 }

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

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

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

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

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

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

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

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

06068 {
06069    int res;
06070    int lastnum = 0;
06071 
06072    res = ast_play_and_wait(chan, "vm-youhave");
06073 
06074    if (!res && vms->newmessages) {
06075       lastnum = vms->newmessages;
06076 
06077       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06078          res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
06079       }
06080 
06081       if (!res && vms->oldmessages) {
06082          res = ast_play_and_wait(chan, "vm-and");
06083       }
06084    }
06085 
06086    if (!res && vms->oldmessages) {
06087       lastnum = vms->oldmessages;
06088 
06089       if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
06090          res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
06091       }
06092    }
06093 
06094    if (!res) {
06095       if (lastnum == 0) {
06096          res = ast_play_and_wait(chan, "vm-no");
06097       }
06098       if (!res) {
06099          res = ast_say_counted_noun(chan, lastnum, "vm-message");
06100       }
06101    }
06102 
06103    return res;
06104 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

02208 {
02209    switch (ast_lock_path(path)) {
02210    case AST_LOCK_TIMEOUT:
02211       return -1;
02212    default:
02213       return 0;
02214    }
02215 }

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

Definition at line 931 of file app_voicemail.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

00932 {
00933    FILE *p = NULL;
00934    int pfd = mkstemp(template);
00935    chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
00936    if (pfd > -1) {
00937       p = fdopen(pfd, "w+");
00938       if (!p) {
00939          close(pfd);
00940          pfd = -1;
00941       }
00942    }
00943    return p;
00944 }

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

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

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

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

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

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

05896 {
05897    int cmd;
05898 
05899    if (!strncasecmp(chan->language, "it", 2) || !strncasecmp(chan->language, "es", 2) || !strncasecmp(chan->language, "fr", 2) || !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, French or Portuguese syntax */
05900       cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
05901       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05902    } else if (!strncasecmp(chan->language, "gr", 2)){
05903       return vm_play_folder_name_gr(chan, mbox);
05904    } else if (!strncasecmp(chan->language, "pl", 2)){
05905       return vm_play_folder_name_pl(chan, mbox);
05906    } else if (!strncasecmp(chan->language, "ua", 2)){  /* Ukrainian syntax */
05907       return vm_play_folder_name_ua(chan, mbox);
05908    } else if (!strcasecmp(chan->language, "he")){  /* Hebrew syntax */
05909       cmd = ast_play_and_wait(chan, mbox);
05910       return cmd;
05911    } else {  /* Default English */
05912       cmd = ast_play_and_wait(chan, mbox);
05913       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
05914    }
05915 }

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

Definition at line 5848 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

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

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

Definition at line 5866 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05867 {
05868    int cmd;
05869 
05870    if (!strcasecmp(mbox, "vm-INBOX") || !strcasecmp(mbox, "vm-Old")) {
05871       if (!strcasecmp(mbox, "vm-INBOX"))
05872          cmd = ast_play_and_wait(chan, "vm-new-e");
05873       else
05874          cmd = ast_play_and_wait(chan, "vm-old-e");
05875       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05876    } else {
05877       cmd = ast_play_and_wait(chan, "vm-messages");
05878       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05879    }
05880 }

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

Definition at line 5882 of file app_voicemail.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

05883 {
05884    int cmd;
05885 
05886    if (!strcasecmp(mbox, "vm-Family") || !strcasecmp(mbox, "vm-Friends") || !strcasecmp(mbox, "vm-Work")){
05887       cmd = ast_play_and_wait(chan, "vm-messages");
05888       return cmd ? cmd : ast_play_and_wait(chan, mbox);
05889    } else {
05890       cmd = ast_play_and_wait(chan, mbox);
05891       return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
05892    }
05893 }

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

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

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

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

08055 {
08056    struct ast_module_user *u;
08057    char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
08058    struct ast_vm_user vmus;
08059    char *options = NULL;
08060    int silent = 0, skipuser = 0;
08061    int res = -1;
08062 
08063    u = ast_module_user_add(chan);
08064    
08065    if (s) {
08066       s = ast_strdupa(s);
08067       user = strsep(&s, "|");
08068       options = strsep(&s, "|");
08069       if (user) {
08070          s = user;
08071          user = strsep(&s, "@");
08072          context = strsep(&s, "");
08073          if (!ast_strlen_zero(user))
08074             skipuser++;
08075          ast_copy_string(mailbox, user, sizeof(mailbox));
08076       }
08077    }
08078 
08079    if (options) {
08080       silent = (strchr(options, 's')) != NULL;
08081    }
08082 
08083    if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
08084       pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
08085       pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
08086       ast_play_and_wait(chan, "auth-thankyou");
08087       res = 0;
08088    }
08089 
08090    ast_module_user_remove(u);
08091    return res;
08092 }

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

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

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

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

Definition at line 5386 of file app_voicemail.c.

References ast_control_streamfile().

05387 {
05388    return ast_control_streamfile(chan, file, "#", "*", "1456789", "0", "2", skipms);
05389 }

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

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

05379 {
05380    int res;
05381    if ((res = ast_stream_and_wait(chan, file, chan->language, AST_DIGIT_ANY)) < 0) 
05382       ast_log(LOG_WARNING, "Unable to play message %s\n", file); 
05383    return res;
05384 }


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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 9333 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 9333 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 8196 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 8201 of file app_voicemail.c.

struct ast_cli_entry cli_voicemail[] [static]

Definition at line 8206 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 8094 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 8098 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 Thu Dec 17 23:51:30 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7